Fix onboarding flow. Start onboarding and finish on homePage

This commit is contained in:
Gustavo Maximiliano Cortez 2017-09-06 18:25:16 -03:00
parent 7b92d23970
commit 0788347829
No known key found for this signature in database
GPG Key ID: 15EDAD8D9F2EB1AF
24 changed files with 121 additions and 256 deletions

View File

@ -8,6 +8,7 @@ import { AppProvider } from '../providers/app/app';
import { ProfileProvider } from '../providers/profile/profile';
import { TabsPage } from '../pages/tabs/tabs';
import { OnboardingPage } from '../pages/onboarding/onboarding';
@Component({
templateUrl: 'app.html'
@ -47,7 +48,7 @@ export class CopayApp {
} else {
// TODO: go to onboarding page
this.logger.warn('Profile does not exist. Go to Onboarding.');
this.rootPage = TabsPage;
this.rootPage = OnboardingPage;
}
});
});

View File

@ -22,6 +22,11 @@ import { CopayApp } from './app.component';
/* Pages */
import { TabsPage } from '../pages/tabs/tabs';
import { OnboardingPage } from '../pages/onboarding/onboarding';
import { TourPage } from '../pages/onboarding/tour/tour';
import { EmailPage } from '../pages/onboarding/email/email';
import { BackupRequestPage } from '../pages/onboarding/backup-request/backup-request';
import { DisclaimerPage } from '../pages/onboarding/disclaimer/disclaimer';
/* Tabs */
import { HomePage } from '../pages/home/home';
import { ReceivePage } from '../pages/receive/receive';
@ -56,6 +61,11 @@ export function createTranslateLoader(http: Http) {
SettingsPage,
AboutPage,
TermsOfUsePage,
OnboardingPage,
TourPage,
EmailPage,
BackupRequestPage,
DisclaimerPage,
TabsPage
],
imports: [
@ -82,6 +92,11 @@ export function createTranslateLoader(http: Http) {
SettingsPage,
AboutPage,
TermsOfUsePage,
OnboardingPage,
TourPage,
EmailPage,
BackupRequestPage,
DisclaimerPage,
TabsPage
],
providers: [

View File

@ -1,12 +1,4 @@
<ion-header>
<ion-navbar transparent hideBackButton>
</ion-navbar>
</ion-header>
<ion-content class="onboarding backup-request">
<ion-content class="backup-request">
<div id="warning">
<img class="svg" src="assets/img/warning.svg" id="alert-icon" />
<div class="onboarding-topic" translate>No backup, no bitcoin.</div>

View File

@ -1,13 +0,0 @@
import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { BackupRequestPage } from './backup-request';
@NgModule({
declarations: [
BackupRequestPage,
],
imports: [
IonicPageModule.forChild(BackupRequestPage),
],
})
export class BackupRequestPageModule {}

View File

@ -1,7 +1,8 @@
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams, AlertController} from 'ionic-angular';
import { NavController, NavParams, AlertController} from 'ionic-angular';
import { DisclaimerPage } from '../disclaimer/disclaimer';
@IonicPage()
@Component({
selector: 'page-backup-request',
templateUrl: 'backup-request.html',
@ -22,7 +23,6 @@ export class BackupRequestPage {
initBackupFlow() {
// TODO navigate to backupFlow
this.navCtrl.push('BackupWarningPage');
}
later(confirmed: boolean) {
@ -40,7 +40,7 @@ export class BackupRequestPage {
this.later(true);
}, 300);
} else {
this.navCtrl.push('DisclaimerPage');
this.navCtrl.push(DisclaimerPage);
}
}
}]

View File

