Commit 6a845010 by Nabil Sadki

Réclamer mes mérites : QR code et Codes de mérites

parent 6b8ea085
......@@ -105,8 +105,36 @@
<feature name="StatusBar">
<param name="ios-package" onload="true" value="CDVStatusBar" />
</feature>
<engine name="android" spec="^8.1.0" />
<allow-navigation href="http://localhost:8101" sessionid="600eac0d" />
<allow-navigation href="http://localhost:8100" sessionid="bbeff116" />
<plugin name="cordova-sqlite-storage" spec="^3.2.0" />
<plugin name="cordova-plugin-advanced-http" spec="^2.1.1">
<variable name="OKHTTP_VERSION" value="3.10.0" />
</plugin>
<plugin name="cordova.plugins.diagnostic" spec="^5.0.0">
<variable name="ANDROID_SUPPORT_VERSION" value="28.+" />
</plugin>
<plugin name="cordova-plugin-request-location-accuracy" spec="^2.3.0">
<variable name="PLAY_SERVICES_LOCATION_VERSION" value="16.+" />
</plugin>
<plugin name="cordova-plugin-local-notification" spec="^0.9.0-beta.2" />
<plugin name="cordova-plugin-whitelist" spec="~1.3.3" />
<plugin name="cordova-plugin-statusbar" spec="~2.4.2" />
<plugin name="cordova-plugin-splashscreen" spec="~5.0.2" />
<plugin name="cordova-plugin-ionic-webview" spec="^4.0.0">
<variable name="ANDROID_SUPPORT_ANNOTATIONS_VERSION" value="27.+" />
</plugin>
<plugin name="cordova-plugin-ionic-keyboard" spec="^2.0.5" />
<plugin name="cordova-plugin-background-mode" spec="~0.7.2" />
<plugin name="cordova-plugin-app-version" spec="^0.1.9" />
<plugin name="cordova-plugin-googleplus" spec="^8.0.0">
<variable name="PLAY_SERVICES_VERSION" value="11.8.0" />
</plugin>
<plugin name="cordova-plugin-google-analytics" spec="^1.8.6">
<variable name="GMS_VERSION" value="16.0.3" />
</plugin>
<engine name="android" spec="^8.1.0" />
<plugin name="cordova-plugin-network-information" spec="~2.0.2" />
<plugin name="cordova-plugin-qrscanner" spec="~3.0.1" />
<plugin name="cordova-plugin-camera" spec="~4.1.0" />
</widget>
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -24,7 +24,7 @@
"@ionic-native/app-version": "^5.11.0",
"@ionic-native/background-geolocation": "^5.8.0",
"@ionic-native/background-mode": "^5.11.0",
"@ionic-native/camera": "^5.14.0",
"@ionic-native/camera": "^5.19.0",
"@ionic-native/core": "^5.0.0",
"@ionic-native/diagnostic": "^5.8.0",
"@ionic-native/file": "^5.14.0",
......@@ -34,6 +34,7 @@
"@ionic-native/ionic-webview": "^5.14.0",
"@ionic-native/local-notifications": "^5.11.0",
"@ionic-native/location-accuracy": "^5.8.0",
"@ionic-native/network": "^5.18.0",
"@ionic-native/qr-scanner": "^5.14.0",
"@ionic-native/splash-screen": "^5.0.0",
"@ionic-native/status-bar": "^5.0.0",
......@@ -44,16 +45,19 @@
"cordova-plugin-app-version": "^0.1.9",
"cordova-plugin-background-mode": "git+https://github.com/sercatven/cordova-plugin-background-mode.git",
"cordova-plugin-badge": "^0.8.8",
"cordova-plugin-camera": "^4.1.0",
"cordova-plugin-file": "^6.0.1",
"cordova-plugin-google-analytics": "^1.8.6",
"cordova-plugin-googleplus": "^8.0.0",
"cordova-plugin-local-notification": "^0.9.0-beta.2",
"cordova-plugin-play-games-services": "^1.1.2",
"cordova-plugin-qrscanner": "^3.0.1",
"cordova-plugin-request-location-accuracy": "^2.3.0",
"cordova-sqlite-storage": "^3.2.0",
"cordova.plugins.diagnostic": "^5.0.0",
"core-js": "^2.5.4",
"core-js": "^2.6.11",
"firebase": "^6.6.1",
"g": "^2.0.1",
"ionic-image-loader": "^6.3.3",
"leaflet": "^1.5.1",
"leaflet.markercluster": "^1.4.1",
......@@ -126,6 +130,11 @@
},
"cordova-plugin-google-analytics": {
"GMS_VERSION": "16.0.3"
},
"cordova-plugin-network-information": {},
"cordova-plugin-qrscanner": {},
"cordova-plugin-camera": {
"ANDROID_SUPPORT_V4_VERSION": "27.+"
}
},
"platforms": [
......
......@@ -10,6 +10,7 @@ import { GoogleAnalytics } from '@ionic-native/google-analytics/ngx';
import { AppVersion } from '@ionic-native/app-version/ngx';
import { AuthService } from './services/auth.service';
import { NetworkService } from './services/network.service';
// import { LocationService } from './services/location-service';
import * as Config from './constants';
......@@ -30,7 +31,8 @@ export class AppComponent {
private storage: Storage,
private ga: GoogleAnalytics,
private appVersion: AppVersion,
private _AUTH: AuthService
private _AUTH: AuthService,
private _NTWK: NetworkService
) {
this.initializeApp();
}
......
......@@ -26,6 +26,7 @@ import { File } from '@ionic-native/File/ngx';
import { WebView } from '@ionic-native/ionic-webview/ngx';
import { FilePath } from '@ionic-native/file-path/ngx';
import { QRScanner, QRScannerStatus } from '@ionic-native/qr-scanner/ngx';
import { Network } from '@ionic-native/network/ngx';
import { environment } from 'src/environments/environment';
import { AuthService } from './services/auth.service';
import { AuthGuardService } from './services/auth-guard.service';
......@@ -74,7 +75,9 @@ import { PipesModule } from './pipes/pipes.module';
QRScanner,
AuthService,
AuthGuardService,
GoogleAnalytics
GoogleAnalytics,
Network
],
bootstrap: [AppComponent]
})
......
......@@ -3,3 +3,6 @@ export const WORDPRESS_URL = 'http://www.allo-testeurs.com/';
export const WORDPRESS_REST_API_URL = WORDPRESS_URL + 'wp-json/wp/v2/';
export const GA_TRACKID = 'UA-129706772-2';
export const WORDPRESS_REST_API_ACF_USER_URL = WORDPRESS_URL + 'wp-json/acf/v3/users/';
export const DRUPAL_URL = 'http://partners.allo-testeurs.com/';
export const DRUPAL_OAUTH_CLIENT_ID = 'be89e1d8-a10c-4448-90e3-8a97a1f305f9';
......@@ -10,6 +10,25 @@
<ion-list>
<ion-list-header color="medium">Informations de base</ion-list-header>
<ion-item>
<ion-label>Civilité <ion-text color="danger">*</ion-text>
</ion-label>
<ion-select placeholder="Choisir" okText="OK" cancelText="Fermer" formControlName="civilite">
<ion-select-option value="Mme">Mme</ion-select-option>
<ion-select-option value="Mlle">Mlle</ion-select-option>
<ion-select-option value="Mr">Mr</ion-select-option>
</ion-select>
</ion-item>
<div class="validation-errors">
<ng-container *ngFor="let validation of vMessages.civilite">
<div class="error-message"
*ngIf="vForm.get('civilite').hasError(validation.type) && (vForm.get('civilite').dirty || vForm.get('civilite').touched)">
<ion-text color="danger">
<ion-icon name="information-circle-outline"></ion-icon> {{ validation.message }}
</ion-text>
</div>
</ng-container>
</div>
<ion-item>
<ion-label position="floating">Prénom <ion-text color="danger">*</ion-text>
</ion-label>
<ion-input type="text" formControlName="prenom" clearInput></ion-input>
......@@ -70,7 +89,13 @@
</ng-container>
</div>
<ion-list-header color="medium">Sécurité</ion-list-header>
<div formGroupName="matching_passwords">
<ion-item>
<ion-text class="ion-padding ion-text-justify">
Un email vous sera envoyer afin de compléter la création de compte et créer un mot de passe pour votre
compte.
</ion-text>
</ion-item>
<!-- <div formGroupName="matching_passwords">
<ion-item>
<ion-label position="floating">Mot de passe <ion-text color="danger">*</ion-text>
</ion-label>
......@@ -109,10 +134,11 @@
</div>
</ng-container>
</div>
</div>
</div> -->
<ion-item lines="none" class="ion-text-end">
<ion-button class="ion-float-end" color="tertiary" routerLink="/login" routerDirection="backward" routerLinkActive="active">
Annuler</ion-button>
<ion-button class="ion-float-end" color="tertiary" routerLink="/login" routerDirection="backward"
routerLinkActive="active">
Annuler</ion-button>
<ion-button class="ion-float-end" type="submit" [disabled]="!vForm.valid"
(click)="vForm.valid && onSubmit(vForm.value)">Créer mon compte</ion-button>
</ion-item>
......
import { Component, OnInit } from '@angular/core';
import { Validators, FormBuilder, FormGroup, FormControl } from '@angular/forms';
import { Storage } from '@ionic/storage';
import { Router } from '@angular/router';
import { PasswordValidator } from '../../../validators/password';
import { AlloService } from '../../../services/allo-service';
import { AuthService } from '../../../services/auth.service';
......@@ -16,6 +17,9 @@ export class CreatePage implements OnInit {
matchingPasswordsGroup: FormGroup;
syncing = false;
vMessages = {
civilite: [
{ type: 'required', message: 'Champs requis.' }
],
nom: [
{ type: 'required', message: 'Champs requis.' }
],
......@@ -45,22 +49,24 @@ export class CreatePage implements OnInit {
constructor(
public formBuilder: FormBuilder,
public storage: Storage,
public router: Router,
public _ALLO: AlloService,
public _AUTH: AuthService
) { }
ngOnInit() {
this.matchingPasswordsGroup = new FormGroup({
password: new FormControl('', Validators.compose([
Validators.minLength(5),
Validators.required,
Validators.pattern('^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[a-zA-Z0-9]+$')
])),
password_confirm: new FormControl('', Validators.required)
}, (formGroup: FormGroup) => {
return PasswordValidator.areEqual(formGroup);
});
// this.matchingPasswordsGroup = new FormGroup({
// password: new FormControl('', Validators.compose([
// Validators.minLength(5),
// Validators.required,
// Validators.pattern('^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[a-zA-Z0-9]+$')
// ])),
// password_confirm: new FormControl('', Validators.required)
// }, (formGroup: FormGroup) => {
// return PasswordValidator.areEqual(formGroup);
// });
this.vForm = this.formBuilder.group({
civilite: new FormControl('', Validators.required),
nom: new FormControl('', Validators.required),
prenom: new FormControl('', Validators.required),
tel: new FormControl('', Validators.required),
......@@ -70,7 +76,7 @@ export class CreatePage implements OnInit {
Validators.required,
Validators.pattern('^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,15}$')
])),
matching_passwords: this.matchingPasswordsGroup,
// matching_passwords: this.matchingPasswordsGroup,
});
}
......@@ -82,11 +88,20 @@ export class CreatePage implements OnInit {
result => {
this._ALLO.dismissLoading();
console.log(result);
this.vForm.reset();
this._ALLO.presentAlert('Confirmation', 'Votre compte est bien créé.<br>Nous venons de vous envoyer un email pour activer votre compte et choisir un mot de passe.')
.then(() => {
this.router.navigate(['login']);
});
},
err => {
console.log(err);
this._ALLO.dismissLoading();
const error = JSON.parse(err.error)
console.log(err);
this.vForm.reset();
this._ALLO.presentAlert('Erreur', this._AUTH.getErrorMessage(err));
});
}
......
......@@ -6,12 +6,12 @@
</ion-button>
</ion-toolbar>
</ion-header>
<ion-content text-center color="primary" padding>
<ion-content color="primary" class="ion-padding ion-text-center">
<!-- <img src="../../../assets/logo-full-white.png" /> -->
<ion-icon name="unlock" class="key-logo"></ion-icon>
<form [formGroup]="validationsForm" (ngSubmit)="onSubmit(validationsForm.value)">
<ion-card color="light" no-padding no-margin>
<ion-card-content no-padding>
<ion-card color="light" class="ion-no-margin ion-no-padding">
<ion-card-content class="ion-no-padding">
<ion-item>
<!-- <ion-label position="floating">Email :</ion-label> -->
<ion-input name="email" formControlName="email" type="email" placeholder="adresse@email.com" required>
......@@ -44,7 +44,7 @@
</ion-text>
</a> -->
<ion-item-divider color="primary"> </ion-item-divider>
<ion-button color="dark" expand="block" type="submit" [disabled]="validationsForm.invalid" no-margin>
<ion-button color="dark" expand="block" type="submit" [disabled]="validationsForm.invalid" class="ion-no-margin">
<ion-icon name="log-in"></ion-icon>
Connexion
</ion-button>
......@@ -56,10 +56,10 @@
<div class="separator">
<span>Autres options :</span>
</div>
<ion-grid no-padding margin-top>
<ion-grid class="ion-margin-top ion-no-padding">
<ion-row>
<ion-col class="ion-no-padding ion-text-start">
<ion-button color="dark" class="btn-g" (click)="doAnonymousLogIn()" no-margin>
<ion-button color="dark" class="btn-g ion-no-margin" (click)="doAnonymousLogIn()">
<ion-icon name="walk"></ion-icon>
Anonyme
</ion-button>
......
......@@ -70,30 +70,38 @@ export class LoginPage implements OnInit {
doAnonymousLogIn() {
this.ga.trackEvent('Login', 'Tapped button', 'Anonymous login');
this._AUTH.isAnonymous = true;
const wpUser = {
token: null,
user_nicename: 'anonymous',
user_display_name: 'Mode anonyme',
user_email: 'nomail',
const alloUser = {
user_infos : {
"uid": 0,
"mail": "nomail",
"nom": "anonymous",
"prenom": "anonymous",
"nom_complet": "Mode anonyme",
"cnie": "-",
"adresse": "-",
"tel": "-",
"badge": "testeur",
}
};
this.storage.set('wpUser', wpUser).then(() => {
this._AUTH.setUser(wpUser);
// this.storage.get('APP_PARAMS').then(appParams => {
// if (appParams.PARAM_mainslider) {
// this.router.navigate(['app/dashboard']);
// } else {
// this.router.navigate(['mainslider']);
// }
// });
this.storage.set('alloUser', alloUser).then(() => {
this._AUTH.setUser(alloUser);
this.storage.get('APP_PARAMS').then(appParams => {
if (appParams.PARAM_mainslider) {
this.router.navigate(['app/dashboard']);
} else {
this.router.navigate(['mainslider']);
}
});
});
}
onSubmit(values) {
this.ga.trackEvent('Login', 'Tapped button', 'Try normal login');
this._ALLO.presentLoading();
this._AUTH.doLogin(values)
// this._AUTH.doLogin(values)
this._AUTH.doDrupLogin(values)
.then(
res => {
res => {console.log(res);
this.ga.trackEvent('Login', 'Result', 'Successfull connection');
this._ALLO.dismissLoading();
this._AUTH.isAnonymous = false;
......@@ -105,12 +113,13 @@ export class LoginPage implements OnInit {
}
});
},
err => {
err => {console.log(err);
this.ga.trackEvent('Login', 'Result', 'Connection error : ' + err);
this._ALLO.dismissLoading();
// swal('Connexion', 'Email ou Mot de passe incorrects. Veuillez réessayer.', 'error');
// this._ALLO.presentAlert('Connexion', 'Email ou Mot de passe incorrects.<br>Veuillez réessayer.');
this._ALLO.presentToast('', 'Email ou Mot de passe incorrects.<br>Veuillez réessayer.', 'top');
this._ALLO.presentToast('', this._AUTH.getErrorMessage(err), 'top');
console.log('Auth error', err);
});
// this._ALLO.presentLoading();
......
......@@ -18,26 +18,41 @@
<ion-grid>
<ion-row padding>
<ion-col size="4">
<ion-avatar>
<ion-avatar [hidden]="editMode">
<ion-img [src]="_AUTH.userInfos.avatar"></ion-img>
<!-- <ion-chip color="primary" *ngIf="editMode">
<ion-icon name="camera" class="ion-no-margin"></ion-icon> Modifier
</ion-chip> -->
</ion-avatar>
</ion-col>
<ion-col size="8">
<ion-col [size]="editMode ? 12 : 8">
<ion-text>
<h2 [hidden]="editMode">{{ _AUTH.userInfos.display_name }}</h2>
<h2 [hidden]="editMode">{{ _AUTH?.userInfos?.nom_complet }}</h2>
</ion-text>
<ion-list>
<ion-item [hidden]="!editMode">
<ion-select placeholder="Choisir" okText="OK" cancelText="Fermer"
[value]="_AUTH.userInfos.civilite" formControlName="civilite">
<ion-select-option value="Mme">Mme</ion-select-option>
<ion-select-option value="Mlle">Mlle</ion-select-option>
<ion-select-option value="Mr">Mr</ion-select-option>
</ion-select>
</ion-item>
<ion-item [hidden]="!editMode">
<ion-input type="text" [value]="_AUTH.userInfos.display_name" formControlName="name"
<ion-input type="text" [value]="_AUTH.userInfos.prenom" formControlName="first_name" placeholder="Prénom"
clearInput>
</ion-input>
</ion-item>
<ion-chip [color]="editMode ? 'medium' : 'primary'" [outline]="editMode ? false : true">
<ion-icon name="star"></ion-icon>
<ion-label>Testeur</ion-label>
</ion-chip>
</ion-text>
<ion-item [hidden]="!editMode">
<ion-input type="text" [value]="_AUTH.userInfos.nom" formControlName="last_name" placeholder="Nom" clearInput>
</ion-input>
</ion-item>
</ion-list>
<ion-chip [color]="editMode ? 'medium' : 'primary'" [outline]="editMode ? false : true"
[hidden]="editMode">
<ion-icon name="star"></ion-icon>
<ion-label>Testeur(se)</ion-label>
</ion-chip>
</ion-col>
</ion-row>
<!-- <ion-row no-padding padding-horizontal padding-top>
......@@ -61,12 +76,12 @@
<ion-icon name="stopwatch" slot="start"></ion-icon> {{ _AUTH.userInfos.expire_at | expireAt }}
</ion-item>
<ion-item lines="none" [color]="editMode ? 'medium' : ''">
<ion-icon name="person" slot="start"></ion-icon> {{ _AUTH.userInfos.cni }}
<ion-icon name="person" slot="start"></ion-icon> {{ _AUTH.userInfos.cnie }}
</ion-item>
</ion-card>
<ion-card color="primary" *ngIf="!_AUTH?.userInfos?.card_number && !editMode">
<ion-text>
<h5 class="ion-text-center">Vous n'avez pas encore.</h5>
<h5 class="ion-text-center">Vous n'avez pas encore</h5>
<h3 class="ion-text-center">la Carte Testeur.</h3>
<p class="ion-text-center">Le saviez-vous? la Carte Testeur vous permet de bénéficer de plusieurs offres
exclusives!</p>
......@@ -83,24 +98,25 @@
<!-- <ion-button slot="end" color="light" fill="outline" routerLink="/app/profil-edit" routerDirection="root"
routerLinkActive="active">Modifier</ion-button> -->
</ion-item>
<ion-item>
<ion-item [color]="editMode ? 'medium' : ''">
<ion-icon name="mail" slot="start" [color]="editMode ? 'secondary' : ''"></ion-icon>
<ion-text [hidden]="editMode">{{ _AUTH.userInfos.user_email }}</ion-text>
<ion-input type="email" [hidden]="!editMode" [value]="_AUTH.userInfos.user_email"
formControlName="email" clearInput>
</ion-input>
<ion-text>{{ _AUTH?.userInfos?.mail }}</ion-text>
<!-- <ion-text [hidden]="editMode">{{ _AUTH?.userInfos?.mail }}</ion-text>
<ion-input type="email" [hidden]="!editMode" [value]="_AUTH?.userInfos?.mail" formControlName="email"
clearInput>
</ion-input> -->
</ion-item>
<ion-item>
<ion-icon name="pin" slot="start" [color]="editMode ? 'secondary' : ''"></ion-icon>
<ion-text [hidden]="editMode">{{ _AUTH.userInfos.addresse }}</ion-text>
<ion-input type="text" [hidden]="!editMode" [value]="_AUTH.userInfos.addresse"
formControlName="addresse" clearInput>
<ion-text [hidden]="editMode">{{ _AUTH?.userInfos?.adresse }}</ion-text>
<ion-input type="text" [hidden]="!editMode" [value]="_AUTH?.userInfos?.adresse"
formControlName="addresse" placeholder="Addresse" clearInput>
</ion-input>
</ion-item>
<ion-item lines="none">
<ion-icon name="call" slot="start" [color]="editMode ? 'secondary' : ''"></ion-icon>
<ion-text [hidden]="editMode">{{ _AUTH.userInfos.phone }}</ion-text>
<ion-input type="text" [hidden]="!editMode" [value]="_AUTH.userInfos.phone" formControlName="phone"
<ion-text [hidden]="editMode">{{ _AUTH?.userInfos?.tel }}</ion-text>
<ion-input type="text" [hidden]="!editMode" [value]="_AUTH?.userInfos?.tel" formControlName="phone" placeholder="Téléphone"
clearInput>
</ion-input>
</ion-item>
......@@ -120,4 +136,4 @@
</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-footer>
</ion-footer>
\ No newline at end of file
import { Component, OnInit } from '@angular/core';
import { AuthService } from '../../../services/auth.service';
import { AlloService } from '../../../services/allo-service';
import { Validators, FormBuilder, FormGroup, FormControl } from '@angular/forms';
import { Storage } from '@ionic/storage';
......@@ -15,7 +16,13 @@ export class ProfilPage implements OnInit {
editMode = false;
syncing = false;
validationMessages = {
name: [
civilite: [
{ type: 'required', message: 'Champs requis.' }
],
first_name: [
{ type: 'required', message: 'Champs requis.' }
],
last_name: [
{ type: 'required', message: 'Champs requis.' }
],
email: [
......@@ -33,12 +40,15 @@ export class ProfilPage implements OnInit {
constructor(
public formBuilder: FormBuilder,
public storage: Storage,
public _ALLO: AlloService,
public _AUTH: AuthService
) { }
ngOnInit() {
this.validationsForm = this.formBuilder.group({
name: new FormControl('', Validators.required),
civilite: new FormControl('', Validators.required),
first_name: new FormControl('', Validators.required),
last_name: new FormControl('', Validators.required),
phone: new FormControl('', Validators.required),
addresse: new FormControl('', Validators.required),
email: new FormControl('', Validators.compose([
......@@ -46,41 +56,43 @@ export class ProfilPage implements OnInit {
Validators.pattern('^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,15}$')
]))
});
this.storage.get('wpUserInfos').then(wpUserInfos => {
if (wpUserInfos) {
this.validationsForm.controls['name'].setValue(wpUserInfos.display_name);
this.validationsForm.controls['email'].setValue(wpUserInfos.user_email);
this.validationsForm.controls['addresse'].setValue(wpUserInfos.addresse);
this.validationsForm.controls['phone'].setValue(wpUserInfos.phone);
this.storage.get('alloUser').then(alloUser => {
if (alloUser) {
this.validationsForm.controls['civilite'].setValue(alloUser.user_infos.civilite);
this.validationsForm.controls['first_name'].setValue(alloUser.user_infos.prenom);
this.validationsForm.controls['last_name'].setValue(alloUser.user_infos.nom);
this.validationsForm.controls['email'].setValue(alloUser.user_infos.mail);
this.validationsForm.controls['addresse'].setValue(alloUser.user_infos.adresse);
this.validationsForm.controls['phone'].setValue(alloUser.user_infos.tel);
}
});
}
onSubmit(values) {
this.syncing = true;
this.storage.get('wpUserInfos').then(wpUserInfos => {
if (wpUserInfos) {
wpUserInfos.display_name = values.name;
wpUserInfos.user_email = values.email;
wpUserInfos.addresse = values.addresse;
wpUserInfos.phone = values.phone;
this.storage.set('wpUserInfos', wpUserInfos).then(() => {
this._AUTH.userInfos = wpUserInfos;
const userData = {
name: values.name,
email: values.email,
addresse: values.addresse,
phone: values.phone,
context: 'edit',
meta: {
addresse: values.addresse,
phone: values.phone
}
};
this._AUTH.doUserUpdate(userData).then(
this.storage.get('alloUser').then(alloUser => {
if (alloUser) {
alloUser.user_infos.civilite = values.civilite;
alloUser.user_infos.prenom = values.first_name;
alloUser.user_infos.nom = values.last_name;
alloUser.user_infos.nom_complet = values.first_name + ' ' + values.last_name;
alloUser.user_infos.mail = values.email;
alloUser.user_infos.adresse = values.addresse;
alloUser.user_infos.tel = values.phone;
this.storage.set('alloUser', alloUser).then(() => {
this._AUTH.updateServiceProps(alloUser);
this._AUTH.userInfos = alloUser.user_infos;
this._AUTH.infoFullname = alloUser.user_infos.prenom + ' ' + alloUser.user_infos.nom;
this._AUTH.doUserUpdate(alloUser.user_infos).then(
result => {
console.log(result);
this._ALLO.presentToast('Confirmation', 'Modifications bien sauvegardées', 'top');
this.editMode = false;
this.syncing = false;
},
err => {
console.log(err);
});
});
}
......
......@@ -8,7 +8,7 @@
<ion-title>Lots à gagner</ion-title>
<ion-chip slot="end">
<ion-icon name="ribbon" color="secondary"></ion-icon>
<ion-label color="light">10 542</ion-label>
<ion-label color="light">{{ _QST.pointsMerites }}</ion-label>
</ion-chip>
</ion-toolbar>
</ion-header>
......
import { Component, OnInit } from '@angular/core';
import { ModalController } from '@ionic/angular';
import { QuestsService } from "../../../services/quests.service";
import { LotsService } from '../../../services/data/lots.service';
import { LotsAGagnerFilterPage } from '../lots-a-gagner-filter/lots-a-gagner-filter.page';
......@@ -12,6 +13,7 @@ export class LotsAGagnerPage implements OnInit {
constructor(
public modalController: ModalController,
private _QST: QuestsService,
public _LOTS: LotsService
) { }
......
......@@ -20,12 +20,12 @@
<ion-row>
<ion-col size="4">
<ion-avatar>
<ion-img [src]="_AUTH?.userInfos?.avatar"></ion-img>
<ion-img [src]="_AUTH?.infoAvatar"></ion-img>
</ion-avatar>
</ion-col>
<ion-col size="8">
<ion-text>
<h4>{{ _AUTH?.userInfos?.display_name }}</h4>
<h4>{{ _AUTH?.infoFullname }}</h4>
</ion-text>
<ion-chip color="light">
<ion-icon name="star"></ion-icon>
......
......@@ -15,7 +15,7 @@ export class MenuPage implements OnInit {
title: 'Les promos',
url: '/app/dashboard',
icon: 'home',
anonymous: 'true'
anonymous: true
},
{
title: 'Partenaires',
......@@ -32,7 +32,8 @@ export class MenuPage implements OnInit {
{
title: 'Mes mérites',
url: '/app/mes-merites',
icon: 'ribbon'
icon: 'ribbon',
anonymous: false
},
{
title: 'Paramètres',
......
......@@ -7,7 +7,7 @@
<ion-title>Mes mérites</ion-title>
<ion-chip slot="end">
<ion-icon name="ribbon" color="secondary"></ion-icon>
<ion-label color="light">10 542</ion-label>
<ion-label color="light">{{ _QST.pointsMerites }}</ion-label>
</ion-chip>
</ion-toolbar>
</ion-header>
......@@ -44,56 +44,78 @@
</ion-segment-button>
</ion-segment>
<ion-list *ngSwitchCase="'approbation'">
<ion-item *ngFor="let img of [1,2,3,4,5,6,7,8,9]">
<ion-icon name="timer" slot="start"></ion-icon>
<ion-card [hidden]="_DMD.demandesEnCours.data.length" padding>
<h1 class="ion-text-center">
<ion-icon name="filing" color="danger"></ion-icon>
</h1>
<ion-text>
<h3 class="ion-text-center">Aucune demande pour le moment.</h3>
</ion-text>
</ion-card>
<ion-item *ngFor="let demande of _DMD.demandesEnCours.data">
<ion-text class="ion-text-center" slot="end">
<ion-icon name="timer"></ion-icon>
</ion-text>
<ion-label>
<h2>Connexion</h2>
<p>Se connecter à l'application la première fois</p>
<p>
<ion-icon name="calendar"></ion-icon> Demandé le : 0{{ img }}/09/2019
</p>
<h2>{{ demande.attributes.title }}</h2>
<p>
<ion-badge color="warning">
<ion-icon name="ribbon"></ion-icon>
100
{{ demande.attributes.field_merites }}
</ion-badge>
</p>
</ion-label>
</ion-item>
</ion-list>
<ion-list *ngSwitchCase="'traitees'">
<ion-item>
<ion-badge color="warning" slot="start">
<ion-icon name="ribbon"></ion-icon>
200
</ion-badge>
<ion-label>
<h2>Connexion</h2>
<p>Se connecter à l'application la première fois</p>
<p>
<ion-icon name="calendar"></ion-icon> Terminé le : 04/09/2019
<ion-icon name="calendar"></ion-icon> Demandé le : {{ demande.attributes.created | date: 'dd/MM/yyyy à HH:mm' }}
</p>
<p>
<ion-badge color="success" slot="start">
Approuvée
<ion-badge color="orange" *ngIf="demande.attributes.field_type_de_demande == 'code'">
<ion-icon name="code-working"></ion-icon>
Code de mérites
</ion-badge>
<ion-badge color="blue" *ngIf="demande.attributes.field_type_de_demande == 'qrcode'">
<ion-icon name="qr-scanner"></ion-icon>
QR code scan
</ion-badge>
</p>
</ion-label>
</ion-item>
<ion-item *ngFor="let img of [1,2,3,4,5,6,7,8,9]">
<ion-badge color="warning" slot="start">
<ion-icon name="ribbon"></ion-icon>
500
</ion-badge>
</ion-list>
<ion-list *ngSwitchCase="'traitees'">
<ion-card [hidden]="_DMD.demandesTraitees.data.length" padding>
<h1 class="ion-text-center">
<ion-icon name="filing" color="danger"></ion-icon>
</h1>
<ion-text>
<h3 class="ion-text-center">Aucune demande pour le moment.</h3>
</ion-text>
</ion-card>
<ion-item *ngFor="let demandeT of _DMD.demandesTraitees.data">
<ion-text class="ion-text-center" slot="end">
<ion-icon name="checkmark-circle" color="success" *ngIf="demandeT.attributes.field_statut_de_la_demande == 'approuvee'"></ion-icon>
<ion-icon name="close-circle" color="danger" *ngIf="demandeT.attributes.field_statut_de_la_demande == 'refusee'"></ion-icon>
</ion-text>
<ion-label>
<h2>Parrainage</h2>
<p>Parrainer 10 ami(e)s</p>
<h2>{{ demandeT.attributes.title }}</h2>
<p>
<ion-badge [color]="demandeT.attributes.field_statut_de_la_demande == 'approuvee' ? 'success' : 'danger'">
<ion-icon name="ribbon"></ion-icon>
{{ demandeT.attributes.field_merites }}
</ion-badge>
</p>
<p>
<ion-icon name="calendar"></ion-icon> Terminé le : 0{{ img }}/09/2019
<ion-icon name="calendar"></ion-icon> Traitée le : {{ demandeT.attributes.changed | date: 'dd/MM/yyyy à HH:mm' }}
</p>
<p *ngIf="demandeT.attributes.field_statut_de_la_demande == 'refusee'">
<ion-icon name="hand"></ion-icon> Raison du refus : {{ demandeT.attributes.field_raison_du_refus }}
</p>
<p>
<ion-badge color="danger" slot="start">
Refusée
<ion-badge color="orange" *ngIf="demandeT.attributes.field_type_de_demande == 'code'">
<ion-icon name="code-working"></ion-icon>
Code de mérites
</ion-badge>
<ion-badge color="blue" *ngIf="demandeT.attributes.field_type_de_demande == 'qrcode'">
<ion-icon name="qr-scanner"></ion-icon>
QR code scan
</ion-badge>
</p>
</ion-label>
......
ion-list {
ion-text[slot="end"] {
ion-icon[name="timer"], ion-icon[name="checkmark-circle"], ion-icon[name="close-circle"] {
font-size: 2.5rem;
}
}
}
\ No newline at end of file
import { Component, OnInit } from '@angular/core';
import { QuestsService } from '../../../services/quests.service';
import { DemandsService } from "../../../services/demands.service";
@Component({
selector: 'app-mes-merites',
......@@ -8,9 +10,14 @@ import { Component, OnInit } from '@angular/core';
export class MesMeritesPage implements OnInit {
viewList = 'approbation';
constructor() { }
constructor(
private _QST: QuestsService,
private _DMD: DemandsService
) { }
ngOnInit() {
this._DMD.loadDemands();
}
segmentChanged(event) {
......
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { Routes, RouterModule } from '@angular/router';
import { IonicModule } from '@ionic/angular';
......@@ -19,6 +19,7 @@ const routes: Routes = [
CommonModule,
FormsModule,
IonicModule,
ReactiveFormsModule,
RouterModule.forChild(routes)
],
declarations: [ReclamerMeritesCodePage]
......
......@@ -7,7 +7,8 @@
Code de mérites
</ion-title>
<ion-buttons slot="end">
<ion-button color="success" fill="solid" size="small">Valider</ion-button>
<ion-button color="success" fill="solid" size="small" [disabled]="!validationsForm.valid"
(click)="validationsForm.valid && validateCode(validationsForm.value)">Valider</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
......@@ -23,11 +24,13 @@
</ion-item>
<ion-card>
<ion-list>
<ion-list-header color="tertiary">Code de mérites</ion-list-header>
<ion-item lines="none">
<ion-label position="floating">Code</ion-label>
<ion-input placeholder="Saisissez le code ici..."></ion-input>
</ion-item>
<form [formGroup]="validationsForm">
<ion-list-header color="tertiary">Code de mérites</ion-list-header>
<ion-item lines="none">
<ion-label position="floating">Code</ion-label>
<ion-input placeholder="Saisissez le code ici..." formControlName="code"></ion-input>
</ion-item>
</form>
</ion-list>
</ion-card>
</ion-content>
\ No newline at end of file
import { Component, OnInit } from '@angular/core';
import { Validators, FormBuilder, FormGroup, FormControl } from '@angular/forms';
import { HTTP } from '@ionic-native/http/ngx';
import { AuthService } from "../../../services/auth.service";
import { AlloService } from "../../../services/allo-service";
import { QuestsService } from "../../../services/quests.service";
import { DemandsService } from "../../../services/demands.service";
import * as Config from "../../../constants";
@Component({
selector: 'app-reclamer-merites-code',
......@@ -7,9 +14,69 @@ import { Component, OnInit } from '@angular/core';
})
export class ReclamerMeritesCodePage implements OnInit {
constructor() { }
validationsForm: FormGroup;
validationMessages = {
code: [
{ type: 'required', message: 'Champs requis.' }
]
};
constructor(
public formBuilder: FormBuilder,
private httpAdv: HTTP,
private _AUTH: AuthService,
private _ALLO: AlloService,
private _QST: QuestsService,
private _DMD: DemandsService
) { }
ngOnInit() {
this.validationsForm = this.formBuilder.group({
code: new FormControl('', Validators.required)
});
}
validateCode(values) {
this._ALLO.presentLoading();
const header = {
'Authorization': 'Bearer ' + this._AUTH.userToken,
};
this.httpAdv.sendRequest(Config.DRUPAL_URL + 'partenaire/validate-merits-code/' + values.code,
{
method: 'post',
data: {},
headers: header,
serializer: 'json',
timeout: 5000
}
)
.then((response: any) => {
this._ALLO.dismissLoading();
const data = JSON.parse(response.data);
this.validationsForm.reset();
if (data.code == 'OK') {
// const merites = +data.merites
this._QST.pointsMerites = +this._QST.pointsMerites + +data.merites;
this._AUTH.getUser().then(alloUser => {
alloUser.user_infos.merites = this._QST.pointsMerites;
this._AUTH.setUser(alloUser).then(() => {
this._ALLO.presentAlert('Félicitations!', 'Vous venez de gagner :<br><h3>' + data.merites + ' mérites!!</h3>');
// this._AUTH.doRefreshToken().then(() => {
this._DMD.loadDemands();
// });
})
});
} else {
this._ALLO.presentAlert('Validation', 'Le code saisi n\'est pas valide.');
}
})
.catch(response => {
this._ALLO.dismissLoading();
console.log(response);
this.validationsForm.reset();
this._ALLO.presentAlert('Erreur', 'Problème lors du traitement de votre requête.');
});
}
}
import { Component, OnInit } from '@angular/core';
import { QRScanner, QRScannerStatus } from '@ionic-native/qr-scanner/ngx';
import { HTTP } from '@ionic-native/http/ngx';
import { AuthService } from "../../../services/auth.service";
import { AlloService } from "../../../services/allo-service";
import * as Config from "../../../constants";
@Component({
selector: 'app-reclamer-merites-qrcode',
......@@ -10,7 +14,10 @@ export class ReclamerMeritesQrcodePage implements OnInit {
isOn = false;
scanner: any;
constructor(
private qrScanner: QRScanner
private qrScanner: QRScanner,
private httpAdv: HTTP,
private _AUTH: AuthService,
private _ALLO: AlloService
) { }
ngOnInit() {
......@@ -23,12 +30,34 @@ export class ReclamerMeritesQrcodePage implements OnInit {
this.isOn = true;
this.qrScanner.show();
this.scanner = this.qrScanner.scan().subscribe((text: string) => {
this.scanner = this.qrScanner.scan().subscribe((token: string) => {
this.hideQRcode();
console.log('Scanned something', text, this.isOn);
// setTimeout(() => {
// alert(text);
// }, 3000);
// Validate token
if (token.startsWith('token:')) {
console.log('Scanned something', token, this.isOn);
const header = {
'Authorization': 'Bearer ' + this._AUTH.userToken,
};
this.httpAdv.sendRequest(Config.DRUPAL_URL + 'partenaire/validate-qrcode' + token.replace('token:', ''),
{
method: 'post',
data: {},
headers: header,
serializer: 'json',
timeout: 5000
}
)
.then((response: any) => {
this._ALLO.presentAlert('Félicitations!', 'Vous venez de gagner :<br><h3>' + response.merites + ' mérites</h3>');
})
.catch(response => {
console.log(response);
this._ALLO.presentAlert('Erreur', 'Problème lors du traitement de votre requête.');
});
} else {
this._ALLO.presentAlert('Infos', 'Le code scanné n\'est pas valide.');
}
});
} else if (status.denied) {
......
......@@ -23,8 +23,8 @@
</ion-row>
</ion-grid> -->
<ion-chip slot="end">
<ion-icon name="trending-up" color="blue"></ion-icon>
<ion-label color="dark" class="ion-padding-end">{{ _QST.pointsExp }}</ion-label>
<!-- <ion-icon name="trending-up" color="blue"></ion-icon>
<ion-label color="dark" class="ion-padding-end">{{ _QST.pointsExp }}</ion-label> -->
<ion-icon name="ribbon" color="secondary"></ion-icon>
<ion-label color="dark">{{ _QST.pointsMerites }}</ion-label>
</ion-chip>
......
......@@ -13,6 +13,7 @@ export class AlloService {
public prmTrackdelay = 60000;
public prmNotifnbr: any = 'all';
public loading;
public loaderIsLoaded = false;
constructor(
private alertCtrl: AlertController,
......@@ -99,12 +100,28 @@ export class AlloService {
cssClass: 'custom-class custom-loading'
});
return await this.loading.present().then(() => {
this.loaderIsLoaded = true;
this.showPage = true;
});
}
async presentNetworkLookup() {
this.showPage = false;
this.loading = await this.loadingCtrl.create({
// spinner: null,
duration: 0,
message: 'Connection perdue...',
cssClass: 'custom-class custom-loading'
});
return await this.loading.present().then(() => {
this.showPage = true;
});
}
dismissLoading() {
this.loading.dismiss();
if (this.loaderIsLoaded) {
this.loadingCtrl.dismiss();
}
}
async presentToast(header, message, position) {
......
import { Injectable } from '@angular/core';
import { QuestsService } from "../quests.service";
@Injectable({
providedIn: 'root'
......@@ -9,7 +10,9 @@ export class LotsService {
filtredLots: Array<any>;
filters = {};
constructor() {
constructor(
private _QST: QuestsService
) {
this.lots = this.getLots();
this.filtredLots = this.lots;
}
......@@ -199,7 +202,7 @@ export class LotsService {
if (value === 'all') {
return_value = true;
} else if (key === 'show') {
return_value = item.merites <= 1000;
return_value = item.merites <= this._QST.pointsMerites;
} else if (key === 'type') {
return_value = item.type === parseInt(value);
} else if (key === 'brand') {
......
import { TestBed } from '@angular/core/testing';
import { DemandsService } from './demands.service';
describe('DemandsService', () => {
beforeEach(() => TestBed.configureTestingModule({}));
it('should be created', () => {
const service: DemandsService = TestBed.get(DemandsService);
expect(service).toBeTruthy();
});
});
import { Injectable } from '@angular/core';
import { HTTP } from '@ionic-native/http/ngx';
import { AuthService } from "./auth.service";
import { AlloService } from './allo-service';
import * as Config from '../constants';
@Injectable({
providedIn: 'root'
})
export class DemandsService {
demandesEnCours = {data: []};
demandesTraitees = {data: []};
constructor(
private httpAdv: HTTP,
private _AUTH: AuthService,
private _ALLO: AlloService
) { }
loadDemands() {
this.getDemands(0, 'created').then(
response => {
const jsonApi = JSON.parse(response.data);console.log(jsonApi);
this.demandesEnCours = jsonApi;
},
err => {
console.log(err);
}
);
this.getDemands(1, 'changed').then(
response => {
const jsonApi = JSON.parse(response.data);console.log(jsonApi);
this.demandesTraitees = jsonApi;
},
err => {
console.log(err);
}
);
}
/**
* Update user profil data
* @param userData Data object
*/
getDemands(traitee, sort) {
return new Promise<any>((resolve, reject) => {
const header = {
'Authorization': 'Bearer ' + this._AUTH.userToken
};
this.httpAdv.sendRequest(Config.DRUPAL_URL + 'atapi/node/demande?sort=-' + sort + '&include=field_offre,field_partenaire,field_qrcode,field_abonne,field_code_de_merites&filter[field_demande_traitee_]=' + traitee,
{
method: 'get',
data: {},
headers: header,
timeout: 5000
}
)
.then(response => { resolve(response); })
.catch(response => { reject(response) });
});
}
getInclude(includes, id) {
includes.forEach(element => {
});
}
}
import { TestBed } from '@angular/core/testing';
import { NetworkService } from './network.service';
describe('NetworkService', () => {
beforeEach(() => TestBed.configureTestingModule({}));
it('should be created', () => {
const service: NetworkService = TestBed.get(NetworkService);
expect(service).toBeTruthy();
});
});
import { Injectable } from '@angular/core';
import { Network } from '@ionic-native/network/ngx';
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
import { AlloService } from "./allo-service";
@Injectable({
providedIn: 'root'
})
export class NetworkService {
public isConnected = new BehaviorSubject(false);
constructor(
private network: Network,
private _ALLO: AlloService
) {
this.watch();
}
watch() {
console.log('[Start]: Network watching.');
let disconnectSubscription = this.network.onDisconnect().subscribe(() => {
console.log('network was disconnected :-(');
this.isConnected.next(false);
this._ALLO.presentNetworkLookup();
});
// stop disconnect watch
// disconnectSubscription.unsubscribe();
let connectSubscription = this.network.onConnect().subscribe(() => {
console.log('network connected!');
// We just got a connection but we need to wait briefly
// before we determine the connection type. Might need to wait.
// prior to doing any api requests as well.
setTimeout(() => {
if (this.network.type === 'wifi') {
console.log('we got a wifi connection, woohoo!');
}
this.isConnected.next(true);
this._ALLO.dismissLoading();
}, 3000);
});
// stop connect watch
// connectSubscription.unsubscribe();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment