diff --git a/cypress/integration/returning-user.spec.js b/cypress/integration/returning-user.spec.js new file mode 100644 index 0000000..7f64c9b --- /dev/null +++ b/cypress/integration/returning-user.spec.js @@ -0,0 +1,45 @@ +import { createYield } from "typescript" + +context('go back to home after opening return user', () => { + it("will go back to the homepage", () => { + cy.visit("localhost:8100/returning-user") + + cy.contains('Cancel').click() + cy.url().should('be', 'localhost:8100/home') + }) +}) + +context('sign in for for returning users', ()=> { + it("exsisting user is found", ()=> { + cy.visit('localhost:8100/returning-user'); + cy.get('[data-test="return-user-phone-input"]') + .type('3035551212') + .should("have.value", "3035551212"); + + cy.get('[data-test="return-user-email-input"]') + .type('dave@dave.com') + .should('have.value', 'ethan@ethan.com'); + + cy.contains('Find Me').click() + + cy.get('.alert-wrapper').should("be.visible").contains("Found you") + }) +}) + +context("user not in the system", () =>{ + it("shows user not found would you like to sign up?", ()=> { + cy.visit("localhost:8100/returning-user") + + cy.get('[data-test="return-user-phone-input"]') + .type("78945645123") + .should('have.value', '78945645123') + + cy.get('[data-test="return-user-email-input"]') + .type("fake@fake.com") + .should("have.value", "fake@fake.com") + + cy.contains("Find Me").click() + + cy.get('.alert-wrapper').should("be.visible").contains("couldn't find a profile") + }) +}) diff --git a/src/app/_services/user.service.ts b/src/app/_services/user.service.ts index ac20050..54a4767 100644 --- a/src/app/_services/user.service.ts +++ b/src/app/_services/user.service.ts @@ -66,7 +66,7 @@ export class UserService { } getUserByEmailOrPhone(query) { - let url = environment.apiUrl + "/api/user?q=" + query; + let url = environment.apiUrl + "/api/user?q=" + query; let rtn = new Promise( (resolve, reject) => { diff --git a/src/app/returning-user/country-phone.model.ts b/src/app/returning-user/country-phone.model.ts new file mode 100644 index 0000000..00c6549 --- /dev/null +++ b/src/app/returning-user/country-phone.model.ts @@ -0,0 +1,33 @@ +import libphonenumber from 'google-libphonenumber'; + +export class CountryPhone { + iso: string; + name: string; + code: string; + sample_phone: string; + + constructor (iso: string, name: string) { + this.iso = iso; + this.name = name; + + let phoneUtil = libphonenumber.PhoneNumberUtil.getInstance(), + PNF = libphonenumber.PhoneNumberFormat, + PNT = libphonenumber.PhoneNumberType, + country_example_number = phoneUtil.getExampleNumberForType(this.iso, PNT.MOBILE), + // We need to define what kind of country phone number type we are going to use as a mask. + // You can choose between many types including: + // - FIXED_LINE + // - MOBILE + // - For more types please refer to google libphonenumber repo (https://github.com/googlei18n/libphonenumber/blob/f9e9424769964ce1970c6ed2bd60b25b976dfe6f/javascript/i18n/phonenumbers/phonenumberutil.js#L913) + example_number_formatted = phoneUtil.format(country_example_number, PNF.NATIONAL); + // We need to define how are we going to format the phone number + // You can choose between many formats including: + // - NATIONAL + // - INTERNATIONAL + // - E164 + // - RFC3966 + + this.sample_phone = example_number_formatted; + this.code = "+" + country_example_number.getCountryCode(); + } +} diff --git a/src/app/returning-user/returning-user.page.html b/src/app/returning-user/returning-user.page.html index 29de73e..1d385c7 100644 --- a/src/app/returning-user/returning-user.page.html +++ b/src/app/returning-user/returning-user.page.html @@ -14,13 +14,20 @@ In the DTIM, our goal is to help you prepare for your next big tech interview.

- - Phone (only digits, no symbols) or Email - - +
+ + Phone (only digits, no symbols) + + + + + Email + + - Find Me - Cancel + Find Me + Cancel +
\ No newline at end of file diff --git a/src/app/returning-user/returning-user.page.ts b/src/app/returning-user/returning-user.page.ts index cc8a3fc..8375b90 100644 --- a/src/app/returning-user/returning-user.page.ts +++ b/src/app/returning-user/returning-user.page.ts @@ -1,10 +1,15 @@ import { Component, OnInit } from '@angular/core'; +import { Validators, FormControl, FormGroup, FormBuilder } from '@angular/forms'; import { Router, ActivatedRoute, ParamMap } from '@angular/router'; import { Location } from '@angular/common'; import { AlertService } from '../_services/alert.service'; import { UserService } from '../_services/user.service'; +import { CountryPhone } from './country-phone.model'; +import { PhoneValidator } from '../validators/phone.validator'; + + @Component({ selector: 'app-returning-user', templateUrl: './returning-user.page.html', @@ -12,44 +17,124 @@ import { UserService } from '../_services/user.service'; }) export class ReturningUserPage implements OnInit { - query = undefined; + query = { + phone: undefined, + email: undefined + } + + validations_form: FormGroup; + country_phone_group: FormGroup; + countries: Array; constructor(private _location: Location, private _router: Router, private _route: ActivatedRoute, private _userService: UserService, - private _alertService: AlertService ) { + private _alertService: AlertService, + private formBuilder: FormBuilder ) { - } + } + + validation_messages = { + 'name': [ + { type: 'required', message: 'Name is required.' } + ], + 'email': [ + { type: 'required', message: 'Email is required.' }, + { type: 'pattern', message: 'Please enter a valid email, OR a ten digit phone number.' } + ], + 'phone': [ + { type: 'required', message: 'Phone is required.' }, + { type: 'validCountryPhone', message: 'Please enter a ten digit phone number, OR a valid email.' } + ] + }; ngOnInit() { - + this.countries = [ + new CountryPhone('US', 'United States') + ]; + + let country = new FormControl(this.countries[0], Validators.required); + let phone = new FormControl('', Validators.compose([ + PhoneValidator.validCountryPhone(country) + ])); + this.country_phone_group = new FormGroup({ + country: country, + phone: phone + }); + + this.validations_form = this.formBuilder.group({ + name: new FormControl('', Validators.required), + email: new FormControl('', Validators.compose([ + Validators.pattern('^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9]+([\.]{1})([a-zA-Z0-9]{2,3})$') + ])), + country_phone: this.country_phone_group + }, + { + updateOn: "blur" + } + ); + } + + getErrorMessages() { + if((this.validations_form.controls.email.status === "VALID" && /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9]+([\.]{1})([a-zA-Z0-9]{2,3})$/.test(this.validations_form.controls.email.value)) && (this.validations_form.controls.country_phone.status === "VALID" && this.validations_form.controls.country_phone.value.phone.length === 10)) { + console.log('valid email and phone') + this.validation_messages.phone[1] = { type: 'validCountryPhone', message: 'You have entered a valid email address. Please clear this field OR provide a 10 digit phone number.' }; + this.validation_messages.email[1] = { type: 'pattern', message: 'You have entered a valid phone number. Please clear this field OR provide a valid email.' }; + } else if ((this.validations_form.controls.country_phone.status === "VALID" && this.validations_form.controls.country_phone.value.phone.toString().length === 10)) { + this.validation_messages.email[1] = { type: 'pattern', message: 'You have entered a valid phone number. Please clear this field OR provide a valid email.' }; + this.validation_messages.phone[1] = { type: 'validCountryPhone', message: 'Please enter a ten digit phone number, OR a valid email.' }; + } else if ((this.validations_form.controls.email.status === "VALID" && /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9]+([\.]{1})([a-zA-Z0-9]{2,3})$/.test(this.validations_form.controls.email.value))) { + console.log('valid email') + this.validation_messages.phone[1] = { type: 'validCountryPhone', message: 'You have entered a valid email address. Please clear this field OR provide a 10 digit phone number.' }; + this.validation_messages.email[1] = { type: 'pattern', message: 'Please enter a valid email, OR a ten digit phone number.' }; + } else if ((this.validations_form.controls.email.status === "VALID" && !(/^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9]+([\.]{1})([a-zA-Z0-9]{2,3})$/.test(this.validations_form.controls.email.value)))) { + console.log('invalid email with valid status'); + this.validation_messages.phone[1] = { type: 'validCountryPhone', message: 'Please enter a ten digit phone number, OR a valid email.' }; + this.validation_messages.email[1] = { type: 'pattern', message: 'Please enter a valid email, OR a ten digit phone number.' }; + } else { + this.validation_messages.phone[1] = { type: 'validCountryPhone', message: 'Please enter a ten digit phone number, OR a valid email.' }; + this.validation_messages.email[1] = { type: 'pattern', message: 'Please enter a valid email, OR a ten digit phone number.' }; + } } + + onQueryChange($event) { - this.query = $event.currentTarget.value; + if ($event.currentTarget.id == "phone") { + this.query.phone = $event.currentTarget.value + } else if($event.currentTarget.id == "email") { + this.query.email = $event.currentTarget.value + } } - getQuery() { - return this.query; + getQuery(value) { + if (value == 'phone') { + return this.query.phone; + } else if(value == "email") { + return this.query.email + } } isSearchBtnEnabled() { - if (this.query) { - if (!isNaN(this.query.charAt(0) * 1)) { // if the first char is a number - return this.query.length === 10 && !isNaN(this.query); - } else { - return this.query.length >= 3; - } + if (this.query.email || this.query.phone){ + return true + } else { + return false } - - return this.query && this.query.length >= 3; } onSearchBtnClicked() { let self = this; + let data = undefined; + + if (self.query.email) { + data = self.query.email + } else { + data = self.query.phone + } - self._userService.getUserByEmailOrPhone(self.query).then((user) => { + self._userService.getUserByEmailOrPhone(data).then((user) => { if (user) { self._userService.markUserAsAttending(user["id"]).then(() => {