| @@ -1,23 +1,24 @@ | |||||
| <ion-content> | <ion-content> | ||||
| <div class="content-container"> | |||||
| <section class="action-buttons"> | |||||
| <div class="nav"> | |||||
| <button (click)="back()"> <ion-icon name="chevron-back-outline"></ion-icon> <span> BACK </span> </button> | |||||
| </div> | |||||
| <header> {{ matchDay.matchDetails.home.name }} v/s {{ matchDay.matchDetails.away.name }} <br> <span> {{ matchDay.staduim.name }} Stadium </span> </header> | |||||
| <div class="action"> | |||||
| <button> <ion-icon name="share-social-outline"></ion-icon> </button> | |||||
| </div> | |||||
| </section> | |||||
| <section class="action-buttons"> | |||||
| <div class="nav"> | |||||
| <button (click)="back()"> <ion-icon name="chevron-back-outline"></ion-icon> <span> BACK </span> </button> | |||||
| </div> | |||||
| <header> {{ matchDay.matchDetails.home.name }} v/s {{ matchDay.matchDetails.away.name }} <br> | |||||
| <span> {{ matchDay.staduim.name }} Stadium, <br> {{ getEventDateTime(matchDay.dateTime) }} </span> </header> | |||||
| <div class="action"> | |||||
| <button> <ion-icon name="share-social-outline"></ion-icon> </button> | |||||
| </div> | |||||
| </section> | |||||
| <div class="content-container" [ngClass]="{'push-bottom' : selectedSeats.length > 0}"> | |||||
| <section class="upfold"> | <section class="upfold"> | ||||
| <img class="bg-img" [src]="matchDay.staduim.sideView"> | |||||
| <!-- <img class="bg-img" [src]="matchDay.staduim.sideView"> --> | |||||
| <ul class="quadrants"> | <ul class="quadrants"> | ||||
| <li *ngFor="let stands of matchDay.seatsAvailable" | |||||
| [ngClass]="{'active' : selectedStand === stands.stand}" | |||||
| (click)="selectedStand = stands.stand"> | |||||
| <li *ngFor="let stands of matchDay.seatsAvailable; let i = index;" | |||||
| [ngClass]="{'active' : selectedStand === i}" | |||||
| (click)="selectedStand = i"> | |||||
| <label> {{ stands.stand }} Stand </label> | <label> {{ stands.stand }} Stand </label> | ||||
| </li> | </li> | ||||
| </ul> | </ul> | ||||
| @@ -35,19 +36,32 @@ | |||||
| </header> | </header> | ||||
| <ul class="stand-list"> | <ul class="stand-list"> | ||||
| <li *ngFor="let stands of matchDay.seatsAvailable" | |||||
| [ngClass]="{'active' : selectedStand === stands.stand}" | |||||
| (click)="selectedStand = stands.stand"> | |||||
| <li *ngFor="let stands of matchDay.seatsAvailable; let i = index;" | |||||
| [ngClass]="{'active' : selectedStand === i}" | |||||
| (click)="selectedStand = i"> | |||||
| <label> | <label> | ||||
| {{ getFirstChar(stands.stand) }} | {{ getFirstChar(stands.stand) }} | ||||
| </label> | </label> | ||||
| <p> | <p> | ||||
| {{ stands.seats.length }} seats remaining, <br> starts from <strong> ₹ {{ stands.seats[0].price }} </strong> | |||||
| <span *ngIf="stands.seats.length > 0"> {{ stands.seats.length }} </span> | |||||
| <span *ngIf="stands.seats.length === 0"> {{ stands.seats.length }} </span> | |||||
| seats remaining, <br> <span *ngIf="stands.seats.length > 0"> starts from <strong> ₹ {{ stands.seats[0].price }} </strong> </span> | |||||
| </p> | </p> | ||||
| <div class="count-action" *ngIf="selectedStand === i"> | |||||
| <button (click)="removeSeat()" | |||||
| [ngClass]="{'active' : selectedSeats.length > 0}"> - </button> | |||||
| <span class="count"> {{ selectedSeats.length }} </span> | |||||
| <button (click)="addSeat()" | |||||
| [ngClass]="{'active' : stands.seats.length > 0}"> + </button> | |||||
| </div> | |||||
| </li> | </li> | ||||
| </ul> | </ul> | ||||
| </section> | </section> | ||||
| </div> | </div> | ||||
| <section class="checkout-data" *ngIf="selectedSeats.length > 0"> | |||||
| <p> <span> Total: </span> ₹ {{ getTotalAmount() }} </p> | |||||
| <button class="checkout-button"> Proceed to Payment </button> | |||||
| </section> | |||||
| </ion-content> | </ion-content> | ||||
| @@ -1,20 +1,24 @@ | |||||
| $dark-blue: #161e2d; | $dark-blue: #161e2d; | ||||
| $blue-grey: #949599; | $blue-grey: #949599; | ||||
| $sea-blue: #2ea9f5; | $sea-blue: #2ea9f5; | ||||
| $green: #01b868; | |||||
| ion-content { | ion-content { | ||||
| --background: transparent; | --background: transparent; | ||||
| background-color: $dark-blue; | background-color: $dark-blue; | ||||
| } | } | ||||
| .push-bottom { | |||||
| margin-bottom: 50px; | |||||
| } | |||||
| .action-buttons { | .action-buttons { | ||||
| display: flex; | display: flex; | ||||
| justify-content: space-between; | justify-content: space-between; | ||||
| align-items: flex-start; | align-items: flex-start; | ||||
| padding: 0 3% 0 0%; | padding: 0 3% 0 0%; | ||||
| height: 50px; | |||||
| position: sticky; | |||||
| position: -webkit-sticky; | |||||
| height: 70px; | |||||
| position: fixed; | |||||
| left: 0; | left: 0; | ||||
| top: 0; | top: 0; | ||||
| background-color: lighten($blue-grey, 35%); | background-color: lighten($blue-grey, 35%); | ||||
| @@ -39,7 +43,6 @@ ion-content { | |||||
| } | } | ||||
| span { | span { | ||||
| font-size: 0.9rem; | |||||
| font-size: 14px; | font-size: 14px; | ||||
| } | } | ||||
| } | } | ||||
| @@ -56,7 +59,7 @@ ion-content { | |||||
| text-overflow: ellipsis; | text-overflow: ellipsis; | ||||
| span { | span { | ||||
| font-weight: 400; | |||||
| font-weight: 500; | |||||
| color: $blue-grey; | color: $blue-grey; | ||||
| font-size: 12px; | font-size: 12px; | ||||
| } | } | ||||
| @@ -92,9 +95,10 @@ ion-content { | |||||
| position: sticky; | position: sticky; | ||||
| position: -webkit-sticky; | position: -webkit-sticky; | ||||
| left: 0; | left: 0; | ||||
| top: 50px; | |||||
| top: 70px; | |||||
| z-index: 0; | z-index: 0; | ||||
| overflow: hidden; | overflow: hidden; | ||||
| margin-bottom: 50px; | |||||
| .quadrants { | .quadrants { | ||||
| position: absolute; | position: absolute; | ||||
| @@ -274,7 +278,7 @@ ion-content { | |||||
| position: relative; | position: relative; | ||||
| background-color: white; | background-color: white; | ||||
| z-index: 1; | z-index: 1; | ||||
| padding: 5px 0% 10px 0%; | |||||
| padding: 5px 0% 15px 0%; | |||||
| border-top-left-radius: 7px; | border-top-left-radius: 7px; | ||||
| border-top-right-radius: 7px; | border-top-right-radius: 7px; | ||||
| overflow: hidden; | overflow: hidden; | ||||
| @@ -297,14 +301,25 @@ ion-content { | |||||
| .stand-list { | .stand-list { | ||||
| list-style: none; | list-style: none; | ||||
| padding: 0 5%; | |||||
| padding: 0; | |||||
| margin: 10px 0px 0px 0px; | margin: 10px 0px 0px 0px; | ||||
| li { | li { | ||||
| display: flex; | display: flex; | ||||
| align-items: center; | align-items: center; | ||||
| justify-content: flex-start; | justify-content: flex-start; | ||||
| padding: 10px 0; | |||||
| padding: 10px 15px; | |||||
| border-radius: 7px; | |||||
| width: 95%; | |||||
| margin: 0 auto; | |||||
| &.active { | |||||
| background-color: $dark-blue; | |||||
| p { | |||||
| color: white; | |||||
| } | |||||
| } | |||||
| } | } | ||||
| label { | label { | ||||
| @@ -320,7 +335,7 @@ ion-content { | |||||
| letter-spacing: 1px; | letter-spacing: 1px; | ||||
| background-color: $sea-blue; | background-color: $sea-blue; | ||||
| font-size: 0.8rem; | font-size: 0.8rem; | ||||
| margin-right: 20px; | |||||
| margin-right: 15px; | |||||
| } | } | ||||
| p { | p { | ||||
| @@ -328,5 +343,85 @@ ion-content { | |||||
| color: $blue-grey; | color: $blue-grey; | ||||
| line-height: 1.5; | line-height: 1.5; | ||||
| font-size: 1rem; | font-size: 1rem; | ||||
| width: calc(100% - 30px - 100px); | |||||
| } | |||||
| .count-action { | |||||
| width: 100px; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: space-between; | |||||
| background-color: rgba($blue-grey, 0.1); | |||||
| border-radius: 30px; | |||||
| padding: 5px; | |||||
| button { | |||||
| width: 25px; | |||||
| height: 25px; | |||||
| border-radius: 50%; | |||||
| font-size: 16px; | |||||
| border: 1px solid $blue-grey; | |||||
| background-color: rgba($blue-grey, 0.1); | |||||
| border-radius: 50%; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: center; | |||||
| color: $blue-grey; | |||||
| opacity: 0; | |||||
| pointer-events: none; | |||||
| transition: opacity 0.3s; | |||||
| &.active { | |||||
| pointer-events: all; | |||||
| opacity: 1; | |||||
| } | |||||
| } | |||||
| .count { | |||||
| color: white; | |||||
| font-weight: 700; | |||||
| font-size: 20px; | |||||
| } | |||||
| } | |||||
| } | |||||
| .checkout-data { | |||||
| position: fixed; | |||||
| left: 0; | |||||
| bottom: 0; | |||||
| z-index: 2; | |||||
| background-color: lighten($blue-grey, 35%); | |||||
| padding: 0 10px 0 5%; | |||||
| box-shadow: 0px 0px 10px $blue-grey; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: space-between; | |||||
| width: 100%; | |||||
| height: 60px; | |||||
| border-top-left-radius: 7px; | |||||
| border-top-right-radius: 7px; | |||||
| p { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: flex-start; | |||||
| font-size: 20px; | |||||
| font-weight: 400; | |||||
| color: darken($blue-grey, 20%); | |||||
| span { | |||||
| font-weight: 500; | |||||
| margin-right: 10px; | |||||
| } | |||||
| } | |||||
| button { | |||||
| background-color: $green; | |||||
| color: white; | |||||
| font-size: 14px; | |||||
| border-radius: 5px; | |||||
| height: 40px; | |||||
| padding: 0 10px; | |||||
| box-shadow: 0px 0px 5px $blue-grey; | |||||
| } | } | ||||
| } | } | ||||
| @@ -1,6 +1,7 @@ | |||||
| import { Component, OnInit } from '@angular/core'; | import { Component, OnInit } from '@angular/core'; | ||||
| import { ActivatedRoute } from '@angular/router'; | import { ActivatedRoute } from '@angular/router'; | ||||
| import { Location } from '@angular/common'; | import { Location } from '@angular/common'; | ||||
| import * as moment from 'moment'; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-booking-details', | selector: 'app-booking-details', | ||||
| @@ -9,7 +10,11 @@ import { Location } from '@angular/common'; | |||||
| }) | }) | ||||
| export class BookingDetailsPage implements OnInit { | export class BookingDetailsPage implements OnInit { | ||||
| matchDay: any; | matchDay: any; | ||||
| selectedStand: string = ''; | |||||
| selectedStand: number; | |||||
| selectedSeats: Array<{ | |||||
| id: string, | |||||
| price: string, | |||||
| }> = []; | |||||
| constructor( | constructor( | ||||
| private route: ActivatedRoute, | private route: ActivatedRoute, | ||||
| @@ -29,4 +34,31 @@ export class BookingDetailsPage implements OnInit { | |||||
| return text.charAt(0) | return text.charAt(0) | ||||
| } | } | ||||
| getEventDateTime(dateTime: Date) { | |||||
| return moment(dateTime).format('ddd, MMM DD YYYY hh:mm a'); | |||||
| } | |||||
| addSeat() { | |||||
| let seats: Array<any> = this.matchDay.seatsAvailable[this.selectedStand].seats; | |||||
| this.selectedSeats.push(seats.pop()); | |||||
| } | |||||
| removeSeat() { | |||||
| let seats: Array<any> = this.matchDay.seatsAvailable[this.selectedStand].seats; | |||||
| seats.push(this.selectedSeats.pop()); | |||||
| } | |||||
| getTotalAmount() { | |||||
| let total = 0; | |||||
| this.selectedSeats.forEach((seat) => { | |||||
| total += Number(seat.price) | |||||
| }); | |||||
| return total; | |||||
| } | |||||
| } | } | ||||
| @@ -114,7 +114,7 @@ export class BookingPage implements OnInit { | |||||
| let price = faker.commerce.price(); | let price = faker.commerce.price(); | ||||
| let randomNumber = Math.random() * (4 - 0) + 0; | |||||
| let randomNumber = Math.random() * (15 - 0) + 0; | |||||
| for (let k = 0; k < randomNumber; k += 1) { | for (let k = 0; k < randomNumber; k += 1) { | ||||
| this.bookingSeatsData[i].seatsAvailable[j].seats.push({ | this.bookingSeatsData[i].seatsAvailable[j].seats.push({ | ||||