소스 검색

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);
}
}
}
}

불러오는 중...
취소
저장