@ -1,70 +0,0 @@
<ion-header>
<ion-navbar>
<ion-title>Term of use</ion-title>
<ion-buttons end>
<button ion-button (click)="closeModal()">Close</button>
</ion-buttons>
</ion-navbar>
</ion-header>
<ion-content padding>
<div id="terms" class="enable_text_select">
<p>
This is a binding Agreement between BitPay, Inc. (&ldquo;BitPay&rdquo; or &ldquo;We&rdquo;) and the person, persons, or entity (&ldquo;You&rdquo; or &ldquo;Your&rdquo;) using the service, Software, or application (&ldquo;Software&rdquo;).
</p>
<p class="terms__heading">
RIGHTS AND OBLIGATIONS
</p>
<p>
BitPay provides the Software solely on the terms and conditions set forth in this Agreement and on the condition that You accept and comply with them. By using the Software You (a) accept this Agreement and agree that You are legally bound by its terms; and (b) represent and warrant that: (i) You are of legal age to enter into a binding agreement; and (ii) if You are a corporation, governmental organization or other legal entity, You have the right, power and authority to enter into this Agreement on behalf of the corporation, governmental organization or other legal entity and bind them to these terms.
</p>
<p>
This Software functions as a free, open source, and multi-signature digital wallet. The Software does not constitute an account where We or other third parties serve as financial intermediaries or custodians of Your bitcoin(s).
</p>
<p>
While the Software has undergone beta testing and continues to be improved by feedback from the open-source user and developer community, We cannot guarantee there will not be bugs in the Software. You acknowledge that Your use of this Software is at Your own discretion and in compliance with all applicable laws. You are responsible for safekeeping Your passwords, private key pairs, PINs, and any other codes You use to access the Software.
</p>
<p>
IF YOU LOSE ACCESS TO YOUR BITCOIN WALLET OR YOUR ENCRYPTED PRIVATE KEYS AND YOU HAVE NOT SEPARATELY STORED A BACKUP OF YOUR WALLET AND CORRESPONDING PASSWORD, YOU ACKNOWLEDGE AND AGREE THAT ANY BITCOIN YOU HAVE ASSOCIATED WITH THAT WALLET WILL BECOME INACCESSIBLE. All transaction requests are irreversible. The authors of the Software, employees and affiliates of BitPay, copyright holders, and BitPay, Inc. cannot retrieve Your private keys or passwords if You lose or forget them and cannot guarantee transaction confirmation as they do not have control over the bitcoin network.
</p>
<p class="terms__heading">
DISCLAIMER
</p>
<p>
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OF THE SOFTWARE, EMPLOYEES AND AFFILIATES OF BITPAY, COPYRIGHT HOLDERS, OR BITPAY, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
</p>
<p>
IN NO EVENT WILL BITPAY OR ITS AFFILIATES, OR ANY OF ITS OR THEIR RESPECTIVE SERVICE PROVIDERS, BE LIABLE TO YOU OR ANY THIRD PARTY FOR ANY USE, INTERRUPTION, DELAY OR INABILITY TO USE THE SOFTWARE, LOST REVENUES OR PROFITS, DELAYS, INTERRUPTION OR LOSS OF SERVICES, BUSINESS OR GOODWILL, LOSS OR CORRUPTION OF DATA, LOSS RESULTING FROM SYSTEM OR SYSTEM SERVICE FAILURE, MALFUNCTION OR SHUTDOWN, FAILURE TO ACCURATELY TRANSFER, READ OR TRANSMIT INFORMATION, FAILURE TO UPDATE OR PROVIDE CORRECT INFORMATION, SYSTEM INCOMPATIBILITY OR PROVISION OF INCORRECT COMPATIBILITY INFORMATION OR BREACHES IN SYSTEM SECURITY, OR FOR ANY CONSEQUENTIAL, INCIDENTAL, INDIRECT, EXEMPLARY, SPECIAL OR PUNITIVE DAMAGES, WHETHER ARISING OUT OF OR IN CONNECTION WITH THIS AGREEMENT, BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE) OR OTHERWISE, REGARDLESS OF WHETHER SUCH DAMAGES WERE FORESEEABLE AND WHETHER OR NOT WE WERE ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
</p>
<p class="terms__heading">
INTELLECTUAL PROPERTY
</p>
<p>
We retain all right, title, and interest in and to the Content and all of BitPays brands, logos, and trademarks, including, but not limited to, BitPay, Inc., BitPay, BitPay &ndash; Secure Bitcoin Wallet, BitPay Wallet, BitPay App, Copay, BitPay Prepaid Card, and variations of the wording of the aforementioned brands, logos, and trademarks.
</p>
<p class="terms__heading">
CHOICE OF LAW
</p>
<p>
This Agreement, and its application and interpretation, shall be governed exclusively by the laws of the State of Georgia, without regard to its conflict of law rules. You consent to the exclusive jurisdiction of the federal and state courts located in or near Atlanta, Georgia for any dispute arising under this Agreement.
</p>
<p class="terms__heading">
SEVERABILITY
</p>
<p>
In the event any court shall declare any section or sections of this Agreement invalid or void, such declaration shall not invalidate the entire Agreement and all other paragraphs of the Agreement shall remain in full force and effect.
</p>
<p class="terms__heading">
BINDING AGREEMENT
</p>
<p>
The terms and provisions of this Agreement are binding upon Your heirs, successors, assigns, and other representatives. This Agreement may be executed in counterparts, each of which shall be considered to be an original, but both of which constitute the same Agreement.
</p>
<p>
You assume any and all risks associated with the use of the Software. We reserve the right to modify this Agreement from time to time.
</p>
</div>
</ion-content>

