Skip to content

Commit

Permalink
feat(page): change view mode to category in browse page
Browse files Browse the repository at this point in the history
  • Loading branch information
bravemaster619 committed May 2, 2020
1 parent 451cfd7 commit d272245
Show file tree
Hide file tree
Showing 13 changed files with 349 additions and 11 deletions.
7 changes: 7 additions & 0 deletions src/app/pages/browse/browse-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ const routes: Routes = [
loadChildren: () =>
import("../order/order.module").then((m) => m.OrderPageModule)
},
{
path: "all-categories",
loadChildren: () =>
import("./categories/categories.module").then(
(m) => m.CategoriesPageModule
)
},
{
path: "categories",
loadChildren: () =>
Expand Down
11 changes: 8 additions & 3 deletions src/app/pages/browse/browse.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import { LocationSearchModule } from "src/app/components/location-search/locatio
import { LocalValueDirectiveModule } from "src/app/directives/local-value.module";
import { IonImageModule } from "src/app/components/ion-image/ion-image.module";
import { MerchantListComponent } from "./merchant-list/merchant-list.component";
import { CategoryListComponent } from "./category-list/category-list.component";
import { ProductListModule } from "src/app/components/product-list/product-list.module";
import { PricePipeModule } from "src/app/pipes/price/price.module";
import { CategoryListModule } from "./category-list/category-list.module";

@NgModule({
imports: [
Expand All @@ -25,8 +27,11 @@ import { CategoryListComponent } from "./category-list/category-list.component";
HttpClientModule,
LocationSearchModule,
LocalValueDirectiveModule,
IonImageModule
IonImageModule,
ProductListModule,
PricePipeModule,
CategoryListModule
],
declarations: [BrowsePage, MerchantListComponent, CategoryListComponent]
declarations: [BrowsePage, MerchantListComponent]
})
export class BrowsePageModule {}
87 changes: 83 additions & 4 deletions src/app/pages/browse/browse.page.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,70 @@
debounce="1000"
(ionChange)="handleSearch($event)"
></ion-searchbar>
<ng-container *ngIf="viewMode === 'category-only'; Else segmentMode">
<ion-row class="ion-padding-start ion-padding-end ion-margin-bottom">
<ion-col *ngFor="let category of categories.slice(0,11)" size="3" class="ion-no-margin ion-no-padding">
<ion-button
[color]="selectedCategoryId === category._id ? 'success' : 'light'"
[disabled]="!availableMerchantIds || !availableMerchantIds.length"
size="small"
expand="full"
localValue
[data]="category"
key="name"
(click)="handleSelectCategory(category)"
>
</ion-button>
</ion-col>
<ion-col *ngIf="categories.length >= 12" size="3" class="ion-no-margin ion-no-padding">
<ion-button
color="tertiary"
size="small"
expand="full"
(click)="selectedCategoryId = 'more'"
style="text-align: center; font-weight: 600;"
localValue
routerLink="/tabs/browse/all-categories"
>
...
</ion-button>
</ion-col>
</ion-row>
<ion-row class="ion-padding-start ion-padding-end">
<ng-container *ngIf="!loading; Else skeleton">
<ng-container *ngIf="products.length; Else empty">
<ion-col size="4" *ngFor="let product of products">
<ion-card class="ion-no-margin card-product" (click)="onProductClick(product)">
<ion-card-content>
<div class="wrapper-product-img">
<app-ion-image
[src]="getPictureUrl(product)"
[alt]="product.name"
style="object-fit:cover;"
></app-ion-image>
</div>
<ion-label class="label-product-name">
<h3 localValue [data]="product" [key]="'name'"></h3>
<p>{{product|price}}</p>
</ion-label>
</ion-card-content>
</ion-card>
</ion-col>
</ng-container>
</ng-container>
</ion-row>
</ng-container>
</ion-content>

<ng-template #empty>
<ion-col size="12" align="center">
<ion-label translate="No data to display"></ion-label>
</ion-col>
</ng-template>

<ng-template #segmentMode>
<ion-row class="ion-padding">
<ion-segment [(ngModel)]="viewMode">
<ion-segment [(ngModel)]="viewSegment">
<ion-segment-button value="merchant">
<ion-label translate="Merchant"></ion-label>
</ion-segment-button>
Expand All @@ -20,6 +82,23 @@
</ion-segment-button>
</ion-segment>
</ion-row>
<merchant-list *ngIf="viewMode === 'merchant'"></merchant-list>
<category-list *ngIf="viewMode === 'category'"></category-list>
</ion-content>
<merchant-list *ngIf="viewSegment === 'merchant'"></merchant-list>
<category-list *ngIf="viewSegment === 'category'"></category-list>
</ng-template>

<ng-template #skeleton>
<ion-col *ngFor="let i of [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]" size="4">
<ion-card class="ion-no-margin card-product">
<ion-card-content>
<div class="wrapper-product-img">
<app-ion-image
src="assets/img/no-image.png"
alt="awesome product"
></app-ion-image>
</div>
<ion-skeleton-text animated style="height: 0.5rem;"></ion-skeleton-text>
<ion-skeleton-text animated style="height: 0.5rem;"></ion-skeleton-text>
</ion-card-content>
</ion-card>
</ion-col>
</ng-template>
24 changes: 24 additions & 0 deletions src/app/pages/browse/browse.page.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,30 @@
ion-searchbar {
padding: 1rem;
}
.sc-ion-searchbar-ios-h {
-webkit-padding-start: 1rem;
padding-inline-start: 1rem;
-webkit-padding-end: 1rem;
padding-inline-end: 1rem;
}
.card-product {
border: 1px solid #ccc;
ion-card-content {
padding: 0.5rem;
.wrapper-product-img {
margin-top: -10px;
margin-left: -10px;
margin-right: -10px;
margin-bottom: 5px;
}
ion-label {
h3 {
font-size: 0.75rem;
font-weight: 600;
}
p {
font-size: 0.75rem;
}
}
}
}
6 changes: 5 additions & 1 deletion src/app/pages/browse/browse.page.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { RouterTestingModule } from "@angular/router/testing";
import { FormsModule } from "@angular/forms";
import { CategoryListComponent } from "./category-list/category-list.component";
import { MerchantListComponent } from "./merchant-list/merchant-list.component";
import { ProductListModule } from "src/app/components/product-list/product-list.module";
import { PricePipeModule } from "src/app/pipes/price/price.module";
describe("BrowsePage", () => {
let component: BrowsePage;
let fixture: ComponentFixture<BrowsePage>;
Expand All @@ -35,7 +37,9 @@ describe("BrowsePage", () => {
IonImageModule,
LocalValueDirectiveModule,
IonicStorageModule.forRoot(),
FormsModule
FormsModule,
ProductListModule,
PricePipeModule
]
}).compileComponents();

Expand Down
97 changes: 94 additions & 3 deletions src/app/pages/browse/browse.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,37 @@ import { LocationInterface } from "src/app/models/location.model";
import { LocationService } from "src/app/services/location/location.service";
import { AlertController } from "@ionic/angular";
import { Router } from "@angular/router";
import { ApiService } from "src/app/services/api/api.service";
import { CategoryInterface } from "src/app/models/category.model";
import { ProductInterface } from "src/app/models/product.model";
import { getPictureUrl } from "src/app/models/product.model";
@Component({
selector: "app-browse",
templateUrl: "./browse.page.html",
styleUrls: ["./browse.page.scss"]
})
export class BrowsePage implements OnInit {
location: LocationInterface;
viewMode: string;
viewMode: "segment" | "category-only";
viewSegment: string;
categories: Array<CategoryInterface>;
selectedCategoryId: string;
availableMerchantIds: Array<string>;
products: Array<ProductInterface>;
loading: boolean;
constructor(
private loc: LocationService,
private alert: AlertController,
private translator: TranslateService,
private router: Router
private router: Router,
private api: ApiService
) {
this.viewMode = "merchant";
this.viewSegment = "merchant";
this.viewMode = "category-only";
this.categories = [];
this.selectedCategoryId = "";
this.availableMerchantIds = [];
this.loading = true;
}

ngOnInit() {
Expand All @@ -28,6 +44,19 @@ export class BrowsePage implements OnInit {
this.router.navigate(["/tabs/my-account/setting"]);
}
});
this.getAvailableMerchantIds().then(() => {
this.api.get("Categories/G").then((observable) => {
observable.subscribe((resp: { code: string; data: Array<any> }) => {
if (resp.code === "success") {
this.categories = resp.data;
if (this.categories.length) {
this.selectedCategoryId = this.categories[0]._id;
this.getProducts();
}
}
});
});
});
}

showAlert() {
Expand All @@ -54,4 +83,66 @@ export class BrowsePage implements OnInit {
});
}
}

