瀏覽代碼

Mall details page added

master
kj1352 6 年之前
父節點
當前提交
f2780fdc26
共有 7 個檔案被更改,包括 446 行新增124 行删除
  1. +112
    -6
      src/app/mall-details/mall-details.page.html
  2. +156
    -1
      src/app/mall-details/mall-details.page.scss
  3. +30
    -1
      src/app/mall-details/mall-details.page.ts
  4. +4
    -4
      src/app/malls/malls.page.html
  5. +0
    -110
      src/app/malls/malls.page.scss
  6. +34
    -2
      src/app/services/mall.service.ts
  7. +110
    -0
      src/global.scss

+ 112
- 6
src/app/mall-details/mall-details.page.html 查看文件

@@ -1,17 +1,39 @@
<ion-content *ngIf="mall_details">
<ion-content [scrollEvents]="true" *ngIf="mall_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> {{ mall_details.name }} </h3>
</div>
<div class="stats-holder">
<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>
<div class="utilities-buttons-holder">
<button [ngClass]="{'active' : mall_details.is_bookmarked }" (click)="toggleBookmark(mall_details)"> <ion-icon name="bookmark"></ion-icon> </button>
<button> <ion-icon name="share"></ion-icon> </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="upfold-holder">
<img src="{{ mall_details.image_url }}">
<div class="icons-holder">
<div>
<button> <ion-icon name="arrow-back"></ion-icon> </button>
<button (click)="back()"> <ion-icon name="arrow-back"></ion-icon> </button>
</div>
<div>
<button [ngClass]="{'active' : mall_details.is_bookmarked }"> <ion-icon name="bookmark"></ion-icon> </button>
<button [ngClass]="{'active' : mall_details.is_bookmarked }" (click)="toggleBookmark(mall_details)">
<ion-icon name="bookmark"></ion-icon>
</button>
<button> <ion-icon name="share"></ion-icon> </button>
</div>
</div>
<div class="icons-holder navigate-button">
<button> <ion-icon name="navigate"></ion-icon> </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">
@@ -27,9 +49,93 @@

<div class="tabs-holder" [ngClass]="{ 'right' : selected_tab === 'shopping' }">
<button class="tab" [ngClass]="{ 'active' : selected_tab === 'food' }"
(click)="selected_tab = 'food'"> FOOD OFFERS </button>
(click)="selected_tab = 'food'"> FOOD OUTLETS </button>
<button class="tab" [ngClass]="{ 'active' : selected_tab === 'shopping' }"
(click)="selected_tab = 'shopping'"> SHOPPING OFFERS </button>
(click)="selected_tab = 'shopping'"> SHOPS </button>
</div>

<div class="results-utilities-holder">
<h5 *ngIf="mall_details"> {{ mall_details.outlets.length }} OUTLETS </h5>
<ion-button color="default" fill="clear"> SORT / FILTER </ion-button>
</div>

<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 }">
<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.is_food_outlet"> <ion-icon name="restaurant"></ion-icon> Food </span>
<span *ngIf="!outlet.is_food_outlet"> <ion-icon name="basket"></ion-icon> Shopping </span>
Offers: <strong> {{ outlet.offers.length }} </strong>
</div>
</div>
</ion-label>
</ion-item>
</ion-list>

<ion-list lines="none" class="result-list" *ngIf="selected_tab === 'shopping'">
<ion-item *ngFor="let outlet of mall_details.outlets" [ngClass]="{'show' : !outlet.is_food_outlet }">
<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.is_food_outlet"> <ion-icon name="restaurant"></ion-icon> Food </span>
<span *ngIf="!outlet.is_food_outlet"> <ion-icon name="basket"></ion-icon> Shopping </span>
Offers: <strong> {{ outlet.offers.length }} </strong>
</div>
</div>
</ion-label>
</ion-item>
</ion-list>


<div class="advertisement-slots">
<figure>
<img src="https://static.couponspy.in/picture/coupon/89472.jpg">
</figure>

<figure>
<img src="https://content.adidas.co.in/static/sign_up_popup/sign_up_popup.jpg">
</figure>

<figure>
<img src="https://fsmc.s3.amazonaws.com/a/90804/adidas.jpg">
</figure>

<figure>
<img src="https://static.couponspy.in/picture/coupon/89472.jpg">
</figure>

<figure>
<img src="https://static.couponspy.in/picture/coupon/89472.jpg">
</figure>
</div>

</ion-content>

