Browse Source

Outlet details page partial completion

master
kj1352 6 years ago
parent
commit
eddfdb72a3
10 changed files with 483 additions and 5 deletions
  1. +1
    -0
      src/app/app-routing.module.ts
  2. +3
    -2
      src/app/mall-details/mall-details.page.html
  3. +4
    -1
      src/app/mall-details/mall-details.page.ts
  4. +26
    -0
      src/app/outlet-details/outlet-details.module.ts
  5. +82
    -0
      src/app/outlet-details/outlet-details.page.html
  6. +235
    -0
      src/app/outlet-details/outlet-details.page.scss
  7. +27
    -0
      src/app/outlet-details/outlet-details.page.spec.ts
  8. +50
    -0
      src/app/outlet-details/outlet-details.page.ts
  9. +54
    -1
      src/app/services/mall.service.ts
  10. +1
    -1
      src/global.scss

+ 1
- 0
src/app/app-routing.module.ts View File

@@ -7,6 +7,7 @@ const routes: Routes = [
{ path: 'login', loadChildren: './login/login.module#LoginPageModule' }, { path: 'login', loadChildren: './login/login.module#LoginPageModule' },
{ path: 'malls', loadChildren: './malls/malls.module#MallsPageModule' }, { path: 'malls', loadChildren: './malls/malls.module#MallsPageModule' },
{ path: 'mall-details', loadChildren: './mall-details/mall-details.module#MallDetailsPageModule' }, { path: 'mall-details', loadChildren: './mall-details/mall-details.module#MallDetailsPageModule' },
{ path: 'outlet-details', loadChildren: './outlet-details/outlet-details.module#OutletDetailsPageModule' },
]; ];


@NgModule({ @NgModule({


+ 3
- 2
src/app/mall-details/mall-details.page.html View File

@@ -40,7 +40,7 @@
<div class="card"> <div class="card">
<h3> {{ mall_details.name }} </h3> <h3> {{ mall_details.name }} </h3>
<div class="stats-holder"> <div class="stats-holder">
<div class="stat"> <ion-icon name="star"></ion-icon> {{ mall_details.rating }} <span>(2000)</span> </div>
<div class="stat"> <ion-icon name="star"></ion-icon> {{ mall_details.rating }} </div>
<div class="stat"> <ion-icon name="pin"></ion-icon> {{ mall_details.distance }} km</div> <div class="stat"> <ion-icon name="pin"></ion-icon> {{ mall_details.distance }} km</div>
</div> </div>
<p> {{ mall_details.description }} </p> <p> {{ mall_details.description }} </p>
@@ -60,7 +60,8 @@
</div> </div>


<ion-list lines="none" class="result-list" *ngIf="selected_tab === 'food'"> <ion-list lines="none" class="result-list" *ngIf="selected_tab === 'food'">
<ion-item *ngFor="let outlet of mall_details.outlets" [ngClass]="{'show' : outlet.is_food_outlet }">
<ion-item *ngFor="let outlet of mall_details.outlets" [ngClass]="{'show' : outlet.is_food_outlet }"
(click)="outletDetails(mall_details.id, outlet.id)">
<img src="{{ outlet.image_url }}" slot="start"> <img src="{{ outlet.image_url }}" slot="start">
<ion-label> <ion-label>
<h3> <h3>


+ 4
- 1
src/app/mall-details/mall-details.page.ts View File

@@ -45,7 +45,6 @@ export class MallDetailsPage implements OnInit {
this.mallService.updateMallDetails(mall_details).then(() => this.refresh()); this.mallService.updateMallDetails(mall_details).then(() => this.refresh());
} }



onScroll(event: any) { onScroll(event: any) {
if (event.detail.scrollTop > 100) { if (event.detail.scrollTop > 100) {
this.show_top_bar = true; this.show_top_bar = true;
@@ -54,4 +53,8 @@ export class MallDetailsPage implements OnInit {
} }
} }


outletDetails(mall_id: string, outlet_id: string) {
this.router.navigate(['/outlet-details', { mall_id: mall_id, outlet_id: outlet_id }]);
}

} }

+ 26
- 0
src/app/outlet-details/outlet-details.module.ts View File

@@ -0,0 +1,26 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { Routes, RouterModule } from '@angular/router';

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

import { OutletDetailsPage } from './outlet-details.page';

const routes: Routes = [
{
path: '',
component: OutletDetailsPage
}
];

@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
RouterModule.forChild(routes)
],
declarations: [OutletDetailsPage]
})
export class OutletDetailsPageModule {}