handleSelectCategory(category: CategoryInterface) {
this.loading = true;
this.selectedCategoryId = category._id;
this.getProducts();
}

getProducts() {
this.api
.geth(
"Products",
{
categoryId: this.selectedCategoryId,
merchantId: { $in: this.availableMerchantIds }
},
true,
"filter"
)
.then((resp: Array<ProductInterface>) => {
this.products = resp;
this.loading = false;
});
}

async getAvailableMerchantIds() {
return new Promise((resolve, reject) => {
this.loc.getLocation().subscribe((location) => {
this.location = location;
if (!this.location) return;
this.api
.get("/Areas/G/my", {
lat: this.location.lat,
lng: this.location.lng
})
.then((observable) => {
observable.subscribe((resp: { code: string; data: any }) => {
if (resp.code === "success") {
this.api
.geth("MerchantSchedules/availableMerchants", {
areaId: resp.data._id
})
.then((merchantIds: Array<string>) => {
this.availableMerchantIds = merchantIds;
resolve(merchantIds);
});
} else {
reject(resp);
}
});
})
.catch((e) => {
reject(e);
});
});
});
}
onProductClick(product: ProductInterface) {
this.router.navigate(["/tabs/browse/products", product._id]);
}
getPictureUrl(product: ProductInterface) {
return getPictureUrl(product);
}
}
17 changes: 17 additions & 0 deletions src/app/pages/browse/categories/categories-routing.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { NgModule } from "@angular/core";
import { Routes, RouterModule } from "@angular/router";

import { CategoriesPage } from "./categories.page";

const routes: Routes = [
{
path: "",
component: CategoriesPage
}
];

@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class CategoriesPageRoutingModule {}
24 changes: 24 additions & 0 deletions src/app/pages/browse/categories/categories.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
import { FormsModule } from "@angular/forms";

import { IonicModule } from "@ionic/angular";

import { CategoriesPageRoutingModule } from "./categories-routing.module";

import { CategoriesPage } from "./categories.page";
import { TranslateModule } from "@ngx-translate/core";
import { CategoryListModule } from "src/app/pages/browse/category-list/category-list.module";

@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
CategoriesPageRoutingModule,
TranslateModule.forChild(),
CategoryListModule
],
declarations: [CategoriesPage]
})
export class CategoriesPageModule {}
12 changes: 12 additions & 0 deletions src/app/pages/browse/categories/categories.page.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button defaultHref="/tabs/browse" text=""></ion-back-button>
</ion-buttons>
<ion-title translate="Category"></ion-title>
</ion-toolbar>
</ion-header>

<ion-content>
<category-list></category-list>
</ion-content>
Empty file.
Loading

0 comments on commit d272245

Please sign in to comment.