+ 156
- 1
src/app/mall-details/mall-details.page.scss 查看文件

@@ -1,3 +1,84 @@
.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;
@@ -17,9 +98,15 @@
left: 86%;
bottom: 30px;
width: auto;

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

button {
button, a {
background-color: white;
color: var(--brand-blue);
font-size: 18px;
@@ -135,3 +222,71 @@
}
}
}

.result-list {
ion-item {
display: none;

&.show {
display: block;
}

h3 .rating-holder {
font-size: 9px;
margin-left: auto;
align-self: flex-start;
display: flex;
align-items: flex-end;
margin-right: 10px;

ion-icon {
font-size: 12px;
margin-right: 3px;
}
}

.offers-holder {
border-bottom: 0;
border-top: 1px solid #efefef;

.offer {
ion-icon {
color: var(--brand-grey);
transform: scale(1.1);
}
}
}

.description {
margin: 5px 0;
.share-button {
float: right;
font-size: 14px;
background-color: transparent;
border: 0px;
color: var(--brand-dark-grey);
padding: 0;
}
}
}
}

.advertisement-slots {
white-space: nowrap;
width: 100%;
overflow-x: auto;

figure {
margin: 0;
display: inline-block;
width: 100px;
height: 100px;
margin: 0 5px;

img {
object-fit: cover;
width: 100%;
height: 100%;
}
}
}

+ 30
- 1
src/app/mall-details/mall-details.page.ts 查看文件

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

@Component({
selector: 'app-mall-details',
@@ -10,11 +11,13 @@ import { Mall, MallService } from '../services/mall.service';
export class MallDetailsPage implements OnInit {
mall_details: Mall;
selected_tab: string = 'food';
show_top_bar: boolean = false;

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

ngOnInit() {
@@ -25,4 +28,30 @@ export class MallDetailsPage implements OnInit {
});
}

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

this.mallService.getMallByID(mall_id).then((data: Mall) => {
this.mall_details = data;
});
}

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

toggleBookmark(mall_details: Mall) {
mall_details.is_bookmarked = !mall_details.is_bookmarked;
this.mallService.updateMallDetails(mall_details).then(() => this.refresh());
}


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

}

+ 4
- 4
src/app/malls/malls.page.html 查看文件

@@ -15,11 +15,11 @@
</div>

<div class="results-utilities-holder">
<h5> 15 MALLS </h5>
<h5 *ngIf="malls"> {{ malls.length }} MALLS </h5>
<ion-button color="default" fill="clear"> SORT / FILTER </ion-button>
</div>

<ion-list lines="none" class="malls-list">
<ion-list lines="none" class="result-list">
<ion-item *ngFor="let mall of malls" (click)="showMallDetails(mall)">
<img src="{{ mall.image_url }}" slot="start">
<ion-label>
@@ -69,7 +69,7 @@
<a> Know More </a>
</section>

<ion-list lines="none" class="malls-list">
<ion-list lines="none" class="result-list">
<ion-item *ngFor="let mall of malls" (click)="showMallDetails(mall)">
<img src="{{ mall.image_url }}" slot="start">
<ion-label>
@@ -116,7 +116,7 @@
<button> <ion-icon src="assets/custom/food-4.svg"></ion-icon> <span> Cake </span> </button>
</div>

<ion-list lines="none" class="malls-list">
<ion-list lines="none" class="result-list">
<ion-item *ngFor="let mall of malls" (click)="showMallDetails(mall)">
<img src="{{ mall.image_url }}" slot="start">
<ion-label>


+ 0
- 110
src/app/malls/malls.page.scss 查看文件

@@ -62,116 +62,6 @@
}
}

.results-utilities-holder {
display: flex;
width: 100%;
margin: 10px auto 0;
justify-content: space-between;
align-items: center;
font-weight: bold;

&.no-padding {
margin: 0 auto;
}

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

ion-button {
margin: 0;
font-size: 10px;
padding: 0;
}
}

