Browse Source

Booking details page stands UI

master
kj1352 4 years ago
parent
commit
2ee581bfe0
10 changed files with 494 additions and 79 deletions
  1. +4
    -0
      src/app/app-routing.module.ts
  2. +17
    -0
      src/app/booking-details/booking-details-routing.module.ts
  3. +20
    -0
      src/app/booking-details/booking-details.module.ts
  4. +53
    -0
      src/app/booking-details/booking-details.page.html
  5. +330
    -0
      src/app/booking-details/booking-details.page.scss
  6. +24
    -0
      src/app/booking-details/booking-details.page.spec.ts
  7. +32
    -0
      src/app/booking-details/booking-details.page.ts
  8. +2
    -1
      src/app/booking/booking.page.html
  9. +1
    -76
      src/app/booking/booking.page.scss
  10. +11
    -2
      src/app/booking/booking.page.ts

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

@@ -29,6 +29,10 @@ const routes: Routes = [
{
path: 'booking',
loadChildren: () => import('./booking/booking.module').then( m => m.BookingPageModule)
},
{
path: 'booking-details',
loadChildren: () => import('./booking-details/booking-details.module').then( m => m.BookingDetailsPageModule)
}
];
@NgModule({


+ 17
- 0
src/app/booking-details/booking-details-routing.module.ts View File

@@ -0,0 +1,17 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { BookingDetailsPage } from './booking-details.page';

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

@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class BookingDetailsPageRoutingModule {}

+ 20
- 0
src/app/booking-details/booking-details.module.ts View File

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

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

import { BookingDetailsPageRoutingModule } from './booking-details-routing.module';

import { BookingDetailsPage } from './booking-details.page';

@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
BookingDetailsPageRoutingModule
],
declarations: [BookingDetailsPage]
})
export class BookingDetailsPageModule {}

+ 53
- 0
src/app/booking-details/booking-details.page.html View File

@@ -0,0 +1,53 @@
<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="upfold">
<img class="bg-img" [src]="matchDay.staduim.sideView">

<ul class="quadrants">
<li *ngFor="let stands of matchDay.seatsAvailable"
[ngClass]="{'active' : selectedStand === stands.stand}"
(click)="selectedStand = stands.stand">
<label> {{ stands.stand }} Stand </label>
</li>
</ul>

<figure class="active">
<img src="assets/home-team/stadium-sv.svg">
<img [src]="matchDay.staduim.topView">
</figure>

</section>

<section class="seating-details">
<header>
<h3> Stands </h3>
</header>

<ul class="stand-list">
<li *ngFor="let stands of matchDay.seatsAvailable"
[ngClass]="{'active' : selectedStand === stands.stand}"
(click)="selectedStand = stands.stand">
<label>
{{ getFirstChar(stands.stand) }}
</label>
<p>
{{ stands.seats.length }} seats remaining, starts from <strong> &#8377; {{ stands.seats[0].price }} </strong>
</p>
</li>
</ul>
</section>

</div>

</ion-content>

+ 330
- 0
src/app/booking-details/booking-details.page.scss View File

@@ -0,0 +1,330 @@
$dark-blue: #161e2d;
$blue-grey: #949599;
$sea-blue: #2ea9f5;

ion-content {
--background: transparent;
background-color: $dark-blue;
}

.action-buttons {
display: flex;
justify-content: space-between;
align-items: flex-start;
padding: 0 3% 0 0%;
height: 50px;
position: sticky;
position: -webkit-sticky;
left: 0;
top: 0;
background-color: lighten($blue-grey, 35%);
z-index: 2;
width: 100%;
align-items: center;
box-shadow: 0px 0px 5px $dark-blue;
button {
background-color: transparent;
border: none;
}
.nav button {
color: $blue-grey;
display: flex;
align-items: center;
justify-content: flex-start;

ion-icon {
font-size: 24px;
}
span {
font-size: 0.9rem;
font-size: 14px;
}
}

header {
flex-grow: 1;
padding: 0 10px;
font-size: 14px;
color: darken($blue-grey, 30%);
font-weight: 500;
text-align: left;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;

span {
font-weight: 400;
color: $blue-grey;
font-size: 10px;
}
}

.action {
display: flex;
justify-content: flex-end;
}

.action button {
width: 35px;
height: 35px;
border: 1px solid $blue-grey;
background-color: rgba($blue-grey, 0.1);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-left: 15px;

ion-icon {
color: $blue-grey;
font-size: 17px;
}
}

}

