This commit is contained in:
geek 2018-05-30 16:44:21 +09:00
parent 1cdd48d873
commit 5c52d679db
16 changed files with 163 additions and 45 deletions

View File

@ -1,4 +1,4 @@
<div class="ui-g">
<div class="ui-g" *ngIf="!member">
<div class="ui-g-12">
<form [formGroup]="modifyPasswordForm" (ngSubmit)="modifyPasswordFormSubmit()">
<table class="login-table">
@ -14,31 +14,34 @@
<input type="password"
id="pw"
autocomplete="off" placeholder="password"
formControlName="pw"
formControlName="password"
required class="ui-inputtext ui-corner-all ui-state-default ui-widget">
</span>
<div *ngIf="formErrors.pw" class="help is-danger">
{{ formErrors.pw }}
<div *ngIf="password.touched && !password.valid" class="ui-message ui-messages-error ui-corner-all">
Invalid password
</div>
</div>
<div class="ui-g-12">
<span class="md-inputfield">
<input type="password"
id="confirmPw"
id="pwConfirm"
autocomplete="off" placeholder="confirm password"
formControlName="confirmPw"
formControlName="pwConfirm"
required class="ui-inputtext ui-corner-all ui-state-default ui-widget">
</span>
<div *ngIf="formErrors.confirmPw" class="help is-danger">
{{ formErrors.confirmPw }}
<div *ngIf="pwConfirm.touched && !pwConfirm.valid" class="ui-message ui-messages-error ui-corner-all">
Not matched password
</div>
</div>
<div class="ui-g-12">
<button type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-icon-left">
<button
[disabled]="!modifyPasswordForm.valid"
type="submit"
class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-icon-left">
<span class="ui-button-icon-left ui-c fa fa-fw ui-icon-person"></span>
<span class="ui-button-text ui-c">Confirm</span>
</button>
<a href="javascript:void(0)" (click)="signin.emit()">Signin</a>
<a style="cursor: pointer" (click)="onSignin()">Signin</a>
</div>
</div>
</div>
@ -48,3 +51,7 @@
</form>
</div>
</div>
<div class="ui-g" *ngIf="!member">
Password Modify Complete
</div>

View File

