| @@ -0,0 +1,17 @@ | |||
| import { NgModule } from '@angular/core'; | |||
| import { Routes, RouterModule } from '@angular/router'; | |||
| import { AddPartyPage } from './add-party.page'; | |||
| const routes: Routes = [ | |||
| { | |||
| path: '', | |||
| component: AddPartyPage | |||
| } | |||
| ]; | |||
| @NgModule({ | |||
| imports: [RouterModule.forChild(routes)], | |||
| exports: [RouterModule], | |||
| }) | |||
| export class AddPartyPageRoutingModule {} | |||
| @@ -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 { AddPartyPageRoutingModule } from './add-party-routing.module'; | |||
| import { AddPartyPage } from './add-party.page'; | |||
| @NgModule({ | |||
| imports: [ | |||
| CommonModule, | |||
| FormsModule, | |||
| IonicModule, | |||
| AddPartyPageRoutingModule | |||
| ], | |||
| declarations: [AddPartyPage] | |||
| }) | |||
| export class AddPartyPageModule {} | |||
| @@ -0,0 +1,39 @@ | |||
| <ion-content> | |||
| <section class="action-buttons"> | |||
| <div class="nav"> | |||
| <button (click)="back()"> | |||
| <ion-icon name="chevron-back-outline"></ion-icon> <span> BACK </span> | |||
| </button> | |||
| </div> | |||
| <header> | |||
| Create Party <br> | |||
| <span> Send invitation to contacts </span> <br> | |||
| <span> {{ selectedContacts.length }} contact(s) selected </span> | |||
| </header> | |||
| </section> | |||
| <ion-searchbar showCancelButton="never" mode="ios" | |||
| [(ngModel)]="searchInput" (ionChange)="searchContact()" | |||
| placeholder="Search by name or number"></ion-searchbar> | |||
| <ion-list mode="ios"> | |||
| <ion-item *ngFor="let contact of contactList"> | |||
| <ion-label> | |||
| <h2> {{ contact.name }} </h2> | |||
| <p> {{ contact.phone }} </p> | |||
| </ion-label> | |||
| <ion-button slot="end" fill="outline" [ngClass]="{'active' : selectedContacts.includes(contact.phone) }" | |||
| (click)="selectContact(contact.phone)"> | |||
| <ion-icon name="add"></ion-icon> | |||
| <ion-icon name="checkmark"></ion-icon> | |||
| </ion-button> | |||
| </ion-item> | |||
| </ion-list> | |||
| <ion-button size="block" class="confirm-button" (click)="createParty()" *ngIf="selectedContacts.length > 0"> | |||
| Create Party | |||
| </ion-button> | |||
| </ion-content> | |||
| @@ -0,0 +1,124 @@ | |||
| $dark-blue: #161e2d; | |||
| $blue-grey: #949599; | |||
| $green: #01b868; | |||
| $pink: #d73e53; | |||
| $dark-blue-shade1: #24367c; | |||
| $dark-blue-shade2: #263982; | |||
| ion-content { | |||
| --background: white; | |||
| } | |||
| .action-buttons { | |||
| display: flex; | |||
| justify-content: space-between; | |||
| align-items: flex-start; | |||
| padding: 0 3% 0 0%; | |||
| height: 70px; | |||
| position: 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; | |||
| ion-icon { | |||
| font-size: 24px; | |||
| } | |||
| span { | |||
| margin-left: 5px; | |||
| font-size: 0.9rem; | |||
| font-size: 14px; | |||
| } | |||
| } | |||
| header { | |||
| flex-grow: 1; | |||
| padding: 0 10px; | |||
| font-size: 16px; | |||
| color: darken($blue-grey, 30%); | |||
| font-weight: 500; | |||
| text-align: left; | |||
| white-space: nowrap; | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| span { | |||
| font-weight: 500; | |||
| color: $blue-grey; | |||
| font-size: 12px; | |||
| } | |||
| } | |||
| } | |||
| ion-searchbar { | |||
| margin: 10px 0; | |||
| } | |||
| ion-list { | |||
| margin-bottom: 60px; | |||
| ion-item { | |||
| --padding-start: 5%; | |||
| --padding-end: 5%; | |||
| } | |||
| ion-button { | |||
| margin: 0; | |||
| --border-width: 2px; | |||
| --border-radius: 5px; | |||
| width: 40px; | |||
| height: 40px; | |||
| transform: scale(0.9); | |||
| &.active { | |||
| --background: #01b868; | |||
| --color: white; | |||
| --border-color: #00ad62; | |||
| ion-icon { | |||
| font-size: 30px; | |||
| &:nth-child(2) { | |||
| display: block; | |||
| } | |||
| &:nth-child(1) { | |||
| display: none; | |||
| } | |||
| } | |||
| } | |||
| ion-icon { | |||
| font-size: 20px; | |||
| &:nth-child(2) { | |||
| display: none; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| .confirm-button { | |||
| position: fixed; | |||
| bottom: 0; | |||
| left: 0; | |||
| --color: white; | |||
| margin: 0; | |||
| width: 100%; | |||
| height: 50px; | |||
| --background: #01b868; | |||
| } | |||
| @@ -0,0 +1,24 @@ | |||
| import { async, ComponentFixture, TestBed } from '@angular/core/testing'; | |||
| import { IonicModule } from '@ionic/angular'; | |||
| import { AddPartyPage } from './add-party.page'; | |||
| describe('AddPartyPage', () => { | |||
| let component: AddPartyPage; | |||
| let fixture: ComponentFixture<AddPartyPage>; | |||
| beforeEach(async(() => { | |||
| TestBed.configureTestingModule({ | |||
| declarations: [ AddPartyPage ], | |||
| imports: [IonicModule.forRoot()] | |||
| }).compileComponents(); | |||
| fixture = TestBed.createComponent(AddPartyPage); | |||
| component = fixture.componentInstance; | |||
| fixture.detectChanges(); | |||
| })); | |||
| it('should create', () => { | |||
| expect(component).toBeTruthy(); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,70 @@ | |||
| import { Component, OnInit } from '@angular/core'; | |||
| import * as faker from 'faker'; | |||
| import { ModalController } from '@ionic/angular'; | |||
| @Component({ | |||
| selector: 'app-add-party', | |||
| templateUrl: './add-party.page.html', | |||
| styleUrls: ['./add-party.page.scss'], | |||
| }) | |||
| export class AddPartyPage implements OnInit { | |||
| contactList: Array<{ | |||
| name: string, | |||
| phone: string | |||
| }> = []; | |||
| tempContactList: Array<{ | |||
| name: string, | |||
| phone: string | |||
| }> = []; | |||
| searchInput: string = ''; | |||
| selectedContacts: Array<string> = []; | |||
| constructor( | |||
| private modalController: ModalController | |||
| ) { } | |||
| back() { | |||
| this.modalController.dismiss({ | |||
| createParty: false | |||
| }); | |||
| } | |||
| createParty() { | |||
| this.modalController.dismiss({ | |||
| createParty: true | |||
| }); | |||
| } | |||
| ngOnInit() { | |||
| for (let i = 0; i < 12; i += 1) { | |||
| this.contactList.push({ | |||
| name: faker.name.findName(), | |||
| phone: faker.phone.phoneNumber() | |||
| }); | |||
| } | |||
| this.tempContactList = JSON.parse(JSON.stringify(this.contactList)); | |||
| } | |||
| searchContact() { | |||
| this.contactList = this.tempContactList.filter((contact) => { | |||
| return contact.phone.toString().toLowerCase().includes(this.searchInput.toLowerCase().trim()) || | |||
| contact.name.toString().toLowerCase().includes(this.searchInput.toLowerCase().trim()); | |||
| }); | |||
| } | |||
| selectContact(phone: string) { | |||
| if (this.selectedContacts.includes(phone)) { | |||
| this.selectedContacts.splice(this.selectedContacts.indexOf(phone), 1); | |||
| } else { | |||
| this.selectedContacts.push(phone); | |||
| } | |||
| } | |||
| } | |||
| @@ -45,6 +45,10 @@ const routes: Routes = [ | |||
| { | |||
| path: 'collections', | |||
| loadChildren: () => import('./collections/collections.module').then( m => m.CollectionsPageModule) | |||
| }, | |||
| { | |||
| path: 'add-party', | |||
| loadChildren: () => import('./add-party/add-party.module').then( m => m.AddPartyPageModule) | |||
| } | |||
| ]; | |||
| @NgModule({ | |||
| @@ -22,6 +22,9 @@ export class AppComponent { | |||
| this.platform.ready().then(() => { | |||
| this.statusBar.styleDefault(); | |||
| this.splashScreen.hide(); | |||
| localStorage.isPartyChatOn = 'no'; | |||
| }); | |||
| } | |||
| } | |||
| @@ -5,7 +5,7 @@ | |||
| </div> | |||
| <div class="action"> | |||
| <button class="toggle" (click)="isPollChecked = !isPollChecked"> <ion-checkbox [(ngModel)]="isPollChecked"></ion-checkbox> Poll </button> | |||
| <button> <ion-icon name="link-outline"></ion-icon> </button> | |||
| <button (click)="copyLink()"> <ion-icon name="link-outline"></ion-icon> </button> | |||
| </div> | |||
| </section> | |||
| @@ -1,6 +1,8 @@ | |||
| import { Component, OnInit } from '@angular/core'; | |||
| import { ModalController } from '@ionic/angular'; | |||
| import * as faker from 'faker'; | |||
| import { ToastController } from '@ionic/angular'; | |||
| type IMember = { | |||
| name: string, | |||
| @@ -41,13 +43,30 @@ export class ChatPage implements OnInit { | |||
| myAccount: IMember; | |||
| constructor( | |||
| private modalController: ModalController | |||
| private modalController: ModalController, | |||
| public toastController: ToastController | |||
| ) { } | |||
| back() { | |||
| this.modalController.dismiss(); | |||
| } | |||
| async copyLink() { | |||
| const toast = await this.toastController.create({ | |||
| message: 'Copied invitation link!', | |||
| color: 'medium', | |||
| mode: 'md', | |||
| duration: 100000, | |||
| position: 'top', | |||
| buttons: [{ | |||
| text: 'Ok', | |||
| role: 'cancel', | |||
| }], | |||
| }); | |||
| toast.present(); | |||
| } | |||
| ngOnInit() { | |||
| let myAccountIndex = Math.floor(Math.random() * 11); | |||
| @@ -132,7 +151,7 @@ export class ChatPage implements OnInit { | |||
| setTimeout(() => { | |||
| this.scrollToEnd(); | |||
| }, 300); | |||
| }, 1000); | |||
| }, 200); | |||
| @@ -175,7 +194,6 @@ export class ChatPage implements OnInit { | |||
| this.scrollToEnd(); | |||
| this.myMessage = ''; | |||
| }, 100); | |||
| }, 1000); | |||
| } | |||
| } | |||
| @@ -131,10 +131,16 @@ | |||
| </div> | |||
| <ion-fab vertical="bottom" horizontal="end" slot="fixed"> | |||
| <ion-fab vertical="bottom" horizontal="end" slot="fixed" *ngIf="!showAddParty"> | |||
| <ion-fab-button class="chat-button" (click)="presentChatModal()"> | |||
| <ion-icon name="chatbubble-ellipses-outline"></ion-icon> | |||
| </ion-fab-button> | |||
| </ion-fab> | |||
| <ion-fab vertical="bottom" horizontal="end" slot="fixed" *ngIf="showAddParty"> | |||
| <ion-fab-button class="chat-button" (click)="presentAddChatModal()"> | |||
| <ion-icon name="add-outline"></ion-icon> | |||
| </ion-fab-button> | |||
| </ion-fab> | |||
| </ion-content> | |||
| @@ -4,6 +4,7 @@ import * as moment from 'moment'; | |||
| import { ChatPage } from '../chat/chat.page'; | |||
| import * as faker from 'faker'; | |||
| import { Router } from '@angular/router'; | |||
| import { AddPartyPage } from '../add-party/add-party.page'; | |||
| export type IscoreCard = { | |||
| teamName: string, | |||
| @@ -110,6 +111,8 @@ export class LivePage implements OnInit { | |||
| }> | |||
| }> = []; | |||
| showAddParty: boolean = false; | |||
| constructor( | |||
| public modalController: ModalController, | |||
| private router: Router | |||
| @@ -272,16 +275,35 @@ export class LivePage implements OnInit { | |||
| totalWickets: 1, | |||
| } | |||
| } | |||
| if (localStorage.isPartyChatOn = 'no') { | |||
| this.showAddParty = true; | |||
| } | |||
| } | |||
| async presentChatModal() { | |||
| const modal = await this.modalController.create({ | |||
| component: ChatPage, | |||
| cssClass: 'my-custom-class' | |||
| }); | |||
| return await modal.present(); | |||
| } | |||
| async presentAddChatModal() { | |||
| const modal = await this.modalController.create({ | |||
| component: AddPartyPage, | |||
| }); | |||
| modal.onDidDismiss().then((data) => { | |||
| if(data.data.createParty) { | |||
| this.showAddParty = false; | |||
| } | |||
| }); | |||
| return await modal.present(); | |||
| } | |||
| showBookingDetails(matchData) { | |||
| this.router.navigate(['/booking-details' , { matchData: JSON.stringify(matchData) }]); | |||
| } | |||