Skip to content

Commit bdd0ea6

Browse files
committed
Added initial 3rd Pane for #111
1 parent d0fd877 commit bdd0ea6

13 files changed

+298
-115
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -197,4 +197,4 @@
197197
"browser"
198198
]
199199
}
200-
}
200+
}

src/app/app.component.ts

+85-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Component, Injector, ViewChild, NgZone } from '@angular/core';
2-
import { Platform, Events, Nav, SplitPane, NavController, ModalController, Loading, LoadingController, Toast, ToastController, Alert, AlertController, MenuController } from 'ionic-angular';
2+
import { Platform, Events, Nav, SplitPane, NavController, ModalController, Modal, Loading, LoadingController, Toast, ToastController, Alert, AlertController, MenuController } from 'ionic-angular';
33

44
import { Badge } from '@ionic-native/badge';
55
import { Device } from '@ionic-native/device';
@@ -19,7 +19,10 @@ import { SignupPasswordPage } from '../pages/signup-password/signup-password';
1919
import { SignupOwnerPage } from '../pages/signup-owner/signup-owner';
2020

2121
import { OnboardListPage } from '../pages/onboard-list/onboard-list';
22+
2223
import { CheckinListPage } from '../pages/checkin-list/checkin-list';
24+
import { CheckinRespondPage } from '../pages/checkin-respond/checkin-respond';
25+
2326
import { GroupListPage } from '../pages/group-list/group-list';
2427
import { PersonListPage } from '../pages/person-list/person-list';
2528
import { PersonDetailsPage } from '../pages/person-details/person-details';
@@ -64,6 +67,8 @@ export class TenFourApp {
6467
browser:boolean = false;
6568
desktop:boolean = false;
6669

70+
checkin:Checkin = null;
71+
6772
@ViewChild(Nav)
6873
nav:Nav;
6974

@@ -241,6 +246,9 @@ export class TenFourApp {
241246
this.events.subscribe('user:login', () => {
242247
this.loadMenu();
243248
});
249+
this.events.subscribe('checkin:details', (data:any) => {
250+
this.showCheckinDetails(data.checkin);
251+
});
244252
resolve(true);
245253
})
246254
}
@@ -620,6 +628,12 @@ export class TenFourApp {
620628
return toast;
621629
}
622630

631+
protected showModal(page:any, params:any={}, options:any={}):Modal {
632+
let modal = this.modalController.create(page, params, options);
633+
modal.present();
634+
return modal;
635+
}
636+
623637
private trackEvent(event:string, properties:any=null) {
624638
return this.segment.track(event, properties).then(() => {
625639
this.logger.info(this, "Segment", "trackEvent", event);
@@ -662,4 +676,74 @@ export class TenFourApp {
662676
}
663677
}
664678

679+
680+
private showCheckinDetails(checkin:Checkin) {
681+
this.logger.info(this, "showCheckinDetails", checkin);
682+
this.zone.run(() => {
683+
this.checkin = checkin;
684+
});
685+
}
686+
687+
private hideCheckin() {
688+
this.zone.run(() => {
689+
this.checkin = null;
690+
});
691+
}
692+
693+
private editReply(reply:Reply, event:any) {
694+
this.logger.info(this, "editReply");
695+
if (reply.user_id == this.person.id) {
696+
let modal = this.showModal(CheckinRespondPage, {
697+
organization: this.organization,
698+
checkins: [this.checkin],
699+
checkin: this.checkin,
700+
reply: reply
701+
});
702+
modal.onDidDismiss(data => {
703+
this.logger.info(this, "editReply", "Modal", data);
704+
if (data) {
705+
if (data.canceled) {
706+
this.logger.info(this, "editReply", "Modal", "Canceled");
707+
}
708+
else {
709+
// TODO refresh the checkin list
710+
}
711+
}
712+
});
713+
}
714+
}
715+
716+
private respondCheckin(event:any) {
717+
this.logger.info(this, "sendReply");
718+
let modal = this.showModal(CheckinRespondPage, {
719+
organization: this.organization,
720+
checkins: [this.checkin],
721+
checkin: this.checkin
722+
});
723+
modal.onDidDismiss(data => {
724+
this.logger.info(this, "sendReply", "Modal", data);
725+
if (data) {
726+
if (data.canceled) {
727+
this.logger.info(this, "sendReply", "Modal", "Canceled");
728+
}
729+
else {
730+
// TODO refresh the checkin list
731+
}
732+
}
733+
});
734+
}
735+
736+
private resendCheckin(event:any) {
737+
this.logger.info(this, "resendCheckin");
738+
let loading = this.showLoading("Resending...");
739+
this.api.resendCheckin(this.organization, this.checkin).then((checkin:Checkin) => {
740+
loading.dismiss();
741+
this.showToast(`Check-In ${this.checkin.message} resent`);
742+
},
743+
(error:any) => {
744+
loading.dismiss();
745+
this.showAlert("Problem Resending Check-In", error);
746+
});
747+
}
748+
665749
}

src/app/app.html

+17
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,22 @@
2121
</p>
2222
</ion-content>
2323
</ion-menu>
24+
<ion-menu #details [content]="content" side="right" type="reveal" swipeEnabled="false" *ngIf="checkin">
25+
<ion-header>
26+
<ion-toolbar color="navbar">
27+
<ion-buttons left>
28+
<button ion-button icon-only color="primary" (click)="hideCheckin()">
29+
<ion-icon ios="ios-close" md="md-close"></ion-icon>
30+
</button>
31+
</ion-buttons>
32+
<ion-title>Check-In</ion-title>
33+
</ion-toolbar>
34+
</ion-header>
35+
<ion-content>
36+
<checkin-details [checkin]="checkin" [person]="person"
37+
[canSend]="checkin.canRespond(person)" [canResend]="checkin.canResend(person)"
38+
(sendClicked)="respondCheckin($event)" (resendClicked)="resendCheckin($event)" *ngIf="checkin"></checkin-details>
39+
</ion-content>
40+
</ion-menu>
2441
<ion-nav main #content #rootNavController swipeBackEnabled="false" [root]="rootPage"></ion-nav>
2542
</ion-split-pane>

src/app/app.module.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ import { SendViaModule } from '../components/send-via/send-via.module';
9494
import { ColorPickerModule } from '../components/color-picker/color-picker.module';
9595
import { PersonAvatarModule } from '../components/person-avatar/person-avatar.module';
9696
import { CheckinCardModule } from '../components/checkin-card/checkin-card.module';
97+
import { CheckinDetailModule } from '../components/checkin-details/checkin-details.module';
9798
import { PersonRowModule } from '../components/person-row/person-row.module';
9899
import { GroupRowModule } from '../components/group-row/group-row.module';
99100

@@ -118,6 +119,7 @@ import { CameraProvider } from '../providers/camera/camera';
118119
ColorPickerModule,
119120
SendViaModule,
120121
CheckinCardModule,
122+
CheckinDetailModule,
121123
PersonRowModule,
122124
GroupRowModule,
123125
GroupListModule,
@@ -198,7 +200,6 @@ import { CameraProvider } from '../providers/camera/camera';
198200
{ provide: Contacts, useClass: Contacts },
199201
{ provide: Badge, useClass: Badge },
200202
{ provide: Sim, useClass: Sim },
201-
// { provide: Http, useClass: Http },
202203
{ provide: HTTP, useClass: HTTP },
203204
{ provide: Firebase, useClass: Firebase },
204205
{ provide: ApiProvider, useClass: ApiProvider },
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<ion-list>
2+
<ion-item text-wrap text-center color="white">
3+
<person-avatar [initials]="checkin.user_initials" [image]="checkin.user_picture" [large]="true"></person-avatar>
4+
<h1>{{checkin.message}}</h1>
5+
<p>{{checkin.created_at | dateTime}}. <strong>From {{checkin.user_name}}.</strong></p>
6+
<ion-badge [style.background]="answer.color" [style.color]="white" *ngFor="let answer of checkin.answers">{{answer.replies}}</ion-badge>
7+
<ion-badge color="waiting" *ngIf="checkin.waiting_count > 0">{{checkin.waiting_count}}</ion-badge>
8+
</ion-item>
9+
<ion-item text-wrap color="white">
10+
<button ion-button text-only item-left clear color="primary" tappable *ngIf="hasSendClicked && checkin.canRespond(person)" (click)="onSendClicked($event)">Respond</button>
11+
<button ion-button text-only item-right clear color="primary" tappable *ngIf="hasResendClicked && checkin.canResend(person)" (click)="onResendClicked($event)">Resend</button>
12+
</ion-item>
13+
</ion-list>
14+
<ion-list *ngFor="let answer of checkin.answers">
15+
<ion-list-header *ngIf="answer.replies > 0">{{answer.answer}}</ion-list-header>
16+
<ion-item color="white" [attr.detail-push]="reply.user_id == person.id ? 'true' : null" [attr.tappable]="reply.user_id == person.id ? 'true' : null" (click)="editReply(reply, $event)" *ngFor="let reply of checkin.answerReplies(answer)">
17+
<person-avatar item-left [color]="answer.color" [initials]="reply.user_initials" [image]="reply.user_picture" [large]="false"></person-avatar>
18+
<ion-grid no-padding>
19+
<ion-row no-padding>
20+
<ion-col col-7 text-left no-padding>
21+
<h2>{{reply.user_name}}</h2>
22+
</ion-col>
23+
<ion-col col-5 text-right no-padding>
24+
<small>{{reply.created_at | dateTime}}</small>
25+
</ion-col>
26+
</ion-row>
27+
<ion-row no-padding *ngIf="reply.message">
28+
<ion-col text-left no-padding>
29+
<p text-wrap>{{reply.message}}</p>
30+
</ion-col>
31+
</ion-row>
32+
<ion-row no-padding *ngIf="reply.location_text">
33+
<ion-col text-left no-padding>
34+
<p text-wrap>
35+
<ion-icon ios="ios-pin-outline" md="md-pin"></ion-icon>
36+
{{reply.location_text}}
37+
</p>
38+
</ion-col>
39+
</ion-row>
40+
</ion-grid>
41+
</ion-item>
42+
</ion-list>
43+
<ion-list *ngIf="checkin.replies.length < checkin.recipients.length">
44+
<ion-list-header>No Response</ion-list-header>
45+
<ion-item color="white" *ngFor="let recipient of checkin.recipientsPending()">
46+
<person-avatar item-left [initials]="recipient.initials" [image]="recipient.profile_picture" [large]="false"></person-avatar>
47+
<ion-grid no-padding>
48+
<ion-row no-padding>
49+
<ion-col text-left no-padding>
50+
<h2>{{recipient.name}}</h2>
51+
</ion-col>
52+
</ion-row>
53+
<ion-row no-padding>
54+
<ion-col text-left no-padding>
55+
<p text-wrap>{{recipient.response_status}}</p>
56+
</ion-col>
57+
</ion-row>
58+
</ion-grid>
59+
</ion-item>
60+
</ion-list>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { NgModule } from '@angular/core';
2+
import { IonicPageModule } from 'ionic-angular';
3+
4+
import { CheckinDetailsComponent } from './checkin-details';
5+
6+
import { DateTimeModule } from '../../pipes/date-time/date-time.module';
7+
import { PersonAvatarModule } from '../../components/person-avatar/person-avatar.module';
8+
9+
@NgModule({
10+
declarations: [
11+
CheckinDetailsComponent,
12+
],
13+
imports: [
14+
DateTimeModule,
15+
PersonAvatarModule,
16+
IonicPageModule.forChild(CheckinDetailsComponent),
17+
],
18+
exports: [
19+
CheckinDetailsComponent
20+
]
21+
})
22+
export class CheckinDetailModule {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
checkin-details {
2+
ion-list {
3+
ion-item {
4+
ion-button, button {
5+
font-size: 16px !important;
6+
font-weight: 500 !important;
7+
}
8+
h1 {
9+
10+
}
11+
h2 {
12+
font-weight: 500 !important;
13+
white-space: nowrap;
14+
overflow: hidden;
15+
text-overflow: ellipsis;
16+
}
17+
small {
18+
display: block;
19+
color: #888888 !important;
20+
white-space: nowrap;
21+
overflow: hidden;
22+
text-overflow: ellipsis;
23+
}
24+
p {
25+
padding-top: 4px;
26+
color: #888888 !important;
27+
white-space: nowrap;
28+
overflow: hidden;
29+
text-overflow: ellipsis;
30+
strong {
31+
color: #444444 !important;
32+
font-weight: 500 !important;
33+
}
34+
}
35+
ion-badge {
36+
margin-top: 6px;
37+
margin-right: 8px;
38+
border-radius: 2px !important;
39+
}
40+
}
41+
}
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { Component, Input, Output, EventEmitter } from '@angular/core';
2+
3+
import { Person } from '../../models/person';
4+
import { Checkin } from '../../models/checkin';
5+
6+
@Component({
7+
selector: 'checkin-details',
8+
templateUrl: 'checkin-details.html'
9+
})
10+
export class CheckinDetailsComponent {
11+
12+
@Input()
13+
checkin:Checkin;
14+
15+
@Input()
16+
person:Person;
17+
18+
@Input()
19+
canSend:boolean = false;
20+
21+
@Input()
22+
canResend:boolean = false;
23+
24+
@Output()
25+
sendClicked = new EventEmitter();
26+
27+
@Output()
28+
resendClicked = new EventEmitter();
29+
30+
hasSendClicked:boolean = false;
31+
hasResendClicked:boolean = false;
32+
33+
constructor() {
34+
}
35+
36+
ngOnInit() {
37+
this.hasSendClicked = this.sendClicked && this.sendClicked.observers.length > 0;
38+
this.hasResendClicked = this.resendClicked && this.resendClicked.observers.length > 0;
39+
}
40+
41+
onSendClicked(event:any) {
42+
this.sendClicked.emit();
43+
}
44+
45+
onResendClicked(event:any) {
46+
this.resendClicked.emit();
47+
}
48+
49+
}

0 commit comments

Comments
 (0)