+ 82
- 0
src/app/outlet-details/outlet-details.page.html View File

@@ -0,0 +1,82 @@
<ion-content [scrollEvents]="true" *ngIf="outlet_details" (ionScroll)="onScroll($event)">
<div class="header-bar" [ngClass]="{'active' : show_top_bar }">
<div class="heading-holder">
<button (click)="back()"> <ion-icon name="arrow-back"></ion-icon> </button>
<h3> {{ outlet_details.name }} </h3>
</div>
<div class="stats-holder">
<div class="stat"> <ion-icon name="star"></ion-icon> {{ outlet_details.rating }} </div>
</div>
<div class="utilities-buttons-holder">
<button [ngClass]="{'active' : outlet_details.is_bookmarked }"> <ion-icon name="bookmark"></ion-icon> </button>
<button> <ion-icon name="share"></ion-icon> </button>
</div>
</div>

<div class="upfold-holder">
<img src="{{ outlet_details.image_url }}">
<div class="icons-holder">
<div>
<button (click)="back()"> <ion-icon name="arrow-back"></ion-icon> </button>
</div>
<div>
<button [ngClass]="{'active' : outlet_details.is_bookmarked }">
<ion-icon name="bookmark"></ion-icon>
</button>
<button> <ion-icon name="share"></ion-icon> </button>
</div>
</div>
<div class="icons-holder navigate-button">
<a target="_blank" href="https://maps.google.com/?q={{ mall_details.location.latitude }},{{ mall_details.location.longitude }}">
<ion-icon name="navigate"></ion-icon>
</a>
</div>
</div>

<div class="card-holder">
<div class="card">
<h3> {{ outlet_details.name }} </h3>
<div class="stats-holder">
<div class="stat"> <ion-icon name="star"></ion-icon> {{ outlet_details.rating }} </div>
</div>
<p> {{ outlet_details.description }} </p>
</div>
</div>

<div class="menu-card-holder">
<header>
<h3> MENU </h3>
<div class="toggle"> VEG MENU <ion-toggle [(ngModel)]="show_only_veg"></ion-toggle> </div>
</header>
<div class="tags-holder">
<button [ngClass]="{'active' : selected_tag === tag}" (click)="selected_tag = tag" *ngFor="let tag of outlet_details.tags"> {{ tag }} </button>
</div>

<div class="results-utilities-holder">
<h5 *ngIf="outlet_details"> {{ outlet_details.menu_items.length }} FOOD ITEMS </h5>
<ion-button color="default" fill="clear"> SORT / FILTER </ion-button>
</div>

<div class="items-holder">

<div class="item" *ngFor="let item of outlet_details.menu_items">
<div class="rating"> {{ item.rating }} </div>
<img src="{{ item.image_url }}">
<h5> {{ item.name }} </h5>
<p> {{ item.description }} </p>
<div class="label-holder">
<div class="category" [ngClass]="{'non-veg' : !item.is_vegeterian, 'veg' : item.is_vegeterian }"></div>
<span *ngIf="!item.is_vegeterian"> Non-Veg Meals </span>
<span *ngIf="item.is_vegeterian"> Veg Meals </span>
</div>
<div class="duration"> {{ item.wait_duration }} Minutes </div>
<div class="price">
<span class="discounted"> {{ calculateDiscount(item.price, item.discount) }} </span>
<span class="actual-price"> {{ item.price }} </span>
</div>
</div>

</div>
</div>

</ion-content>

+ 235
- 0
src/app/outlet-details/outlet-details.page.scss View File