View File

@ -1,13 +0,0 @@
import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { DisclaimerModalPage } from './disclaimer-modal';
@NgModule({
declarations: [
DisclaimerModalPage,
],
imports: [
IonicPageModule.forChild(DisclaimerModalPage),
],
})
export class DisclaimerModalPageModule {}

View File

@ -1,3 +0,0 @@
page-disclaimer-modal {
}

View File

@ -1,21 +0,0 @@
import { Component } from '@angular/core';
import { IonicPage, NavParams, ViewController } from 'ionic-angular';
@IonicPage()
@Component({
selector: 'page-disclaimer-modal',
templateUrl: 'disclaimer-modal.html',
})
export class DisclaimerModalPage {
constructor(public navParams: NavParams, private view: ViewController) {
}
ionViewDidLoad() {
}
closeModal() {
this.view.dismiss();
}
}

View File

@ -27,7 +27,7 @@
<ion-checkbox [(ngModel)]="terms.accepted"></ion-checkbox>
<div class="modal-text">
<label (click)="selectTerms()" translate>I have read, understood, and agree to the </label>
<a (click)="openModal()" translate>Terms of Use.</a>
<a (click)="openDisclaimer()" translate>Terms of Use.</a>
</div>
</div>
<button class="primary" ion-button block [disabled]="!accepted.first || !accepted.second || !terms.accepted" (click)="confirm()" translate>Confirm &amp; Finish</button>

View File

@ -1,13 +0,0 @@
import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { DisclaimerPage } from './disclaimer';
@NgModule({
declarations: [
DisclaimerPage,
],
imports: [
IonicPageModule.forChild(DisclaimerPage),
],
})
export class DisclaimerPageModule {}

View File