.malls-list ion-item {
margin: 0 0 20px;

ion-label {
padding: 0;
margin: 0;
}

img {
align-self: flex-start;
width: 70px;
height: 70px;
object-fit: cover;
margin-right: 15px;
}

h3 {
margin: 0;
color: var(--brand-dark-grey);
font-weight: 500;
font-size: 14px;
letter-spacing: 0.5px;
text-overflow: ellipsis;
display: flex;
justify-content: space-between;

ion-icon {
color: var(--brand-grey);
font-size: 16px;

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

.description {
font-size: 12px;
color: var(--brand-grey);
}

.offers-holder {
display: flex;
justify-content: space-between;
color: var(--brand-yellow);
letter-spacing: 0.5px;
border-bottom: 1px solid var(--brand-grey);
padding: 7px 0;
margin-bottom: 7px;

.offer {
font-size: 10px;
width: 50%;
}
}

.utilities-holder {
display: flex;
justify-content: space-between;
align-items: center;

.container {
display: flex;
width: 40%;
justify-content: space-between;

.utility {
width: 50%;
font-size: 10px;
color: var(--brand-grey);
font-weight: bold;
}

.utility-button {
text-align: right;
width: 50%;
background-color: transparent;
border: 0;
font-size: 16px;
color: var(--brand-grey);
}
}
}
}

.advertisement {
height: 150px;
background-image: url('../../assets/custom/background-2.svg');


+ 34
- 2
src/app/services/mall.service.ts 查看文件

@@ -10,8 +10,9 @@ type Outlet = {
id: string,
image_url?: string,
name: string,
type: string,
description: string,
offers: Array<Offer>,
is_food_outlet: boolean,
is_bookmarked: boolean,
rating: number,
};
@@ -44,7 +45,29 @@ export class MallService {
is_archived: false,
image_url: 'https://www.gopalanmall.com/images/mall-arcade-01.jpg',
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.',
outlets: [],
outlets: [{
id: '0001',
image_url: 'https://images.markets.businessinsider.com/image/5a74835585cdd489228b47be-900/shutterstock643079686.jpg',
name: 'McDonalds',
description: 'Veg / Non-Veg Food Restaurant',
offers: [{
name: 'McDonalds Offer',
description: 'Get 25% offer on you first meal',
coupon_code: 'MCD25F',
}],
is_food_outlet: true,
is_bookmarked: false,
rating: 3.5,
}, {
id: '0002',
image_url: 'https://pbs.twimg.com/profile_images/354890582/symbol.jpg',
name: 'Shopper\'s stop',
description: 'Clothing store',
offers: [],
is_food_outlet: false,
is_bookmarked: true,
rating: 4.8,
}],
offer_collection: [{
name: 'Food',
offers: [{
@@ -116,4 +139,13 @@ export class MallService {
public async getMallByID(id: string) {
return this.malls.find((mall) => mall.id === id);
}

public async updateMallDetails(mall_details: Mall) {
for (let i = 0; i < this.malls.length; i += 1) {
if (this.malls[i].id === mall_details.id) {
this.malls[i] = mall_details;
}
}
return this.malls;
}
}

+ 110
- 0
src/global.scss 查看文件

@@ -168,3 +168,113 @@ header, h1, h2, h3, h4, h5 {
opacity: 0.5;
}
}

.results-utilities-holder {
display: flex;
width: 100%;
margin: 10px auto 0;
justify-content: space-between;
align-items: center;
font-weight: bold;

&.no-padding {
margin: 0 auto;
}

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

ion-button {
margin: 0;
font-size: 10px;
padding: 0;
}
}

.result-list ion-item {
margin: 0 0 20px;

ion-label {
padding: 0;
margin: 0;
}

img {
align-self: flex-start;
width: 70px;
height: 70px;
object-fit: cover;
margin-right: 15px;
}

h3 {
margin: 0;
color: var(--brand-dark-grey);
font-weight: 500;
font-size: 14px;
letter-spacing: 0.5px;
text-overflow: ellipsis;
display: flex;
justify-content: space-between;

ion-icon {
color: var(--brand-grey);
font-size: 16px;

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

.description {
font-size: 10px;
color: var(--brand-grey);
}

.offers-holder {
display: flex;
justify-content: space-between;
color: var(--brand-yellow);
letter-spacing: 0.5px;
border-bottom: 1px solid #efefef;
padding: 7px 0;
margin-bottom: 7px;

.offer {
font-size: 10px;
width: 50%;
}
}

.utilities-holder {
display: flex;
justify-content: space-between;
align-items: center;

.container {
display: flex;
width: 40%;
justify-content: space-between;

.utility {
width: 50%;
font-size: 10px;
color: var(--brand-grey);
font-weight: bold;
}

.utility-button {
text-align: right;
width: 50%;
background-color: transparent;
border: 0;
font-size: 16px;
color: var(--brand-grey);
}
}
}
}

Loading…
取消
儲存