Skip to content

Commit

Permalink
Added Like and Favorite Page using IDB
Browse files Browse the repository at this point in the history
  • Loading branch information
BryanYehuda committed Jul 1, 2021
1 parent 3362b70 commit 67d1de2
Show file tree
Hide file tree
Showing 10 changed files with 165 additions and 8 deletions.
11 changes: 11 additions & 0 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
},
"dependencies": {
"css-loader": "^3.6.0",
"idb": "^6.1.2",
"regenerator-runtime": "^0.13.7",
"serviceworker-webpack-plugin": "^1.0.1",
"style-loader": "^1.2.1"
Expand Down
27 changes: 27 additions & 0 deletions src/scripts/data/database.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { openDB } from 'idb';
import CONFIG from '../globals/config';

const { DATABASE_NAME, DATABASE_VERSION, OBJECT_STORE_NAME } = CONFIG;

const dbPromise = openDB(DATABASE_NAME, DATABASE_VERSION, {
upgrade(database) {
database.createObjectStore(OBJECT_STORE_NAME, { keyPath: 'id' });
},
});

const FavoriteRestaurantIdb = {
async getRestaurant(id) {
return (await dbPromise).get(OBJECT_STORE_NAME, id);
},
async getAllRestaurant() {
return (await dbPromise).getAll(OBJECT_STORE_NAME);
},
async putRestaurant(restaurant) {
return (await dbPromise).put(OBJECT_STORE_NAME, restaurant);
},
async deleteRestaurant(id) {
return (await dbPromise).delete(OBJECT_STORE_NAME, id);
},
};

export default FavoriteRestaurantIdb;
5 changes: 4 additions & 1 deletion src/scripts/globals/config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
const CONFIG = {
BASE_URL: 'https://restaurant-api.dicoding.dev/',
BASE_IMAGE_URL: 'https://restaurant-api.dicoding.dev/images/medium/',
CACHE_NAME: 'RestoMantap-v1',
CACHE_NAME: 'RestoMantap-1',
DATABASE_NAME: 'restaurant-catalogue-database',
DATABASE_VERSION: 1,
OBJECT_STORE_NAME: 'restaurants',
};

export default CONFIG;
48 changes: 48 additions & 0 deletions src/scripts/utils/like-button-initiator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import FavoriteRestaurantIdb from '../data/database';
import { createLikeButtonTemplate, createLikedButtonTemplate } from '../views/templates/template-creator';

const LikeButtonInitiator = {
async init({ likeButtonContainer, restaurant }) {
this._likeButtonContainer = likeButtonContainer;
this._restaurant = restaurant;

await this._renderButton();
},

async _renderButton() {
const { id } = this._restaurant;

if (await this._isRestaurantExist(id)) {
this._renderLiked();
} else {
this._renderLike();
}
},

async _isRestaurantExist(id) {
const restaurant = await FavoriteRestaurantIdb.getRestaurant(id);
return !!restaurant;
},

_renderLike() {
this._likeButtonContainer.innerHTML = createLikeButtonTemplate();

const likeButton = document.querySelector('#likeButton');
likeButton.addEventListener('click', async () => {
await FavoriteRestaurantIdb.putRestaurant(this._restaurant);
this._renderButton();
});
},

_renderLiked() {
this._likeButtonContainer.innerHTML = createLikedButtonTemplate();

const likeButton = document.querySelector('#likeButton');
likeButton.addEventListener('click', async () => {
await FavoriteRestaurantIdb.deleteRestaurant(this._restaurant.id);
this._renderButton();
});
},
};

export default LikeButtonInitiator;
14 changes: 14 additions & 0 deletions src/scripts/views/pages/detail.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import UrlParser from '../../routes/url-parser';
import DicodingDB from '../../data/dicodingdb';
import { createRestaurantDetailTemplate } from '../templates/template-creator';
import LikeButtonInitiator from '../../utils/like-button-initiator';

const Detail = {
async render() {
return `
<div id="likeButtonContainer"></div>
<div id="restaurant" class="restaurant"></div>
<div id="likeButtonContainer"></div>
`;
},

Expand All @@ -14,6 +17,17 @@ const Detail = {
const restaurants = await DicodingDB.DetailRestaurant(url.id);
const restaurantContainer = document.querySelector('#restaurant');
restaurantContainer.innerHTML = createRestaurantDetailTemplate(restaurants);

LikeButtonInitiator.init({
likeButtonContainer: document.querySelector('#likeButtonContainer'),
restaurant: {
id: restaurants.id,
name: restaurants.name,
rating: restaurants.rating,
city: restaurants.city,
pictureId: restaurants.pictureId,
},
});
},
};

Expand Down
23 changes: 18 additions & 5 deletions src/scripts/views/pages/favorite.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
const Favorite = {
import FavoriteRestaurantIdb from '../../data/database';
import { createRestaurantItemTemplate } from '../templates/template-creator';

const Like = {
async render() {
return `
<h2>Favorite Page</h2>
`;
<section class="headline" id="headline">
<h2>List Restoran Mantap Favorit Anda</h2>
</section>
<section class="content" id="list">
</section>
`;
},

async afterRender() {
// Fungsi ini akan dipanggil setelah render()
const restaurants = await FavoriteRestaurantIdb.getAllRestaurant();
const restaurantContainer = document.querySelector('#list');
restaurants.forEach((restaurant) => {
restaurantContainer.innerHTML += createRestaurantItemTemplate(restaurant);
});
},
};

export default Favorite;
export default Like;
19 changes: 18 additions & 1 deletion src/scripts/views/templates/template-creator.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,21 @@ const createRestaurantItemTemplate = (restaurants) => `
</article>
`;

export { createRestaurantItemTemplate, createRestaurantDetailTemplate };
const createLikeButtonTemplate = () => `
<button aria-label="like this movie" id="likeButton" class="like">
<i class="fa fa-heart-o" aria-hidden="true"></i>
</button>
`;

const createLikedButtonTemplate = () => `
<button aria-label="unlike this movie" id="likeButton" class="like">
<i class="fa fa-heart" aria-hidden="true"></i>
</button>
`;

export {
createRestaurantItemTemplate,
createRestaurantDetailTemplate,
createLikeButtonTemplate,
createLikedButtonTemplate,
};
22 changes: 22 additions & 0 deletions src/styles/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -336,4 +336,26 @@ input[type=submit]:active {
border: 1px solid #D83A56;
color: #fff;
transition: all 0.2s;
}


/***************************
LIKE
***************************/

.like {
font-size: 35px;
position: fixed;
bottom: 16px;
right: 16px;
background-color: #db0000;
color: white;
border: 0;
border-radius: 50%;
width: 75px;
height: 75px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
3 changes: 2 additions & 1 deletion src/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="manifest" href="manifest.json">
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@100;200;400;600;700;900&display=swap" rel="stylesheet">
<script src="https://use.fontawesome.com/b070c8f1df.js"></script>
<!-- Link Ends -->
</head>

Expand All @@ -43,7 +44,7 @@
<div class="hero-text-box">
<h1>RestoMantap <br>Pastinya Mantap!</h1>
<a class="btn btn-full" href="#headline">Cari Restoran Sekarang!</a>
<a class="btn btn-ghost" href="#">Restoran Favorit</a>
<a class="btn btn-ghost" href="#/favorite">Restoran Favorit</a>
</div>
</header>
<!-- Header Ends -->
Expand Down

0 comments on commit 67d1de2

Please sign in to comment.