Implement category search method

This commit is contained in:
2023-09-14 10:21:18 +07:00
parent b03bad79fd
commit e74f309361
9 changed files with 186 additions and 79 deletions
@@ -24,6 +24,10 @@ export default class HomeController {
return this.service.transactionService.saveTransaction(transaction); return this.service.transactionService.saveTransaction(transaction);
} }
handlerGetAllCategory() {
return this.service.categoryService.getAllCategory();
}
init() { init() {
if (this.homeView) { if (this.homeView) {
this.homeView.addHandlerInputChangeWalletForm(); this.homeView.addHandlerInputChangeWalletForm();
@@ -36,6 +40,7 @@ export default class HomeController {
this.handlerGetInfoUserLogin.bind(this), this.handlerGetInfoUserLogin.bind(this),
this.handlerCheckWalletValid.bind(this), this.handlerCheckWalletValid.bind(this),
this.handlerGetWalletUser.bind(this), this.handlerGetWalletUser.bind(this),
this.handlerGetAllCategory.bind(this),
); );
this.homeView.addHandlerSubmitBudgetForm( this.homeView.addHandlerSubmitBudgetForm(
@@ -44,6 +49,8 @@ export default class HomeController {
); );
this.homeView.addHandlerInputChangeBudgetForm(); this.homeView.addHandlerInputChangeBudgetForm();
this.homeView.handlerInputChangeCategoryDialog();
} }
} }
} }
@@ -0,0 +1,7 @@
export default class Category {
constructor({ id, url, name }) {
this.id = id;
this.url = url;
this.name = name;
}
}
@@ -0,0 +1,25 @@
import CommonService from './commonService';
import Category from '../models/category';
export default class CategoryService extends CommonService {
constructor() {
super();
this.defaultPath = 'categories/';
}
async getAllCategory() {
const data = await this.getAllDataFromPath(this.defaultPath);
const listCategory = [];
if (data) {
data.forEach((category) => {
listCategory.unshift(new Category(category));
});
return listCategory;
}
return null;
}
}
@@ -62,4 +62,16 @@ export default class CommonService {
return null; return null;
} }
async getAllDataFromPath(path = this.defaultPath) {
this.connectToDb();
const result = await this.firebaseService.getAllDataFromPath(path);
const data = await timeOutConnect(result);
if (data) return data;
return null;
}
} }
@@ -94,6 +94,35 @@ class FirebaseService {
); );
}); });
} }
getAllDataFromPath(path) {
return new Promise((resolve) => {
onValue(
ref(this.db, path),
(snapshot) => {
const data = [];
// snapshot is a type of data by Firebase define
snapshot.forEach((childSnapshot) => {
// const dataTemp = childSnapshot.val();
// if (dataTemp[property] === value) {
// id = childSnapshot.key;
// data = dataTemp;
// }
const id = childSnapshot.key;
const val = childSnapshot.val();
data.push({ id, ...val });
});
resolve(data);
},
{
onlyOnce: true,
},
);
});
}
} }
export default new FirebaseService(); export default new FirebaseService();
@@ -1,3 +1,4 @@
import CategoryService from './categoryService';
import TransactionService from './transactionService'; import TransactionService from './transactionService';
import UserService from './userService'; import UserService from './userService';
import WalletService from './walletService'; import WalletService from './walletService';
@@ -7,5 +8,6 @@ export default class Service {
this.userService = new UserService(); this.userService = new UserService();
this.walletService = new WalletService(); this.walletService = new WalletService();
this.transactionService = new TransactionService(); this.transactionService = new TransactionService();
this.categoryService = new CategoryService();
} }
} }
+83 -4
View File
@@ -27,7 +27,12 @@ export default class HomeView extends CommonView {
this.walletDialog = document.getElementById('walletDialog'); this.walletDialog = document.getElementById('walletDialog');
} }
async loadPage(getInfoUserLogin, isValidWallet, getWalletByIdUser) { async loadPage(
getInfoUserLogin,
isValidWallet,
getWalletByIdUser,
getAllCategory,
) {
this.getWalletByIdUser = getWalletByIdUser; // Init function this.getWalletByIdUser = getWalletByIdUser; // Init function
this.toggleLoaderSpinner(); this.toggleLoaderSpinner();
const user = await getInfoUserLogin(); const user = await getInfoUserLogin();
@@ -47,15 +52,89 @@ export default class HomeView extends CommonView {
this.loadEvent(); this.loadEvent();
// Init data // Init data
this.loadData(); this.loadData(getAllCategory);
} }
} }
this.toggleLoaderSpinner(); this.toggleLoaderSpinner();
} }
async loadData() { async loadData(getAllCategory) {
const wallet = await this.getWalletByIdUser(this.user.id); // Get data wallet await this.loadWalletUser();
await this.loadCategory(getAllCategory);
}
// ---------------------SELECTED CATEGORY DIALOG---------------------//
/**
* Load category data
* @param {function} getAllCategory Get all category function
*/
async loadCategory(getAllCategory) {
this.listCategory = await getAllCategory();
if (this.listCategory) {
this.renderCategoryItem(this.listCategory);
}
}
handlerInputChangeCategoryDialog() {
this.categoryDialog.addEventListener('input', () => {
setTimeout(() => {
this.searchCategory();
}, 300);
});
}
searchCategory() {
const searchCategoryEl =
this.categoryDialog.querySelector("[name='category']");
const searchValue = searchCategoryEl.value.trim().toLowerCase();
let newListCategory = [];
if (searchValue) {
this.listCategory.forEach((category) => {
const categoryName = category.name.trim().toLowerCase();
if (categoryName.includes(searchValue)) {
newListCategory.unshift(category);
}
});
} else {
newListCategory = this.listCategory;
}
// Render category item
this.renderCategoryItem(newListCategory);
}
renderCategoryItem(listCategory) {
const listCategoryEl = document.querySelector('.list-category');
listCategoryEl.innerHTML = ''; // Remove old category item
listCategory.forEach((category) => {
const markup = `
<div class="category-item" value="${category.name}">
<img
class="icon-category"
src="${category.url}"
alt="${category.name} Icon"
/>
<p class="name-category">${category.name}</p>
</div>
`;
listCategoryEl.insertAdjacentHTML('afterbegin', markup);
});
}
// ---------------------END DIALOG---------------------//
/**
* Load wallet user
*/
async loadWalletUser() {
const wallet = await this.getWalletByIdUser(this.user.id);
const walletName = document.querySelector('.wallet__name'); const walletName = document.querySelector('.wallet__name');
const walletPrice = document.querySelector('.wallet__price'); const walletPrice = document.querySelector('.wallet__price');
const sign = wallet.amount >= 0 ? '+' : '-'; const sign = wallet.amount >= 0 ? '+' : '-';
+9 -75
View File
@@ -194,81 +194,7 @@
</form> </form>
</div> </div>
<div class="dialog__body"> <div class="dialog__body">
<div class="list-category"> <div class="list-category"></div>
<!-- Category item -->
<div class="category-item">
<img
class="icon-category"
src="../assets/images/ic_category_foodndrink.png.png"
alt="Food & Beverage Icon"
/>
<p class="name-category">Food & Beverage</p>
</div>
<div class="category-item">
<img
class="icon-category"
src="../assets/images/ic_category_foodndrink.png.png"
alt="Food & Beverage Icon"
/>
<p class="name-category">Food & Beverage</p>
</div>
<div class="category-item">
<img
class="icon-category"
src="../assets/images/ic_category_foodndrink.png.png"
alt="Food & Beverage Icon"
/>
<p class="name-category">Food & Beverage</p>
</div>
<div class="category-item">
<img
class="icon-category"
src="../assets/images/ic_category_foodndrink.png.png"
alt="Food & Beverage Icon"
/>
<p class="name-category">Food & Beverage</p>
</div>
<div class="category-item">
<img
class="icon-category"
src="../assets/images/ic_category_foodndrink.png.png"
alt="Food & Beverage Icon"
/>
<p class="name-category">Food & Beverage</p>
</div>
<div class="category-item">
<img
class="icon-category"
src="../assets/images/ic_category_foodndrink.png.png"
alt="Food & Beverage Icon"
/>
<p class="name-category">Food & Beverage</p>
</div>
<div class="category-item">
<img
class="icon-category"
src="../assets/images/ic_category_foodndrink.png.png"
alt="Food & Beverage Icon"
/>
<p class="name-category">Food & Beverage</p>
</div>
<div class="category-item">
<img
class="icon-category"
src="../assets/images/ic_category_foodndrink.png.png"
alt="Food & Beverage Icon"
/>
<p class="name-category">Food & Beverage</p>
</div>
<div class="category-item">
<img
class="icon-category"
src="../assets/images/ic_category_foodndrink.png.png"
alt="Food & Beverage Icon"
/>
<p class="name-category">Food & Beverage</p>
</div>
</div>
</div> </div>
</div> </div>
</dialog> </dialog>
@@ -412,5 +338,13 @@
<!-- End app --> <!-- End app -->
</div> </div>
<script type="module" src="../js/main.js"></script> <script type="module" src="../js/main.js"></script>
<script>
document
.querySelector('.list-category')
.addEventListener('click', (e) => {
const value = e.target.getAttribute('value');
alert(value);
});
</script>
</body> </body>
</html> </html>
@@ -605,6 +605,11 @@
color: $dark-gray; color: $dark-gray;
} }
.icon-category {
width: 40px;
height: 40px;
}
.list-category { .list-category {
@extend %d-flex; @extend %d-flex;
@include flex-layout($direction: column); @include flex-layout($direction: column);
@@ -621,6 +626,13 @@
margin-inline: 68px; margin-inline: 68px;
padding: 8px 0; padding: 8px 0;
border-bottom: 1px solid $gray; border-bottom: 1px solid $gray;
transition: 0.3s;
cursor: pointer;
&:hover,
&.selected {
background-color: $hover-light-primary-color;
}
} }
} }