Skip to content

Commit

Permalink
Added User profile features (#227)
Browse files Browse the repository at this point in the history
Why ?

Features

Email update
Add/Edit shipping address
Profile Password change
This change addresses the need by:

Now user able to see above mention features in his/her profile.
User can change his/her own password, update email address & edit the shipping/delivery address if already exist or can add new one.

[delivers #158933531]
  • Loading branch information
gopalshimpi authored and pkrawat1 committed Aug 9, 2018
1 parent d790555 commit 1778cdd
Show file tree
Hide file tree
Showing 33 changed files with 729 additions and 39 deletions.
10 changes: 5 additions & 5 deletions src/app/checkout/address/add-address/add-address.component.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { getAuthStatus } from './../../../auth/reducers/selectors';
import { AppState } from './../../../interfaces';
import { Store } from '@ngrx/store';
import { AuthActions } from './../../../auth/actions/auth.actions';
import { AddressService } from './../services/address.service';
import { CheckoutService } from './../../../core/services/checkout.service';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { Component, OnInit, OnDestroy, Input, Output, EventEmitter } from '@angular/core';
import { ToastrService } from 'ngx-toastr';
import { AddressService } from '../services/address.service';
import { AuthActions } from '../../../auth/actions/auth.actions';
import { getAuthStatus } from '../../../auth/reducers/selectors';
import { CheckoutService } from '../../../core/services/checkout.service';
import { AppState } from '../../../interfaces';

@Component({
selector: 'app-add-address',
Expand Down
26 changes: 13 additions & 13 deletions src/app/checkout/address/services/address.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,18 @@ export class AddressService {
return this.http.get<any>(`api/v1/countries/105/states`)
}

updateAddress(updatedAddress, addressId,orderNumber){
const url = `api/v1/orders/${orderNumber}/addresses/${addressId}?`
+`address[firstname]=${updatedAddress.firstname}`
+`&address[lastname]=${updatedAddress.lastname}`
+`&address[address1]=${updatedAddress.address1}`
+`&address[address2]=${updatedAddress.address2}`
+`&address[city]=${updatedAddress.city}`
+`&address[state_name]=${updatedAddress.state_name}`
+`&address[phone]=${updatedAddress.phone}`
+`&address[zipcode]=${updatedAddress.zipcode}`
+`&address[state_id]=${updatedAddress.state_id}`
+`&address[country_id]=${updatedAddress.country_id}`
return this.http.put(url, {})
updateAddress(updatedAddress, addressId, orderNumber) {
const url = `api/v1/orders/${orderNumber}/addresses/${addressId}?`
+ `address[firstname]=${updatedAddress.firstname}`
+ `&address[lastname]=${updatedAddress.lastname}`
+ `&address[address1]=${updatedAddress.address1}`
+ `&address[address2]=${updatedAddress.address2}`
+ `&address[city]=${updatedAddress.city}`
+ `&address[state_name]=${updatedAddress.state_name}`
+ `&address[phone]=${updatedAddress.phone}`
+ `&address[zipcode]=${updatedAddress.zipcode}`
+ `&address[state_id]=${updatedAddress.state_id}`
+ `&address[country_id]=${updatedAddress.country_id}`
return this.http.put(url, {})
}
}
2 changes: 1 addition & 1 deletion src/app/checkout/order-failed/order-failed.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<div class="row">
<div class="col-12 col-sm-9">
<h1>Payment Failed</h1>
<h5 *ngIf=errorReason>Reason: {{errorReason}}</h5>
<h5 *ngIf="errorReason">Reason: {{errorReason}}</h5>
<div class="float-left close-btn">
<i class="fa fa-close"></i>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
[ngClass]="[isScrolled ? '':'notscrolled']" role="menu" aria-labelledby="button-triggers-manual">
<ul>
<li role="menuitem">
<a class="dropdown-item" routerLink="/user">My Profile</a>
<a class="dropdown-item" routerLink="/user/profile">My Profile</a>
</li>
<li class="divider dropdown-divider"></li>

Expand Down Expand Up @@ -62,7 +62,7 @@
</button>
<ul id="dropdown-split" *dropdownMenu class="dropdown-menu mobile-profile" role="menu" aria-labelledby="button-split">
<li role="menuitem">
<a class="dropdown-item" routerLink="/user">My Profile</a>
<a class="dropdown-item" routerLink="/user/profile">My Profile</a>
</li>
<li class="divider dropdown-divider"></li>

Expand All @@ -73,11 +73,6 @@
<li role="menuitem">
<a class="dropdown-item" routerLink="/user/addresses">Saved Addresses</a>
</li>
<li class="divider dropdown-divider"></li>
<li role="menuitem">
<a class="dropdown-item" href="#">Edit Profile</a>
</li>

<li class="divider dropdown-divider"></li>
<li role="menuitem">
<a class="dropdown-item" (click)="logout()">Logout</a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ <h1 itemprop="name" class="title">{{product.name}}</h1>
<div class="col-12">
<div class="row m-0">
<div class="product-subtitle col-5 p-0">
<a [routerLink]="['search']" [queryParams]="{'q[name_cont]': brand.name, id: brand.id}" *ngIf="brand">
<a [routerLink]="['/search']" [queryParams]="{'q[name_cont]': brand.name, id: brand.id}" *ngIf="brand">
<span>By </span>
{{brand.name}}
</a>
Expand Down
19 changes: 19 additions & 0 deletions src/app/shared/custom-validator/password-match-validator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { FormGroup } from '@angular/forms';

export class PasswordMatchValidator {
static validate(passwordFormGroup: FormGroup) {
const password = passwordFormGroup.controls.password.value;
const repeatPassword = passwordFormGroup.controls.password_confirmation.value;

if (repeatPassword.length <= 0) {
return null;
}

if (repeatPassword !== password) {
return {
doesMatchPassword: true
};
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<form class="form" [formGroup]="addressForm" (ngSubmit)="onSubmit()">
<div class="row">
<div class="form-group col-sm-6">
<label>Pin Code
<span class="required">*</span>
</label>
<input type="tel" class="form-control" formControlName="zipcode">
<p *ngIf="addressForm.get('zipcode').hasError('required') && addressForm.get('zipcode').touched" class="value-err text-danger show">This is a mandatory field</p>
</div>
<div class="form-group col-sm-6">
<label> Locality / Town
<span class="required">*</span>
</label>
<input type="text" class="form-control" formControlName="address2">
<p *ngIf="addressForm.get('address2').hasError('required') && addressForm.get('address2').touched" class="value-err text-danger show">This is a mandatory field</p>
</div>
<div class="form-group col-sm-6">
<label>City / District
<span class="required">*</span>
</label>
<input type="text" class="form-control" formControlName="city">
<p *ngIf="addressForm.get('city').hasError('required') && addressForm.get('city').touched" class="value-err text-danger show">This is a mandatory field</p>
</div>
<div class="form-group col-sm-6">
<label> State </label>
<select class="form-control" formControlName="state_name">
<option *ngIf="addressParams">{{addressParams.user.ship_address.state.name}}
<option *ngFor="let state of states">{{state.name}}</option>
</select>
</div>

<div class="form-group col-sm-6">
<label>First Name
<span class="required">*</span>
</label>
<input type="text" class="form-control" formControlName="firstname">
<p *ngIf="addressForm.get('firstname').hasError('required') && addressForm.get('firstname').touched" class="value-err text-danger show">This is a mandatory field</p>
</div>
<div class="form-group col-sm-6">
<label> Last Name
<span class="required">*</span>
</label>
<input type="text" class="form-control" formControlName="lastname">
<p *ngIf="addressForm.get('lastname').hasError('required') && addressForm.get('lastname').touched" class="value- text-danger show">This is a mandatory field</p>
</div>

<div class="form-group col-sm-6">
<label>Address
<span class="required">*</span>
</label>
<textarea type="text" class="form-control" formControlName="address1"></textarea>
<p *ngIf="addressForm.get('address1').hasError('required') && addressForm.get('address1').touched" class="value-err text-danger show">This is a mandatory field</p>
</div>
<div class="form-group col-sm-6">
<label>Mobile No
<span class="required">*</span>
</label>
<input type="tel" class="form-control" formControlName="phone">
<p *ngIf="addressForm.get('phone').hasError('required') && addressForm.get('phone').touched" class="value-err text-danger show">This is a mandatory field</p>
</div>
<div class="save-button col-12 col-sm-6">
<button class="btn themebtnprimary">SAVE</button>
</div>
</div>
</form>
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// @import './../../shared/scss/selected_theme_variables';
// .form {
// .half-width {
// width: 190px;
// }
// .full-width {
// width: 400px;
// }
// .value-err {
// height: 18px;
// padding-top: 2px;
// }
// .readonly {
// border: 1px solid $gray-10 !important;
// }
// }

// .email {
// padding-bottom: 10px;
// padding-top: 15px;
// label {
// top: 4px;
// }
// }

// .pincode {
// padding-top: 15px;
// label {
// top: 4px;
// }
// }

// .city,
// .state,
// .first-name,
// .last-name {
// display: inline-block;
// vertical-align: top;
// }

// .state,
// .last-name {
// padding-left: 7px;
// }

// .address {
// textarea {
// height: 70px;
// padding: 10px;
// }
// }
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { AddEditAddressComponent } from './add-edit-address.component';

describe('AddEditAddressComponent', () => {
let component: AddEditAddressComponent;
let fixture: ComponentFixture<AddEditAddressComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ AddEditAddressComponent ]
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(AddEditAddressComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { Component, OnInit, Input, EventEmitter, Output } from '@angular/core';
import { FormGroup, FormBuilder } from '@angular/forms';
import { AddressService } from '../../../../checkout/address/services/address.service';
import { ToastrService } from 'ngx-toastr';
import { UserService } from '../../../services/user.service';

@Component({
selector: 'app-add-edit-address',
templateUrl: './add-edit-address.component.html',
styleUrls: ['./add-edit-address.component.scss']
})
export class AddEditAddressComponent implements OnInit {
addressForm: FormGroup;
states: any;
@Input() isEditAddrPressed: boolean;
@Input() addressParams: any;
@Output() isAddressEdited: EventEmitter<boolean> = new EventEmitter<boolean>();

constructor(private fb: FormBuilder,
private addrService: AddressService,
private toastrService: ToastrService,
private userService: UserService,
) {
this.addressForm = addrService.initAddressForm();

this.addrService.getAllStates().subscribe(data => {
this.states = data.states;
});
}

ngOnInit() {
if (this.isEditAddrPressed) {
this.fillAddress(this.addressForm);
}
}

onSubmit() {
const address = this.addressForm.value;
for (const state of this.states) {
if (state.name === address.state_name) {
address['state_id'] = state.id;
address['country_id'] = state.country_id;
address['state_name'] = state.name;
break;
}
}
if (this.addressForm.valid) {
if (this.isEditAddrPressed) {
this.addressParams.user.ship_address = address;
this.userService.updateUserAddress(this.addressParams)
.subscribe((res: any) => {
this.navigatePage();
this.toastrService.success(res.status, 'Success!')
})

} else {
this.addressParams.user.ship_address = address;
this.userService.createUserAddress(this.addressParams)
.subscribe((res: any) => {
this.navigatePage();
this.toastrService.success(res.status, 'Success!')
})
}
} else {
this.toastrService.error('Some fields are blank!', 'Unable to save address!');
}
}

fillAddress(addressForm) {
const existingAddress = this.addressParams.user.ship_address;
addressForm.get('zipcode').setValue(existingAddress.zipcode);
addressForm.get('address2').setValue(existingAddress.address2);
addressForm.get('city').setValue(existingAddress.city);
addressForm.get('state_name').setValue(existingAddress.state.name);
addressForm.get('firstname').setValue(existingAddress.firstname);
addressForm.get('lastname').setValue(existingAddress.lastname);
addressForm.get('address1').setValue(existingAddress.address1);
addressForm.get('phone').setValue(existingAddress.phone);
}
navigatePage() {
this.isAddressEdited.emit(true)
}
}
20 changes: 17 additions & 3 deletions src/app/user/components/addresses/addresses.component.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
<p>
addresses works!
</p>
<div *ngIf="userDetails$ | async; let userDetails">
<div *ngIf="userDetails.ship_address!=null">
<span *ngIf="!isEditAddrPressed; else elseBlock" class='reviewlink pl-1' (click)="editAddress()">Edit</span>
<ng-template #elseBlock>
<span class='reviewlink pl-1' (click)="cancelAddressEdit()">Cancel</span>
</ng-template>
<app-saved-address *ngIf="!isEditAddrPressed" [userDetails]="userDetails"></app-saved-address>
<div *ngIf="isEditAddrPressed">
<strong>Edit Address</strong>
<app-add-edit-address [isEditAddrPressed]="isEditAddrPressed" [addressParams]="buildAddressParams(userDetails)" (isAddressEdited)="addressEditedDone($event)"></app-add-edit-address>
</div>
</div>
<div *ngIf="userDetails?.ship_address===null">
<strong>Add Address</strong>
<app-add-edit-address [isEditAddrPressed]="false" (isAddressEdited)="addressEditedDone($event)" [addressParams]="buildAddressParams(userDetails)"></app-add-edit-address>
</div>
</div>
6 changes: 6 additions & 0 deletions src/app/user/components/addresses/addresses.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.reviewlink {
cursor: pointer;
&:hover {
text-decoration: underline
}
}
Loading

0 comments on commit 1778cdd

Please sign in to comment.