.upfold {
height: 100vw;
width: 100vw;
position: sticky;
position: -webkit-sticky;
left: 0;
top: 50px;
z-index: 0;
overflow: hidden;

.quadrants {
position: absolute;
z-index: 2;
left: 0;
top: 0;
display: flex;
justify-content: center;
width: 100%;
height: 100%;
padding: 0;
margin: 0;
list-style: none;
flex-wrap: wrap;
border-radius: 50%;
overflow: hidden;
transform: scale(0);
animation: popOut 0.3s forwards;
animation-delay: 1s;

li {
width: 50%;
height: 50%;
background-color: rgba($dark-blue, 0.2);
display: flex;
justify-content: center;
color: white;
font-weight: 700;
letter-spacing: 0.5px;
padding: 30px;
transition: background-color 0.3s, color 0.3s;

&:nth-child(1n + 1) {
justify-content: flex-end;
}

&:nth-child(2n) {
justify-content: flex-start;
}

&:nth-child(1) {
border-right: 1px solid white;
align-items: flex-end;
}

&:nth-child(2) {
align-items: flex-end;
}

&:nth-child(3) {
border-right: 1px solid white;
border-top: 1px solid white;
}

&:nth-child(4) {
border-top: 1px solid white;
}

&.active {
background-color: rgba($dark-blue, 0.9);
}
}
}
@keyframes popOut {
from {
transform: scale(0);
} to {
transform: scale(1);
}
}

.bg-img {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
object-fit: cover;
object-position: center;
filter: brightness(50%);
opacity: 0;
z-index: 0;
animation: fadeInSlow 3s forwards;
animation-delay: 1s;
}

@keyframes fadeInSlow {
from {
opacity: 0;
} to {
opacity: 1;
}
}

figure {
position: relative;
margin: 0;
display: block;
width: 100%;
height: 100%;
transition: filter 0.3s;
border: 0px;
padding: 0;
border-radius: 7px;
overflow: hidden;
z-index: 1;
-webkit-perspective: 1200px;
-moz-perspective: 1200px;
-ms-perspective: 1200px;
perspective: 1200px;

&.active {
img {
&:nth-child(1) {
animation: sideViewOut 0.3s forwards;
animation-delay: 0.5s;
}

&:nth-child(2) {
animation: topViewIn 0.3s forwards;
animation-delay: 0.5s;
}
}
}

img {
height: 90%;
object-fit: contain;
display: block;
width: 90%;
margin: 0 auto;
position: absolute;
left: 5%;
top: 5%;

-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-ms-transform-style: preserve-3d;
transform-style: preserve-3d;
transform-origin: 50px 0;

&:nth-child(2) {
transform: translateY(50%)rotateX(90deg);
opacity: 0;
}
}
}

@keyframes sideViewOut {
0% {
transform: translateY(0%)rotateX(0deg);
}
100% {
transform: translateY(50%)rotateX(-90deg);
width: 80%;
height: 50%;
opacity: 0;
}
}

@keyframes topViewIn {
0% {
transform: translateY(50%)rotateX(90deg);
opacity: 0;
}
100% {
transform: translateY(0%)rotateX(0deg);
opacity: 1;
}
}
}

.seating-details {
position: relative;
background-color: white;
z-index: 1;
padding: 5px 5% 10px 5%;
border-top-left-radius: 7px;
border-top-right-radius: 7px;
overflow: hidden;
min-height: calc(100vh - 100vw - 50px);
header h3 {
margin: 0;
color: lighten($dark-blue, 10%);
font-weight: 700;
letter-spacing: 1px;
font-size: 1.1rem;
}

header {
padding: 10px 0;
border-bottom: 1px solid $blue-grey;
}
}

.stand-list {
list-style: none;
padding: 0;
margin: 10px 0px 0px 0px;

li {
display: flex;
align-items: center;
justify-content: flex-start;
padding: 10px 0;
}

label {
display: flex;
align-items: center;
justify-content: center;
border-radius: 7px;
width: 30px;
height: 30px;
overflow: hidden;
color: white;
font-weight: 500;
letter-spacing: 1px;
background-color: $sea-blue;
font-size: 0.8rem;
margin-right: 10px;
}

p {
margin: 0;
color: $blue-grey;
line-height: 1.5;
font-size: 1rem;
}
}

+ 24
- 0
src/app/booking-details/booking-details.page.spec.ts View File

@@ -0,0 +1,24 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';