@@ -0,0 +1,235 @@
.header-bar {
background-image: url('../../assets/custom/background-2.svg');
background-size: cover;
background-repeat: no-repeat;
background-position: left top;
display: flex;
align-items: center;
justify-content: space-between;
padding: 15px;
height: 75px;
z-index: 2;
pointer-events: none;
opacity: 0;
top: 0;
left: 0;
width: 100%;
position: fixed;
transition: opacity 0.5s;
box-shadow: 0px 3px 5px var(--brand-grey);

&.active {
opacity: 1;
pointer-events: all;
}


.heading-holder {
display: flex;
align-items: center;
}

button, a {
background-color: white;
color: var(--brand-blue);
font-size: 18px;
padding: 5px;
border-radius: 50%;
height: 30px;
width: 30px;
display: flex;
justify-content: center;
align-items: center;

&.active {
color: white;
background-color: var(--brand-blue);
}
}

h3 {
font-size: 16px;
color: white;
letter-spacing: 0.5px;
margin-left: 10px;
font-weight: 600;
}

.stats-holder {
font-size: 10px;
color: white;
display: flex;
align-items: center;

.stat {
margin-left: 10px;
}
}

.utilities-buttons-holder {
position: absolute;
right: 15px;
bottom: -15px;
display: flex;
align-items: center;
button, a {
margin-left: 10px;
box-shadow: 0px 3px 5px var(--brand-grey);
}
}
}

.upfold-holder {
position: relative;
height: 45vh;
width: 100%;
padding-top: 30px;
margin-bottom: -25px;

.icons-holder {
position: relative;
display: flex;
width: 90%;
margin: 0 auto;
justify-content: space-between;

&.navigate-button {
position: absolute;
left: 86%;
bottom: 30px;
width: auto;

a {
display: flex;
justify-content: center;
align-items: center;
}
}

button, a {
background-color: white;
color: var(--brand-blue);
font-size: 18px;
padding: 5px;
border-radius: 50%;
height: 30px;
width: 30px;
display: block;
margin-bottom: 10px;
box-shadow: 0px 0px 5px var(--brand-grey);

&.active {
background-color: var(--brand-blue);
color: white;
}
}
}

img {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
object-fit: cover;
filter: brightness(80%);
}
}

.card-holder {
background-color: transparent;
position: relative;

.card {
box-shadow: 0px 0px 5px var(--brand-grey);
width: 90%;
margin: 0 auto;
border-radius: 10px;
overflow: hidden;
padding: 20px;
background-color: white;

h3 {
color: var(--brand-dark-grey);
font-size: 20px;
letter-spacing: 0.5px;
font-weight: 600;
}

.stats-holder {
display: flex;
justify-content: space-between;
color: var(--brand-blue);
font-size: 10px;
font-weight: bold;
margin: 15px 0;

span {
color: var(--brand-grey);
}
}

p {
margin: 0 auto;
font-size: 11px;
line-height: 1.5;
color: var(--brand-grey);
}
}
}

.menu-card-holder {
margin: 25px 0;

header {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
background-color: #efefef;
color: var(--brand-dark-grey);
padding: 5px 0 5px 15px;
}

h3 {
font-size: 12px;
}

.toggle {
font-size: 10px;
display: flex;
align-items: center;

ion-toggle {
--handle-background: var(--brand-blue);
--handle-background-checked: var(--brand-blue);
transform: scale(0.8);
}
}

.tags-holder {
display: flex;
flex-wrap: wrap;
padding: 25px 15px 0;

button {
border: 1px solid var(--brand-blue);
border-radius: 30px;
color: var(--brand-blue);
font-size: 12px;
padding: 7px 15px;
background-color: white;
margin-right: 10px;
margin-bottom: 15px;

&.active {
background-color: var(--brand-blue);
color: white;
}
}
}

.results-utilities-holder {
margin-top: 0;
}
}

+ 27
- 0
src/app/outlet-details/outlet-details.page.spec.ts View File

@@ -0,0 +1,27 @@
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { OutletDetailsPage } from './outlet-details.page';

describe('OutletDetailsPage', () => {
let component: OutletDetailsPage;
let fixture: ComponentFixture<OutletDetailsPage>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ OutletDetailsPage ],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(OutletDetailsPage);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});

+ 50
- 0
src/app/outlet-details/outlet-details.page.ts View File

@@ -0,0 +1,50 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Location } from '@angular/common';
import { Mall, Outlet, MallService } from '../services/mall.service';

