| @@ -1,18 +1,79 @@ | |||
| <ion-content> | |||
| <section class="header-bar"> | |||
| <button (click)="back()"> <ion-icon name="arrow-back"></ion-icon> </button> | |||
| <h2> Bookmarks </h2> | |||
| <button> <ion-icon src="assets/custom/search.svg"></ion-icon> </button> | |||
| </section> | |||
| <div class="top-bar-holder"> | |||
| <div class="tabs-holder"> | |||
| <button (click)="selected_tab = 'malls'" class="tab" [ngClass]="{'active' : selected_tab === 'malls'}"> | |||
| Malls | |||
| </button> | |||
| <button (click)="selected_tab = 'outlets'" class="tab" [ngClass]="{'active' : selected_tab === 'outlets'}"> | |||
| Outlets | |||
| </button> | |||
| <div class="header-bar active"> | |||
| <div class="heading-holder"> | |||
| <button (click)="back()"> <ion-icon name="arrow-back"></ion-icon> </button> | |||
| <h3> Bookmarks </h3> | |||
| </div> | |||
| </div> | |||
| <div class="tabs-holder" [ngClass]="{ 'right' : selected_tab === 'outlets' }"> | |||
| <button class="tab" [ngClass]="{ 'active' : selected_tab === 'malls' }" | |||
| (click)="selected_tab = 'malls'"> MALLS </button> | |||
| <button class="tab" [ngClass]="{ 'active' : selected_tab === 'outlets' }" | |||
| (click)="selected_tab = 'outlets'"> OUTLETS </button> | |||
| </div> | |||
| <div *ngIf="selected_tab === 'malls'"> | |||
| <div class="results-utilities-holder"> | |||
| <h5 *ngIf="malls"> {{ bookmarked_malls }} MALLS </h5> | |||
| </div> | |||
| <ion-list lines="none" class="result-list"> | |||
| <ion-item *ngFor="let mall of malls" (click)="showMallDetails(mall)" [ngClass]="{'show' : mall.is_bookmarked }"> | |||
| <img src="{{ mall.image_url }}" slot="start"> | |||
| <ion-label> | |||
| <h3> {{ mall.name }} <ion-icon name="bookmark" [ngClass]="{'active' : mall.is_bookmarked }"></ion-icon> </h3> | |||
| <p class="description"> {{ mall.description }} </p> | |||
| <div class="offers-holder"> | |||
| <div class="offer"> | |||
| <ion-icon src="assets/custom/restaurant.svg"></ion-icon> | |||
| Food Offers: <strong> {{ mall.offers.length }} </strong> | |||
| </div> | |||
| <div class="offer"> | |||
| <ion-icon src="assets/custom/shopping-purse-icon.svg"></ion-icon> | |||
| Shopping Offers: <strong> {{ mall.offers.length }} </strong> | |||
| </div> | |||
| </div> | |||
| </ion-label> | |||
| </ion-item> | |||
| </ion-list> | |||
| </div> | |||
| <div *ngIf="selected_tab === 'outlets'"> | |||
| <div class="results-utilities-holder"> | |||
| <h5 *ngIf="malls"> {{ bookmarked_outlets }} OUTLETS </h5> | |||
| </div> | |||
| <ion-list lines="none" class="result-list"> | |||
| <div *ngFor="let mall of malls"> | |||
| <ion-item *ngFor="let outlet of mall.outlets" [ngClass]="{'show' : outlet.is_bookmarked }" | |||
| (click)="outletDetails(mall.id, outlet.id)"> | |||
| <img src="{{ outlet.image_url }}" slot="start"> | |||
| <ion-label> | |||
| <h3> | |||
| {{ outlet.name }} | |||
| <div class="rating-holder"> | |||
| <ion-icon name="star"></ion-icon> {{ outlet.rating }} | |||
| </div> | |||
| <ion-icon name="bookmark" [ngClass]="{'active' : outlet.is_bookmarked }"></ion-icon> | |||
| </h3> | |||
| <p class="description"> | |||
| {{ outlet.description }} | |||
| <button class="share-button"> | |||
| <ion-icon name="share"></ion-icon> | |||
| </button> | |||
| </p> | |||
| <div class="offers-holder"> | |||
| <div class="offer"> | |||
| <span *ngIf="outlet.outlet_type === 'FOOD'"> <ion-icon name="restaurant"></ion-icon> Food </span> | |||
| <span *ngIf="outlet.outlet_type === 'SHOP'"> <ion-icon name="basket"></ion-icon> Shopping </span> | |||
| Offers: <strong> {{ outlet.offers.length }} </strong> | |||
| </div> | |||
| </div> | |||
| </ion-label> | |||
| </ion-item> | |||
| </div> | |||
| </ion-list> | |||
| </div> | |||
| </ion-content> | |||
| @@ -1,66 +1,16 @@ | |||
| .top-bar-holder { | |||
| background-image: url('../../assets/custom/background-5.svg'); | |||
| background-size: cover; | |||
| background-repeat: no-repeat; | |||
| background-position: left top; | |||
| padding-top: 80px; | |||
| } | |||
| @import '../mall-details/mall-details.page.scss'; | |||
| .header-bar { | |||
| color: white; | |||
| display: flex; | |||
| padding: 20px; | |||
| align-items: center; | |||
| background-image: url('../../assets/custom/background-5.svg'); | |||
| background-size: cover; | |||
| background-repeat: no-repeat; | |||
| background-position: left top; | |||
| position: fixed; | |||
| left: 0; | |||
| top: 0; | |||
| z-index: 2; | |||
| width: 100%; | |||
| h2 { | |||
| font-size: 20px; | |||
| margin: 0 auto 0 10px; | |||
| } | |||
| button { | |||
| margin: 0; | |||
| border-radius: 50%; | |||
| color: var(--brand-blue); | |||
| width: 30px; | |||
| height: 30px; | |||
| background-color: white; | |||
| font-size: 14px; | |||
| ion-icon[name="arrow-back"] { | |||
| font-size: 18px; | |||
| } | |||
| } | |||
| position: sticky; | |||
| } | |||
| .tabs-holder { | |||
| width: 100%; | |||
| padding: 0 20px 20px; | |||
| overflow: scroll; | |||
| white-space: nowrap; | |||
| button { | |||
| display: inline-block; | |||
| border-radius: 20px; | |||
| background-color: transparent; | |||
| color: white; | |||
| font-size: 10px; | |||
| padding: 5px 15px; | |||
| height: 30px; | |||
| margin-right: 10px; | |||
| font-weight: bold; | |||
| ion-list { | |||
| ion-item { | |||
| display: none; | |||
| margin: 10px auto; | |||
| &.active { | |||
| background-color: white; | |||
| color: var(--brand-blue); | |||
| } | |||
| } | |||
| &.show { | |||
| display: block; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,9 +1,8 @@ | |||
| import { Component, OnInit } from '@angular/core'; | |||
| import { Router } from '@angular/router'; | |||
| import { Location } from '@angular/common'; | |||
| import { BookmarkService } from '../services/bookmark.service'; | |||
| import { IMall } from '../models/mall'; | |||
| import { IOutlet } from '../models/outlet'; | |||
| import { MallService } from '../services/mall.service'; | |||
| @Component({ | |||
| selector: 'app-bookmark', | |||
| @@ -12,32 +11,51 @@ import { IOutlet } from '../models/outlet'; | |||
| }) | |||
| export class BookmarkPage implements OnInit { | |||
| selected_tab: string = 'malls'; | |||
| malls: Array<string> = []; | |||
| outlets: Array<string> = []; | |||
| malls: Array<IMall> = []; | |||
| bookmarked_malls: number = 0; | |||
| bookmarked_outlets: number = 0; | |||
| constructor( | |||
| private router: Router, | |||
| private location: Location, | |||
| private bookmarkService: BookmarkService | |||
| private mallService: MallService, | |||
| ) { } | |||
| ngOnInit() { | |||
| } | |||
| ionViewDidEnter() { | |||
| this.bookmarkService.getMallBookmarks().then((data: Array<string>) => { | |||
| this.malls = data; | |||
| console.log(this.malls); | |||
| }); | |||
| this.bookmarkService.getOutletBookmarks().then((data: Array<string>) => { | |||
| this.outlets = data; | |||
| console.log(this.outlets); | |||
| }); | |||
| this.bookmarked_outlets = 0; | |||
| this.mallService.getAllMalls().then((data: Array<IMall>) => { | |||
| this.malls = data; | |||
| this.bookmarked_malls = this.malls.filter((mall => { | |||
| return mall.is_bookmarked; | |||
| })).length; | |||
| let i: number, j: number; | |||
| for (i = 0; i < this.malls.length; i += 1) { | |||
| for (j = 0; j < this.malls[i].outlets.length; j += 1) { | |||
| if (this.malls[i].outlets[j].is_bookmarked) { | |||
| this.bookmarked_outlets += 1; | |||
| } | |||
| } | |||
| } | |||
| }); | |||
| } | |||
| back() { | |||
| this.location.back(); | |||
| } | |||
| showMallDetails(mall: IMall) { | |||
| this.router.navigate(['/mall-details', { mall_id: mall.id }]); | |||
| } | |||
| outletDetails(mall_id: string, outlet_id: string) { | |||
| this.router.navigate(['/outlet-details', { mall_id: mall_id, outlet_id: outlet_id }]); | |||
| } | |||
| } | |||
| @@ -54,4 +54,8 @@ export class MallsPage implements OnInit { | |||
| this.show_sort_popup = !this.show_sort_popup; | |||
| } | |||
| outletDetails(mall_id: string, outlet_id: string) { | |||
| this.router.navigate(['/outlet-details', { mall_id: mall_id, outlet_id: outlet_id }]); | |||
| } | |||
| } | |||
| @@ -5,7 +5,7 @@ export const MALLS: Mall[] = [new Mall({ | |||
| id: '0001', | |||
| name: 'Gopalan Arcade Mall', | |||
| address: 'Mysore Road, Bangalore', | |||
| is_bookmarked: false, | |||
| is_bookmarked: true, | |||
| is_archived: false, | |||
| image_url: 'https://www.gopalanmall.com/images/mall-arcade-01.jpg', | |||
| description: 'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.', | |||
| @@ -37,7 +37,7 @@ export const MALLS: Mall[] = [new Mall({ | |||
| id: '0003', | |||
| name: 'Gopalan Mall', | |||
| address: 'Mysore Road, Bangalore', | |||
| is_bookmarked: false, | |||
| is_bookmarked: true, | |||
| is_archived: false, | |||
| image_url: 'https://www.gopalanmall.com/images/mall-arcade-01.jpg', | |||
| description: 'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.', | |||
| @@ -11,7 +11,7 @@ export const OUTLETS: Outlet[] = [new Outlet({ | |||
| menu_items: MENU_ITEMS_1.map((menu_item) => menu_item.id), | |||
| offers: OFFERS.map((offer) => offer.id), | |||
| outlet_type: OutletType.FOOD, | |||
| is_bookmarked: false, | |||
| is_bookmarked: true, | |||
| rating: 3.5, | |||
| }), new Outlet({ | |||
| id: '0002', | |||
| @@ -22,7 +22,7 @@ export const OUTLETS: Outlet[] = [new Outlet({ | |||
| tags: [], | |||
| menu_items: [], | |||
| outlet_type: OutletType.SHOP, | |||
| is_bookmarked: true, | |||
| is_bookmarked: false, | |||
| rating: 4.8, | |||
| }), new Outlet({ | |||
| id: '0003', | |||
| @@ -8,12 +8,14 @@ import { OutletService } from './outlet.service'; | |||
| providedIn: 'root' | |||
| }) | |||
| export class MallService { | |||
| malls: Array<IMall>; | |||
| malls: Array<IMall> = []; | |||
| constructor( | |||
| private offerService: OfferService, | |||
| private outletService: OutletService | |||
| ) { } | |||
| ) { | |||
| this.fetchMalls(); | |||
| } | |||
| private getDenormalizedMall = async (mall: Mall) => { | |||
| const offers = await Promise.all(mall.offers.map(offer_id => this.offerService.getOfferByID(offer_id))); | |||
| @@ -27,17 +29,23 @@ export class MallService { | |||
| } | |||
| public async getAllMalls() { | |||
| this.malls = await Promise.all(MALLS.map(this.getDenormalizedMall)); | |||
| return this.malls; | |||
| } | |||
| public async getMallByID(id: string) { | |||
| private async fetchMalls() { | |||
| this.malls = await Promise.all(MALLS.map(this.getDenormalizedMall)); | |||
| return this.malls.find((mall) => mall.id === id); | |||
| } | |||
| public async getMallByID(id: string) { | |||
| if (this.malls.length <= 0) { | |||
| await this.fetchMalls(); | |||
| return this.malls.find((mall) => mall.id === id); | |||
| } else { | |||
| return this.malls.find((mall) => mall.id === id); | |||
| } | |||
| } | |||
| async updateMall(data: IMall) { | |||
| this.malls = await Promise.all(MALLS.map(this.getDenormalizedMall)); | |||
| for (let i = 0; i < this.malls.length; i += 1) { | |||
| if (data.id === this.malls[i].id) { | |||
| this.malls[i] = data; | |||