# 8th August Report
## Progress
Time: **09:00**
Event: Entering the lab
---
### Build register page and use the API for repairman registration
Time: **10:49**
- In here we defined the variable in Typescript in order to get the value from HTML, in **register.page.ts**:
```typescript=
// form attributes
fullname = "";
employee_id = "";
email = "";
password = "";
re_password = "";
// image upload attributes
urlImage: any;
fileImage: any = null;
alreadyUpload = false;
```
- Form attributes means variables use to store value from `ion-input` or from the form.
- Image attributes means variables use to store data from image uploaded, on alreadyUpload is identification to determine is the image already upload or not.
- In front end code, HTML and SCSS, we put these form attributes into each `ion-input` as `[(ngModel)]` so the data can be read in back end code, TS.
- We also edit some stylesheet (SCSS) attributes to make the display more comfortable.
- In **register.page.html**:
```htmlmixed=
...
<ion-content class="i-theme1">
...
<div class="section">
<div class="section-inside">
<ion-item lines="none">
<div class="image-upload center">
<h6>Profile Picture</h6>
<label for="file-input">
<!-- Icon by https://www.flaticon.com/authors/iconnice -->
<img
*ngIf="!alreadyUpload"
src="/assets/upload-image/profile-empty.png"
class="image-upload--uploadPhoto before" />
<img
*ngIf="alreadyUpload"
[src]="urlImage"
class="image-upload--uploadPhoto">
</label>
<input id="file-input" accept="image/*" type="file" (change)="onFileSelect($event)" />
</div>
</ion-item>
<ion-item>
<ion-label position="floating">Full Name</ion-label>
<ion-input required type="text" [(ngModel)]="fullname"></ion-input>
</ion-item>
<ion-item>
<ion-label position="floating">Employee ID</ion-label>
<ion-input type="text" [(ngModel)]="employee_id"></ion-input>
</ion-item>
<ion-item>
<ion-label position="floating">Company Email Address</ion-label>
<ion-input type="email" [(ngModel)]="email" (change)=checkEmail(email)></ion-input>
<p *ngIf="emailFalse" class="falseInput">Email is invalid or must be company domain!</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)]="re_password"></ion-input>
</ion-item>
...
</div>
</div>
</ion-content>
```
- Profile picture moves to above of the form, it will shows blank person image if not upload any photo.
- Each of form has `[(ngModel)]` to pass the value into variable inside the back end code (TS).
- On Email and Password form, it has `*ngIf` to check if the input is valid or not, we will not explain this now.
---
- In **register.page.scss**:
```css=
...
.image-upload {
margin: 5px;
}
.image-upload>input {
display: none;
}
.image-upload--uploadPhoto {
display: block;
max-height: 100px;
border-radius: 50%;
}
.before {
opacity: 0.5;
}
...
```
- We add some attributes to make the display more look nice and comfortable.
- The rest of code can be check on our Github repository for Repairman App.
- We have settled the front end components now we build the back end code for function to create the repairman account using the API, of course we will using the Dispenser API service as our handler.
- In **register.page.ts**
```typescript=
import { NavController, AlertController } from '@ionic/angular';
import { DispenserAPIService } from 'src/app/services/DispenserAPI/dispenser-api.service';
export class RegisterPage implements OnInit {
constructor(
private NavCtrl: NavController,
private AlertCtrl: AlertController,
private api: DispenserAPIService
) { }
ngOnInit() {
}
backFunc () {
this.NavCtrl.back();
}
async onFileSelect(event: any) {
if (event.target.files[0].size <= 10485760) {
// Check image length, image cannot empty
if (event.target.files.length > 0) {
this.fileImage = event.target.files[0];
var reader = new FileReader();
// Read file as data url
reader.readAsDataURL(event.target.files[0]);
// Called once readAsDataURL is completed
reader.onload = async () => {
this.urlImage = reader.result;
}
this.alreadyUpload = true;
}
} else {
// Send message if data is to big
const toBig = await this.AlertCtrl.create({
mode: "ios",
header: 'File Size is to Big',
message: 'Please upload file below 10 Mb!',
buttons: [
{
text: 'OK',
handler: () => {
}
}
]
});
toBig.present();
}
}
async signUp() {
// create variable to store alertCtrl
let alert: any;
let alertHeader: string;
let alertMessage: string;
// Check if any input is empty
if (
this.fullname === "" ||
this.employee_id === "" ||
this.email === "" ||
this.password === "" ||
this.re_password === "" ||
this.urlImage === null ||
this.urlImage === undefined
) {
alertHeader = "Form not complete";
alertMessage = "Please fill all form input include upload profile picture!";
} else {
// remove "data:image/jpeg;base64," from url
let splitUrlImage = this.urlImage.split("base64,");
let profile_picture = splitUrlImage[1];
// Send data from API
let register = await this.api.registerRepairman(
this.fullname,
this.email,
this.password,
this.re_password,
this.employee_id,
profile_picture
);
if (register['RepsondNum'] === 1) {
alertHeader = "Registration complete"
alertMessage = "Thank you, your registration form has been submitted!";
} else {
alertHeader = "Registration failed"
alertMessage = register['Message'];
}
}
// make alert object
alert = await this.AlertCtrl.create({
mode: "ios",
header: alertHeader,
message: alertMessage,
buttons: [
{
text: 'OK',
handler: () => { }
}
]
});
// display the alert
alert.present();
}
}
```
- On line 19, `onFileSelect(event)` is for storing the image which uploaded from `event` variable into both **fileImage** as file and **urlImage** as base64 URL.
- On line 59, `signUp()` is for registration, after the repairman click the "Sign Up" button, by getting data from all form attributes and pass using Dispenser API service to do registration.
- Above function also check if all form attributes include profile picture is filled or not, otherwise it will not send data to API.
- Dispenser API service will return two values: **RespondNum** and **Message** to inform the result of API, the Message will displayed using AlertController.
- Result on the page:
<center>
<img src="https://raw.githubusercontent.com/aru1702/images/master/ntust-documentation/42-01.JPG" style="max-width: 250px" />
</center>
<br>
- After **Sign Up** button clicked:
<center>
<img src="https://raw.githubusercontent.com/aru1702/images/master/ntust-documentation/42-02.JPG" style="max-width: 250px" />
</center>
<br>
- Registration data successfully inputed into the database, have checked using Robo3T.
- The picture in base64 also stored.
---
### Forgot Password page
Time: **14:51**
- Forgot password is feature which allow the repairman to reset his account password once he lost or forgot about it.
- Forgot password page UI design hasn't created yet so it must be designed first.
- In **forgot-password.page.html**
```htmlmixed=
<ion-content class="i-theme1">
<div class="icon-cancel">
<img src="assets/cancel/rectangle@3x.png" alt="cancel" (click)="backFunc()">
</div>
<div class="header">
<img
class="img-header"
src="assets/acuo-icons/rectangle_2@3x.png"
alt="acuo-icons">
</div>
<div class="section">
<div class="section-inside">
<div class="title">
<h2><b>FORGOT<br>PASSWORD</b></h2>
</div>
<ion-item>
<ion-label position="floating">Email Address/Employee ID</ion-label>
<ion-input required type="text" [(ngModel)]="credential"></ion-input>
</ion-item>
<div class="btn-yes">
<ion-button class="i-btn-yes" size="small" fill="solid" expand="block" (click)="continue()">Continue</ion-button>
</div>
</div>
</div>
</ion-content>
```
- In **forgot-password.page.scss**
```css=
.i-theme1 {
--background: #777777;
--color: #000000;
}
.btn-yes {
margin-top: 25px;
}
.i-btn-yes {
--background: #259ed6;
--color: #ffffff;
}
.icon-cancel {
text-align: right;
margin-top: 15px;
margin-right: 15px;
}
.header {
text-align: center;
font-weight: bold;
margin-bottom: 75px;
margin-top: 50px;
}
.img-header {
max-height: 60px;
max-width: 100%;
}
.section-inside {
background: #ffffff;
color: #2c2c2c;
padding: 10px;
}
.section {
border-style: solid;
border-width: 5px;
border-color: #259ed6;
border-radius: 10px;
box-shadow: 0px 0px 15px 2px #aad3e6;
margin: 50px 25px;
padding: 5px;
}
.register {
color: #259ed6;
font-weight: bold;
}
.title {
text-align: center;
margin-bottom: 24px;
border-bottom: solid #00000055 1px
}
```
- In **forgot-password.page.ts**
```typescript=
import { Component, OnInit } from '@angular/core';
import { DispenserAPIService } from 'src/app/services/DispenserAPI/dispenser-api.service';
@Component({
selector: 'app-forgot-password',
templateUrl: './forgot-password.page.html',
styleUrls: ['./forgot-password.page.scss'],
})
export class ForgotPasswordPage implements OnInit {
credential = "";
constructor(
private api: DispenserAPIService
) { }
ngOnInit() {
}
async continue () {
const {credential} = this;
if (credential === "") {
} else {
let resultData: any;
resultData = await this.api.forgotPasswordUsingEmail(credential);
if (resultData === 0) {
resultData = await this.api.forgotPasswordUsingEmployeeId(credential);
}
console.log(resultData);
}
}
}
```
- Result display
<center>
<img src="https://raw.githubusercontent.com/aru1702/images/master/ntust-documentation/42-03.JPG" style="max-width: 250px" />
</center>
<br>
- We now have Forgot Password page for repairman app so whenever our repairman forgot about his access to his account, he can reset his password.
- He can choose either using his email address or employee ID in order to request about reset his account password.
- Testing is success and system sends a verification code to email address, repairman can check to his email to retrieve his code.
- The code itself looks like this:
<center>
<img src="https://raw.githubusercontent.com/aru1702/images/master/ntust-documentation/42-04.JPG" style="max-height: 150px" />
</center>
<br>
- He now can use the code to reset his account password and store the new one.
---
### Reset password page
Time: **16:59**
- Reset password is feature which allow the repairman to reset his account password after he request using Forgot Password page.
- After get the verification code, in here repairman will use it to reset his account password.
- Same as above, reset password page UI design hasn't created yet so it must be designed first.
- In **reset-password.page.html**
```htmlmixed=
<ion-content class="i-theme1">
<div class="icon-cancel">
<img src="assets/cancel/rectangle@3x.png" alt="cancel" (click)="backFunc()">
</div>
<div class="header">
<img
class="img-header"
src="assets/acuo-icons/rectangle_2@3x.png"
alt="acuo-icons">
</div>
<div class="section">
<div class="section-inside">
<div class="title">
<h2><b>RESET<br>PASSWORD</b></h2>
</div>
<ion-item>
<ion-label position="floating">Email Address/Employee ID</ion-label>
<ion-input required type="text" [(ngModel)]="credential"></ion-input>
</ion-item>
<ion-item>
<ion-label position="floating">New Password</ion-label>
<ion-input required type="password" [(ngModel)]="new_password"></ion-input>
</ion-item>
<ion-item>
<ion-label position="floating">Re-Type New Password</ion-label>
<ion-input required type="password" [(ngModel)]="re_new_password"></ion-input>
</ion-item>
<ion-item>
<ion-label position="floating">Verification Code</ion-label>
<ion-input required type="text" [(ngModel)]="verif_code"></ion-input>
</ion-item>
<div class="btn-yes">
<ion-button class="i-btn-yes" size="small" fill="solid" expand="block" (click)="reset()">Reset Password</ion-button>
</div>
</div>
</div>
</ion-content>
```
- In **forgot-password.page.scss**
```css=
.i-theme1 {
--background: #777777;
--color: #000000;
}
.btn-yes {
margin-top: 25px;
}
.icon-cancel {
text-align: right;
margin-top: 15px;
margin-right: 15px;
}
.i-btn-yes {
--background: #259ed6;
--color: #ffffff;
}
.header {
text-align: center;
font-weight: bold;
margin-bottom: 25px;
margin-top: 8px;
}
.img-header {
max-height: 60px;
max-width: 100%;
}
.section-inside {
background: #ffffff;
color: #2c2c2c;
padding: 10px;
}
.section {
border-style: solid;
border-width: 5px;
border-color: #259ed6;
border-radius: 10px;
box-shadow: 0px 0px 15px 2px #aad3e6;
margin-left: 25px;
margin-right: 25px;
padding: 5px;
}
.register {
color: #259ed6;
font-weight: bold;
}
.title {
text-align: center;
margin-bottom: 24px;
border-bottom: solid #00000055 1px
}
```
- In **forgot-password.page.ts**
```typescript=
import { Component, OnInit } from '@angular/core';
import { DispenserAPIService } from 'src/app/services/DispenserAPI/dispenser-api.service';
@Component({
selector: 'app-reset-password',
templateUrl: './reset-password.page.html',
styleUrls: ['./reset-password.page.scss'],
})
export class ResetPasswordPage implements OnInit {
// form attributes
credential = "";
new_password = "";
re_new_password = "";
verif_code = "";
constructor(
private api: DispenserAPIService
) { }
ngOnInit() {
}
async reset () {
const { credential, new_password, re_new_password, verif_code } = this;
if (
credential === "" ||
new_password === "" ||
re_new_password === "" ||
verif_code === ""
) {
} else {
let resultData: any;
resultData = await this.api.resetPasswordUsingEmail(credential, new_password, re_new_password, verif_code);
if (resultData === 0 || resultData === -1)
resultData = await this.api.resetPasswordUsingEmployeeId(credential, new_password, re_new_password, verif_code);
console.log(resultData);
}
}
backFunc () {
}
}
```
- Result display
<center>
<img src="https://raw.githubusercontent.com/aru1702/images/master/ntust-documentation/42-05.JPG" style="max-width: 250px" />
</center>
<br>
- After this, now repairman has success reset his account password with the new one. With this, he can now using his account again using the new password.
- If the repairman doesn't reset the password within 10 minutes then he must request another reset password in Forgot Password page.
- If the repairman not input the right verification code, system will not replace his old password with his new inputed in Reset Password page.
- Also like Register Page, new password and re-type new password form should have the same value, otherwise it will not working.
---
## Conclusion
- Register page for Repairman app has already integrated with the API, now it can send the submission of new repairman registration form.
- Forgot password page for Repairman app has been created, system has been build and can print the return value from Dispenser API service.
- Same as forgot password page, reset password page also has been created and will print the return value from the service.
- Furthermore more feature will be added for Authentication pages so it will more user friendly, like adding the alert or error when mistake has been made.
---
Time: **18:00**
Event: Leaving the lab
###### tags: `on-intern`