import { BookingDetailsPage } from './booking-details.page';

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

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ BookingDetailsPage ],
imports: [IonicModule.forRoot()]
}).compileComponents();

fixture = TestBed.createComponent(BookingDetailsPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));

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

+ 32
- 0
src/app/booking-details/booking-details.page.ts View File

@@ -0,0 +1,32 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Location } from '@angular/common';

@Component({
selector: 'app-booking-details',
templateUrl: './booking-details.page.html',
styleUrls: ['./booking-details.page.scss'],
})
export class BookingDetailsPage implements OnInit {
matchDay: any;
selectedStand: string = '';

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

ngOnInit() {
this.matchDay = JSON.parse(this.route.snapshot.paramMap.get('matchData'));
console.log(this.matchDay);
}

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

getFirstChar(text: string) {
return text.charAt(0)
}

}

+ 2
- 1
src/app/booking/booking.page.html View File

@@ -14,7 +14,8 @@


<ion-slides #slides [options]="slideOpts" (ionSlideDidChange)="selectMatchDate()">
<ion-slide *ngFor="let matchDay of bookingSeatsData">
<ion-slide *ngFor="let matchDay of bookingSeatsData"
(click)="showBookingDetails(matchDay)">
<div class="image-holder">
<figure>
<img [src]="matchDay.staduim.sideView">


+ 1
- 76
src/app/booking/booking.page.scss View File

@@ -170,79 +170,4 @@ ion-slides {
font-size: 0.9rem;
line-height: 1.5;
}
}

// figure {
// margin: 0;
// display: block;
// width: 100%;
// height: 100%;
// transition: filter 0.3s;
// border: 0px;
// padding: 0;
// border-radius: 7px;
// overflow: hidden;
// -webkit-perspective: 1200px;
// -moz-perspective: 1200px;
// -ms-perspective: 1200px;
// perspective: 1200px;

// &.active {
// img {
// &:nth-child(1) {
// animation: sideViewOut 0.3s forwards;
// }

// &:nth-child(2) {
// animation: topViewIn 0.3s forwards;
// animation-delay: 0.1s;
// }
// }
// }

// img {
// height: 80%;
// object-fit: contain;
// display: block;
// width: 80%;
// margin: 0 auto;
// position: absolute;
// left: 10%;
// top: 0;

// -webkit-transform-style: preserve-3d;
// -moz-transform-style: preserve-3d;
// -ms-transform-style: preserve-3d;
// transform-style: preserve-3d;
// transform-origin: 50px 0;

// &:nth-child(2) {
// transform: translateY(50%)rotateX(90deg);
// opacity: 0;
// }
// }
// }

// @keyframes sideViewOut {
// 0% {
// transform: translateY(0%)rotateX(0deg);
// }
// 100% {
// transform: translateY(50%)rotateX(-90deg);
// width: 80%;
// height: 50%;
// opacity: 0;
// }
// }

// @keyframes topViewIn {
// 0% {
// transform: translateY(50%)rotateX(90deg);
// opacity: 0;
// }
// 100% {
// transform: translateY(0%)rotateX(0deg);
// opacity: 1;
// }
// }
}

+ 11
- 2
src/app/booking/booking.page.ts View File

@@ -2,6 +2,7 @@ import { Component, OnInit, ViewChild } from '@angular/core';
import { IonSlides } from '@ionic/angular';
import * as faker from 'faker';
import * as moment from 'moment';
import { Router } from '@angular/router';

@Component({
selector: 'app-booking',
@@ -74,7 +75,9 @@ export class BookingPage implements OnInit {
}>
}> = [];

constructor() { }
constructor(
private router: Router
) { }

getFormattedDateTime(dateTime: Date) {
return moment(dateTime).format('DD MMM');
@@ -111,7 +114,9 @@ export class BookingPage implements OnInit {

let price = faker.commerce.price();

for (let k = 0; k < 5; k += 1) {
let randomNumber = Math.random() * (4 - 0) + 0;

for (let k = 0; k < randomNumber; k += 1) {
this.bookingSeatsData[i].seatsAvailable[j].seats.push({
id: this.bookingSeatsData[i].seatsAvailable[j].stand + '##' + k.toString(),
price
@@ -140,4 +145,8 @@ export class BookingPage implements OnInit {
this.slides.slideTo(index);
}

showBookingDetails(matchData) {
this.router.navigate(['/booking-details' , { matchData: JSON.stringify(matchData) }]);
}

}

Loading…
Cancel
Save