@ -1,5 +1,6 @@
import { Component, OnInit, Output, EventEmitter, Input } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import {FormGroup, FormBuilder, Validators, FormControl, ValidationErrors, AbstractControl} from '@angular/forms';
import {Member} from '@overflow/commons-typescript/model/member';
@Component({
selector: 'of-member-modify-password',
@ -7,14 +8,14 @@ import { FormGroup, FormBuilder, Validators } from '@angular/forms';
})
export class MemberModifyPasswordComponent implements OnInit {
@Input() token: string;
@Input() member: Member;
@Output() modifyPassword = new EventEmitter<{token: string, password: string, confirmPassword: string}>();
@Output() signin = new EventEmitter();
modifyPasswordForm: FormGroup;
formErrors = {
'pw': '',
'confirmPw': ''
};
password: AbstractControl;
pwConfirm: AbstractControl;
constructor(
private formBuilder: FormBuilder,
@ -26,26 +27,46 @@ export class MemberModifyPasswordComponent implements OnInit {
initForm() {
this.modifyPasswordForm = this.formBuilder.group({
'pw': [
'password': [
'',
[
// Validators.required,
Validators.required,
Validators.pattern('^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{6,}$'),
Validators.minLength(6),
Validators.maxLength(25),
]
],
'confirmPw': [
'pwConfirm': [
'',
[
// Validators.pattern('^(?=.*[0-9])(?=.*[a-zA-Z])([a-zA-Z0-9]+)$'),
// Validators.minLength(6),
// Validators.maxLength(25)
Validators.compose([
Validators.required, this.pwMatchValidator
])
]
]
],
});
this.password = this.modifyPasswordForm.controls['password'];
this.pwConfirm = this.modifyPasswordForm.controls['pwConfirm'];
}
pwMatchValidator(control: FormControl): ValidationErrors {
let pw;
if (control.parent) {
pw = control.parent.controls['password'].value;
}
if (control.value !== pw) {
return { notMatched: true };
}
return null;
}
modifyPasswordFormSubmit() {
const formValue = Object.assign({}, this.modifyPasswordForm.value);
this.modifyPassword.emit({token: this.token, password: formValue.pw, confirmPassword: formValue.confirmPw});
}
onSignin() {
this.signin.emit();
}
}

View File

@ -1,6 +1,6 @@
<div class="ui-g">
<div class="ui-g" *ngIf="!member">
<div class="ui-g-12">
<form [formGroup]="resetPasswordForm" (ngSubmit)="resetPasswordFormSubmit()">
<form [formGroup]="resetPasswordForm" (ngSubmit)="resetPasswordSubmit()">
<table class="login-table">
<tr>
<td>
@ -20,14 +20,16 @@
</div>
<div class="ui-g-12">
<button type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-icon-left">
<button
[disabled]="!resetPasswordForm.valid"
type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-icon-left">
<span class="ui-button-icon-left ui-c fa fa-fw ui-icon-cached"></span>
<span class="ui-button-text ui-c">Reset Password</span>
</button>
<a href="/auth/signin" >Sign In</a>
<a style="cursor: pointer" (click)="onSignin()">Sign In</a>
|
<a href="/auth/signup" >Sign Up</a>
<a style="cursor: pointer" (click)="onSignup()">Sign Up</a>
</div>
</div>
</div>
@ -38,3 +40,6 @@
</div>
</div>
<div class="ui-g" *ngIf="member">
I sent an authentication mail to the mail address you registered. Please check and change your password.
</div>

View File

@ -1,5 +1,16 @@
import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import {FormGroup, FormBuilder, Validators, AbstractControl} from '@angular/forms';
import {
Component,
OnInit,
Output,
EventEmitter, Input
} from '@angular/core';
import {
FormGroup,
FormBuilder,
Validators,
AbstractControl
} from '@angular/forms';
import {Member} from '@overflow/commons-typescript/model/member';
@Component({
selector: 'of-member-reset-password',
@ -7,6 +18,10 @@ import {FormGroup, FormBuilder, Validators, AbstractControl} from '@angular/form
})
export class MemberResetPasswordComponent implements OnInit {
@Output() resetPassword = new EventEmitter<string>();
@Output() signin = new EventEmitter();
@Output() signup = new EventEmitter();
@Input() member: Member;
resetPasswordForm: FormGroup;
email: AbstractControl;
@ -28,8 +43,16 @@ export class MemberResetPasswordComponent implements OnInit {
this.email = this.resetPasswordForm.controls['email'];
}
resetPasswordFormSubmit() {
resetPasswordSubmit() {
const formValue = Object.assign({}, this.resetPasswordForm.value);
this.resetPassword.emit(formValue.email);
}
onSignin() {
this.signin.emit();
}
onSignup() {
this.signup.emit();
}
}

View File

@ -1,6 +1,7 @@
<of-member-modify-password
[token]="token"
(modifyPassword)="modifyPassword($event)"
(signin)="signin"
(signin)="onSignin()"
[member]="member$ | async"
>
</of-member-modify-password>

View File

@ -1,10 +1,10 @@
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import {select, Store} from '@ngrx/store';
import { Observable } from 'rxjs';
import * as MemberEntityStore from '../store/entity/member';
import { MemberModifyPasswordContainerSelector } from '../store';
import { Observable } from 'rxjs';
import { Member } from '@overflow/commons-typescript/model/member';
@Component({
selector: 'of-member-modify-password-container',
@ -14,15 +14,25 @@ export class MemberModifyPasswordContainerComponent implements OnInit {
@Input() token: string;
@Output() signin = new EventEmitter();
member$: Observable<Member>;
pending$: Observable<boolean>;
error$: Observable<any>;
constructor(
private store: Store<any>,
) { }
ngOnInit() {
this.member$ = this.store.pipe(select(MemberModifyPasswordContainerSelector.selectMember));
this.pending$ = this.store.pipe(select(MemberModifyPasswordContainerSelector.selectPending));
this.error$ = this.store.pipe(select(MemberModifyPasswordContainerSelector.selectError));
}
modifyPassword(info: {token: string, password: string, confirmPassword: string}) {
this.store.dispatch(new MemberEntityStore.ModifyPassword(info));
}
onSignin() {
this.signin.emit();
}
}

View File

@ -1,4 +1,7 @@
<of-member-reset-password
(resetPassword)="resetPassword($event)"
(signin)="onSignin()"
(signup)="onSignup()"
[member]="member$ | async"
>
</of-member-reset-password>

View File

@ -1,24 +1,46 @@
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import {
Component, EventEmitter,
OnInit,
Output
} from '@angular/core';
import {select, Store} from '@ngrx/store';
import {RPCClientError} from '@loafer/ng-rpc';
import * as MemberEntityStore from '../store/entity/member';
import { Observable } from 'rxjs';
import { Member } from '@overflow/commons-typescript/model/member';
import { MemberResetPasswordContainerSelector } from '../store';
@Component({
selector: 'of-member-reset-password-container',
templateUrl: './member-reset-password-container.component.html',
})
export class MemberResetPasswordContainerComponent implements OnInit {
@Output() signin = new EventEmitter();
@Output() signup = new EventEmitter();
member$: Observable<Member>;
pending$: Observable<boolean>;
error$: Observable<any>;
constructor(
private store: Store<any>,
) { }
ngOnInit() {
this.member$ = this.store.pipe(select(MemberResetPasswordContainerSelector.selectMember));
this.pending$ = this.store.pipe(select(MemberResetPasswordContainerSelector.selectPending));
this.error$ = this.store.pipe(select(MemberResetPasswordContainerSelector.selectError));
}
resetPassword(email: string) {
this.store.dispatch(new MemberEntityStore.ResetPassword(email));
}
onSignin() {
this.signin.emit();
}
onSignup() {
this.signup.emit();
}
}

View File

@ -12,6 +12,7 @@ export function reducer(state = initialState, action: Actions): State {
switch (action.type) {
case ActionType.ModifyPassword: {
return {
member: null,
pending: true,
error: null,
};
@ -19,6 +20,7 @@ export function reducer(state = initialState, action: Actions): State {
case ActionType.ModifyPasswordSuccess: {
return {
member: action.payload,
pending: false,
error: null,
};
@ -26,6 +28,7 @@ export function reducer(state = initialState, action: Actions): State {
case ActionType.ModifyPasswordFailure: {
return {
member: null,
pending: false,
error: action.payload,
};

View File

@ -5,11 +5,13 @@ import { RESTClientError } from '@loafer/ng-rest';
import { Member } from '@overflow/commons-typescript/model/member';
export interface State {
member: Member;
pending: boolean;
error: RESTClientError;
}
export const initialState: State = {
member: null,
pending: false,
error: null,
};
@ -17,6 +19,7 @@ export const initialState: State = {
export function getSelectors(selector: Selector<any, State>) {
return {
selectMember: createSelector(selector, (state: State) => state.member),
selectPending: createSelector(selector, (state: State) => state.pending),
selectError: createSelector(selector, (state: State) => state.error),
};

View File

@ -12,6 +12,7 @@ export function reducer(state = initialState, action: Actions): State {
switch (action.type) {
case ActionType.ResetPassword: {
return {
member: null,
pending: true,
error: null,
};
@ -19,6 +20,7 @@ export function reducer(state = initialState, action: Actions): State {
case ActionType.ResetPasswordSuccess: {
return {
member: action.payload,
pending: false,
error: null,
};
@ -26,6 +28,7 @@ export function reducer(state = initialState, action: Actions): State {
case ActionType.ResetPasswordFailure: {
return {
member: null,
pending: false,
error: action.payload,
};

View File

@ -5,11 +5,13 @@ import { RESTClientError } from '@loafer/ng-rest';
import { Member } from '@overflow/commons-typescript/model/member';
export interface State {
member: Member;
pending: boolean;
error: RESTClientError;
}
export const initialState: State = {
member: null,
pending: false,
error: null,
};
@ -17,6 +19,7 @@ export const initialState: State = {
export function getSelectors(selector: Selector<any, State>) {
return {
selectMember: createSelector(selector, (state: State) => state.member),
selectPending: createSelector(selector, (state: State) => state.pending),
selectError: createSelector(selector, (state: State) => state.error),
};

View File

@ -1,6 +1,6 @@
<div class="ui-g">
<div class="ui-g-12 ui-md-9 ui-lg-7">
<of-member-modify-password-container></of-member-modify-password-container>
<of-member-modify-password-container (signin)="onSignin()"></of-member-modify-password-container>
</div>
<div class="ui-g-12 ui-md-3 ui-lg-5 login-descript">
<table class="login-table">

View File

@ -1,5 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import {ActivatedRoute, Router} from '@angular/router';
@Component({
selector: 'of-pages-modify-password',
@ -9,6 +9,7 @@ export class ModifyPasswordPageComponent implements OnInit {
toenURL: string;
constructor(
private router: Router,
private activatedRoute: ActivatedRoute,
) { }
@ -16,4 +17,7 @@ export class ModifyPasswordPageComponent implements OnInit {
this.toenURL = this.activatedRoute.snapshot.queryParams['token'];
}
onSignin() {
this.router.navigate(['auth/signin']);
}
}

View File

@ -1,6 +1,6 @@
<div class="ui-g">
<div class="ui-g-12 ui-md-9 ui-lg-7">
<of-member-reset-password-container></of-member-reset-password-container>
<of-member-reset-password-container (signin)="onSignin()" (signup)="onSignup()"></of-member-reset-password-container>
</div>
<div class="ui-g-12 ui-md-3 ui-lg-5 login-descript">
<table class="login-table">

View File

@ -1,4 +1,5 @@
import { Component, OnInit } from '@angular/core';
import {Router} from '@angular/router';
@Component({
selector: 'of-pages-auth-reset-password',
@ -6,9 +7,18 @@ import { Component, OnInit } from '@angular/core';
})
export class ResetPasswordPageComponent implements OnInit {
constructor() { }
constructor(
private router: Router
) { }
ngOnInit() {
}
onSignin() {
this.router.navigate(['auth/signin']);
}
onSignup() {
this.router.navigate(['auth/signup']);
}
}