# 16th July Report ## Progress Time: **09:00** Event: Entering the lab --- ### Finalize the login page Time: **11:11** - Error handling when user input the wrong email address or password, given by return value from Dispenser API Service with code 0 (zero). - Error will be present with simple Toast, a dismissable pop up notification look like. #### login.page.ts ```typescript= import { Component } from '@angular/core'; import { NavController, ToastController } from '@ionic/angular' import { PreferenceManagerService } from '../../../services/PreferenceManager/preference-manager.service'; import { StaticVariable } from '../../../classes/StaticVariable/static-variable'; import { DispenserAPIService } from '../../../services/DispenserAPI/dispenser-api.service'; @Component({ selector: 'app-login', templateUrl: './login.page.html', styleUrls: ['./login.page.scss'], }) export class LoginPage { email: string = ""; password: string = ""; constructor( private navCtrl: NavController, private pref: PreferenceManagerService, private api: DispenserAPIService, private toastCtrl: ToastController ) { } ngOnInit() { } async login() { const { email, password } = this; let resultData = await this.api.loginUser(email, password); console.log(resultData); if (resultData === 1) { // save the email into session_id await this.pref.saveData(StaticVariable.KEY__SESSION_ID, email); // save the date into last_date let nowDate = new Date(); await this.pref.saveData(StaticVariable.KEY__LAST_DATE, nowDate); // get last page if exists let lastPage = await this.pref.getData(StaticVariable.KEY__LAST_PAGE); if (lastPage === null) { // if null route to home as default this.navCtrl.navigateForward(['dashboard']); } else { // delete last_page from preference await this.pref.removeData(StaticVariable.KEY__LAST_PAGE); // route to going back // this is because when login page called is above the current page this.navCtrl.back(); } console.log("Login successed!"); } else if (resultData === 0) { let myToast = await this.toastCtrl.create({ message: 'Email address or password is incorrect!', duration: 2000, position: 'top', showCloseButton: true, closeButtonText: 'Close' }); myToast.present(); } else { let myToast = await this.toastCtrl.create({ message: 'There is an unexpected error, please try again later!', duration: 2000, position: 'top', showCloseButton: true, closeButtonText: 'Close' }); myToast.present(); } } registerlink() { this.navCtrl.navigateForward(['register']); } } ``` For `login.page.html` and `login.page.scss` don't have any changes. We can refer directly to Github link to see the code **[here](https://github.com/ianjoseph2204/NTUST_SmartDispenser/tree/master/src/app/pages/auth/login)**. --- ### Finalize the register page Time: **11:30** - Register page now has error control to know if the email address is invalid, according to Regex formula it must at least `ONE_CHAR@DOMAIN_NAME.DOMAIN_ROOT` (for example: test@example.com). - It also applied to password with at least 6 characters with must contains one character and one number. - When entering invalid email address and/or password: <center> <img src="https://raw.githubusercontent.com/aru1702/images/master/ntust-documentation/27-01.JPG" /> </center> #### register.page.ts ```typescript= import { Component } from '@angular/core'; import { DispenserAPIService } from '../../../services/DispenserAPI/dispenser-api.service'; import { NavController, ToastController } from '@ionic/angular'; @Component({ selector: 'app-register', templateUrl: './register.page.html', styleUrls: ['./register.page.scss'], }) export class RegisterPage { email : string = ""; password : string = ""; repassword : string = ""; constructor( private navCtrl: NavController, private api: DispenserAPIService, private toastCtrl: ToastController ) { } emailFalse = false; checkEmail (email) { let regexString = '[^@]+@[^\.\..+]+'; let reg = new RegExp(regexString); if (reg.test(email)) this.emailFalse = false; else this.emailFalse = true; console.log("Email: " + this.emailFalse); } passwordFalse = false; checkPassword (password) { let regexString = '^(?=.*[0-9]+.*)(?=.*[a-zA-Z]+.*)[0-9a-zA-Z]{6,}$'; let reg = new RegExp(regexString); if (reg.test(password)) this.passwordFalse = false; else this.passwordFalse = true; console.log("Pass: " + this.passwordFalse); } async signUp () { const { email, password, repassword } = this; let resultData: any; if (!this.emailFalse && !this.passwordFalse) { resultData = await this.api.registerNewUser(email, password, repassword); } else { resultData = { 'RespondNum': 0, 'Message': "Please enter valid email address or password!" }; } if (resultData['RepsondNum'] === 1) { this.navCtrl.navigateForward(['dashboard']); } let myToast = await this.toastCtrl.create({ message: resultData['Message'], duration: 2000, position: 'top', showCloseButton: true, closeButtonText: 'Close' }); myToast.present(); } } ``` #### register.page.html ```htmlmixed= <!DOCTYPE html> <head> <title>ACUO | Register Page</title> </head> <ion-content class="i-theme1"> <div class="header"> <img class="img-header" src="assets/acuo-icons/rectangle_2@3x.png" alt="acuo-icons"> <h3>Register and have your access to our smart dispenser!</h3> </div> <div class="section"> <div> <ion-item> <ion-label position="floating">Email Address</ion-label> <ion-input type="email" [(ngModel)]="email" (change)=checkEmail(email)></ion-input> <p *ngIf="emailFalse" class="falseInput">Email is invalid!</p> </ion-item> <ion-item> <ion-label position="floating">Password</ion-label> <ion-input type="password" [(ngModel)]="password" (change)=checkPassword(password)></ion-input> <p *ngIf="passwordFalse" class="falseInput">Password must minimum 6 character with at least contains 1 alphabet and 1 number!</p> </ion-item> <ion-item> <ion-label position="floating">Re-enter Password</ion-label> <ion-input type="password" [(ngModel)]="repassword"></ion-input> </ion-item> </div> <p style="text-align: center"> By clicking Sign Up, you agree to our Terms, Data Policy and Cookie Policy. You will receieve verification email in you mailbox in order to verify your account. </p> <div class="btn-yes"> <ion-button class="i-btn-yes" size="small" fill="solid" expand="block" (click)="signUp()">Sign up</ion-button> </div> </div> </ion-content> ``` #### register.page.scss On `scss` add only one class: ```css= .falseInput { color: #ff0000; size: 12px } ``` --- ### Finalize the Nearby Dispenser page Time: **14:33** - Nearby dispenser page no longer has session system because it's not necessary. - New display: <center> <img src="https://raw.githubusercontent.com/aru1702/images/master/ntust-documentation/27-02.JPG" /> </center> <br> - Device id get from dashboard, not from input or any source: ```typescript= selectedDeviceId; async main () { this.selectedDeviceId = await this.pref.getData(StaticVariable.KEY__DEVICE_ID); } ``` - Fix some HTML code to get better display, also call picture API to **use as background image** for every cards contain nearby dispenser. ```htmlmixed= <ion-card *ngFor="let item of nearbyNextBuilding" > <div class="body-content--card" [style.backgroundImage]="'url(' + item.Picture + ')'"> // the rest of code </div> </ion-card> ``` - Some css class has changed due to get better display. --- ### Changes in Dispenser API service - This change because on Maintenance Progress page need timestamp for every steps. ```typescript= /** * This function is to get the repair condition of the target * dispenser from the API. It contains the problem that still * under maintenance until it being complete. It returns * the json format. * * @param device_id The device ID of target dispenser * * @returns value The json object of data * * @example * * [ * { * "Device_ID": "MA_05_01", * "Email": "ntust.smartcampus@gmail.com", * "ErrorType": 5, * "Description": "Broken", * "Status": 4, * "UploadTime": "2019-01-02 09:36:00", * "NotifyTime": "2019-01-02 09:36:00", * "Maintainer": "Mr.Pang", * "Result": "Someone push powersaving button", * "CompleteTime": "2019-01-02 24:00:00", * "Index": 0, * "Source": null, * "Source2": null, * "Source3": null * }, * { * "Device_ID": "T4_04_01", * "Email": "ntust.smartcampus@gmail.com", * "ErrorType": 3, * "Description": "Leaking water", * "Status": 4, * "UploadTime": "2019-01-02 20:16:00", * "NotifyTime": "2019-01-02 20:16:00", * "Maintainer": "Mr.Pang", * "Result": "Fan and Compressor are broken", * "CompleteTime": "2019-01-02 24:00:00", * "Index": 0, * "Source": null, * "Source2": null, * "Source3": null * }, * ... * ] */ async getDispenserRepairCondition (device_id: string) { let url = this.urlDispenserRepairCondition + device_id; let returnValue = [{}]; await this.http.get(url).toPromise() .then((result) => { returnValue = result['Data']; }, () => { console.error("Promise rejected: unable to get dispenser repair condition!"); }) .catch((e) => { console.error("Function error: on getDispenserRepairCondition => " + e); }); return returnValue; } ``` --- ## Conclusion - Finalize code for authentication pages: Login page and Register page - Finalize code for Nearby Dispenser page. - Get some API changes from Johnny for maintenance progress problem that needs timestamp for every steps. - Maintenance Progress page still in progress because of API changes and new idea to display the data, this will finish tomorrow. --- Time: **18:10** Event: Leaving the lab ###### tags: `on-intern`