@ -1,7 +1,9 @@
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams, ModalController} from 'ionic-angular';
import { NavController, NavParams} from 'ionic-angular';
import { TermsOfUsePage } from '../../settings/about/terms-of-use/terms-of-use';
import { TabsPage } from '../../tabs/tabs';
@IonicPage()
@Component({
selector: 'page-disclaimer',
templateUrl: 'disclaimer.html',
@ -10,7 +12,7 @@ export class DisclaimerPage {
public accepted: any;
public terms: any;
constructor(public navCtrl: NavController, public navParams: NavParams, public modalCtrl: ModalController) {
constructor(public navCtrl: NavController, public navParams: NavParams) {
this.accepted = {
first: false,
second: false,
@ -27,13 +29,13 @@ export class DisclaimerPage {
this.terms.accepted = !this.terms.accepted;
}
openModal() {
const myModal = this.modalCtrl.create('DisclaimerModalPage');
myModal.present();
openDisclaimer() {
this.navCtrl.push(TermsOfUsePage);
}
confirm() {
// TODO accept disclaimer
this.navCtrl.setRoot(TabsPage);
this.navCtrl.popToRoot();
}
}

View File

@ -1,6 +1,3 @@
<ion-header>
</ion-header>
<ion-content class="email">
<div id="success-container">
<img src="assets/img/onboarding-success.svg" id="success-image" />

View File

@ -1,13 +0,0 @@
import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { EmailPage } from './email';
@NgModule({
declarations: [
EmailPage,
],
imports: [
IonicPageModule.forChild(EmailPage),
],
})
export class EmailPageModule {}

View File

@ -1,7 +1,8 @@
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams, ActionSheetController } from 'ionic-angular';
import { NavController, NavParams, ActionSheetController } from 'ionic-angular';
import { BackupRequestPage } from '../backup-request/backup-request';
@IonicPage()
@Component({
selector: 'page-email',
templateUrl: 'email.html',
@ -19,7 +20,7 @@ export class EmailPage {
}
skip() {
this.navCtrl.push('BackupRequestPage');
this.navCtrl.push(BackupRequestPage);
}
showActionSheet() {
@ -44,6 +45,6 @@ export class EmailPage {
save() {
// TODO SAVE EMAIL
this.navCtrl.push('BackupRequestPage');
this.navCtrl.push(BackupRequestPage);
}
}

View File

@ -0,0 +1,13 @@
<ion-content>
<div class="logo-tagline">
<img src='assets/img/logo-negative.svg' id="logo" />
<p class="onboarding-description" translate>Take control of your money,<br />get started with bitcoin.</p>
</div>
<button ion-button block clear (click)="skipOnboarding()">Skip Onboarding</button>
<div class="buttons">
<button ion-button block (click)="getStarted()" translate>Get started</button>
<button ion-button block outline (click)="restoreFromBackup()" translate>Restore from backup</button>
</div>
</ion-content>

View File

@ -1,13 +1,5 @@
page-welcome {
position: relative;
page-onboarding {
.logo-tagline {
position: absolute;
width: 100%;
height: 70%;
display: flex;
flex-direction: column;
justify-content: space-around;
img {
width: 50%;

View File

@ -0,0 +1,41 @@
import { Component } from '@angular/core';
import { NavController, NavParams } from 'ionic-angular';
import { TourPage } from './tour/tour';
import { TabsPage } from '../tabs/tabs';
@Component({
selector: 'page-onboarding',
templateUrl: 'onboarding.html',
})
export class OnboardingPage {
constructor(
public navCtrl: NavController,
public navParams: NavParams
) {
}
ionViewDidLoad() {
console.log('ionViewDidLoad OnboardingPage');
}
createProfile() {
// TODO: create a new profile
}
getStarted() {
this.navCtrl.push(TourPage);
}
restoreFromBackup() {
// TODO navigate to backupFlow
}
// TODO: Testing purpose
skipOnboarding() {
this.navCtrl.setRoot(TabsPage);
this.navCtrl.popToRoot();
}
}

View File

@ -1,13 +0,0 @@
import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { TourPage } from './tour';
@NgModule({
declarations: [
TourPage,
],
imports: [
IonicPageModule.forChild(TourPage),
],
})
export class TourPageModule { }

View File

@ -1,9 +1,8 @@
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams, LoadingController } from 'ionic-angular';
import { ViewChild } from '@angular/core';
import { Slides, Navbar } from 'ionic-angular';
import { Component, ViewChild } from '@angular/core';
import { NavController, NavParams, LoadingController, Slides, Navbar } from 'ionic-angular';
import { EmailPage } from '../email/email';
@IonicPage()
@Component({
selector: 'page-tour',
templateUrl: 'tour.html',
@ -28,7 +27,7 @@ export class TourPage {
}
skip() {
this.navCtrl.push('EmailPage');
this.navCtrl.push(EmailPage);
}
slidePrev() {
@ -54,7 +53,7 @@ export class TourPage {
setTimeout(() => {
loading.dismiss();
this.navCtrl.push('EmailPage');
this.navCtrl.push(EmailPage);
}, 1500);
}

View File

@ -1,14 +0,0 @@
<ion-header>
</ion-header>
<ion-content class="onboarding">
<div class="logo-tagline">
<img src='assets/img/logo-negative.svg' id="logo" />
<p class="onboarding-description" translate>Take control of your money,<br />get started with bitcoin.</p>
</div>
<div class="buttons">
<button class="primary" ion-button block (click)="getStarted()" translate>Get started</button>
<button class="secondary" ion-button block outline (click)="initBackupFlow()" translate>Restore from backup</button>
</div>
</ion-content>

View File

@ -1,13 +0,0 @@
import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { WelcomePage } from './welcome';
@NgModule({
declarations: [
WelcomePage,
],
imports: [
IonicPageModule.forChild(WelcomePage),
],
})
export class WelcomePageModule { }

View File

@ -1,26 +0,0 @@
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
@IonicPage()
@Component({
selector: 'page-welcome',
templateUrl: 'welcome.html',
})
export class WelcomePage {
constructor(public navCtrl: NavController, public navParams: NavParams) {
}
ionViewDidLoad() {
}
getStarted() {
this.navCtrl.push('TourPage');
}
initBackupFlow() {
// TODO navigate to backupFlow
this.navCtrl.push('BackupWarningPage');
}
}

View File

@ -41,6 +41,30 @@ $colors: (
dark: #222
);
// TODO: Custom variables (backward compatibilities). Will be REMOVED
$v-primary-color: #192c3a;
$v-secondary-color: #31465b;
$v-accent-color: #1abb9b;
$v-dark-gray: #445 !default;
$v-mid-gray: #667 !default;
$v-light-gray: #9b9bab !default;
$v-title-gray: #c2c9d1 !default;
$v-subtle-gray: darken(#ffffff, 5%) !default;
$v-btn-active-color: #148e76;
$v-background-warning: #ffa500;
$v-background-success: #1abb9b;
$v-onboarding-color: #ffffff !default;
$v-onboarding-bar-header-color: #ffffff !default;
$v-onboarding-bar-header-button-color: #ffffff !default;
$v-onboarding-gradient-top-color: $v-primary-color !default;
$v-onboarding-gradient-bottom-color: $v-secondary-color !default;
$v-onboarding-checkbox-on-border: $v-accent-color;
$v-button-primary-bg: $v-accent-color !default;
$v-visible-radius: 6px !default;
// App iOS Variables
// --------------------------------------------------