@Component({
selector: 'app-outlet-details',
templateUrl: './outlet-details.page.html',
styleUrls: ['./outlet-details.page.scss'],
})
export class OutletDetailsPage implements OnInit {
mall_details: Mall;
outlet_details: Outlet;
show_top_bar: boolean = false;
show_only_veg: boolean = false;
selected_tag: string = null;

constructor(
private route: ActivatedRoute,
private location: Location,
private mallService: MallService,
) { }

ngOnInit() {
let mall_id = this.route.snapshot.paramMap.get('mall_id');
let outlet_id = this.route.snapshot.paramMap.get('outlet_id');

this.mallService.getMallByID(mall_id).then((data: Mall) => {
this.mall_details = data;
this.outlet_details = this.mall_details.outlets.find((outlet) => outlet.id === outlet_id);
});
}

back() {
this.location.back();
}

onScroll(event: any) {
if (event.detail.scrollTop > 100) {
this.show_top_bar = true;
} else {
this.show_top_bar = false;
}
}

calculateDiscount(price: number, discount: number) {
return price - (price * discount / 100);
}

}

+ 54
- 1
src/app/services/mall.service.ts View File

@@ -6,12 +6,28 @@ type CoOrdinates = {
longitude: number, longitude: number,
}; };


type Outlet = {

type MenuItem = {
id: string,
name: string,
image_url?: string,
description: string,
is_vegeterian: boolean,
wait_duration: number,
price: number,
discount: number,
rating: number,
tags: Array<string>
};

export type Outlet = {
id: string, id: string,
image_url?: string, image_url?: string,
name: string, name: string,
description: string, description: string,
offers: Array<Offer>, offers: Array<Offer>,
tags: Array<string>,
menu_items: Array<MenuItem>,
is_food_outlet: boolean, is_food_outlet: boolean,
is_bookmarked: boolean, is_bookmarked: boolean,
rating: number, rating: number,
@@ -50,6 +66,41 @@ export class MallService {
image_url: 'https://images.markets.businessinsider.com/image/5a74835585cdd489228b47be-900/shutterstock643079686.jpg', image_url: 'https://images.markets.businessinsider.com/image/5a74835585cdd489228b47be-900/shutterstock643079686.jpg',
name: 'McDonalds', name: 'McDonalds',
description: 'Veg / Non-Veg Food Restaurant', description: 'Veg / Non-Veg Food Restaurant',
tags: ['dinner', 'spicy', 'breakfast', 'pork'],
menu_items: [{
id: '0001',
name: 'McSpicy Paneer',
image_url: 'https://www.mcdonalds.com.my/images/nasi_lemak/burger/burger.jpg?id=bb965dd67df3afa52033',
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 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.',
is_vegeterian: true,
wait_duration: 10,
price: 90,
discount: 10,
rating: 4,
tags: ['burger', 'breakfast']
}, {
id: '0002',
name: 'McAloo Tikki',
image_url: 'https://www.mcdonalds.com.my/images/nasi_lemak/burger/burger.jpg?id=bb965dd67df3afa52033',
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 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.',
is_vegeterian: false,
wait_duration: 13,
price: 120,
discount: 50,
rating: 4.3,
tags: ['spicy', 'dinner']
}, {
id: '0003',
name: 'McPork',
image_url: 'https://www.mcdonalds.com.my/images/nasi_lemak/burger/burger.jpg?id=bb965dd67df3afa52033',
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 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.',
is_vegeterian: false,
wait_duration: 20,
price: 300,
discount: 5,
rating: 4.9,
tags: ['spicy', 'dinner', 'pork']
}],
offers: [{ offers: [{
name: 'McDonalds Offer', name: 'McDonalds Offer',
description: 'Get 25% offer on you first meal', description: 'Get 25% offer on you first meal',
@@ -64,6 +115,8 @@ export class MallService {
name: 'Shopper\'s stop', name: 'Shopper\'s stop',
description: 'Clothing store', description: 'Clothing store',
offers: [], offers: [],
tags: [],
menu_items: [],
is_food_outlet: false, is_food_outlet: false,
is_bookmarked: true, is_bookmarked: true,
rating: 4.8, rating: 4.8,


+ 1
- 1
src/global.scss View File

@@ -183,7 +183,7 @@ header, h1, h2, h3, h4, h5 {


h5 { h5 {
margin: 0 0 0 10px; margin: 0 0 0 10px;
color: var(--brand-grey);
color: var(--brand-dark-grey);
font-size: 10px; font-size: 10px;
} }




Loading…
Cancel
Save