From 88e20f52bfc8024a69b63ea344c859927b19c076 Mon Sep 17 00:00:00 2001 From: Luka Skukan Date: Tue, 7 Feb 2017 16:51:16 +0100 Subject: [PATCH 1/2] WIP custom verify email markup --- src/components/VerifyEmailView.js | 118 +++++++++++++++++++++--------- src/utils.js | 39 +++++++--- 2 files changed, 113 insertions(+), 44 deletions(-) diff --git a/src/components/VerifyEmailView.js b/src/components/VerifyEmailView.js index 4be2a0a..1297a50 100644 --- a/src/components/VerifyEmailView.js +++ b/src/components/VerifyEmailView.js @@ -1,53 +1,103 @@ -import React from 'react'; +import React, {Component, PropTypes} from 'react'; +import keyMirror from 'keymirror'; import utils from '../utils'; import LoginLink from '../components/LoginLink'; import UserActions from '../actions/UserActions'; -export default class VerifyEmailView extends React.Component { - state = { - status: 'VERIFYING' +const verificationStatus = keyMirror({ + VERIFYING: null, + VERIFIED: null, + ERROR: null +}); + +class DefaultVerifyEmailView extends Component { + static propTypes = { + status: PropTypes.string.isRequired, }; - componentDidMount() { - var spToken = this.props.spToken; - - UserActions.verifyEmail(spToken, (err) => { - if (err) { - this.setState({ - status: 'ERROR' - }); - } else { - this.setState({ - status: 'VERIFIED' - }); - } - }); + _getContent() { + switch (this.props.status) { + case verificationStatus.VERIFYING: + return ( +

We are verifying your account.

+ ); + case verificationStatus.VERIFIED: + return ( +

+ Your account has has been verified! Login Now. +

+ ); + case verificationStatus.ERROR: + return ( +
+ This email verification link is not valid. +
+ ); + default: + return null; + } } render() { - let selectedProps = utils.excludeProps(['className','spToken'], this.props); + const selectedProps = utils.excludeProps(['className','status'], this.props) return (
- {{ - VERIFYING: ( -

We are verifying your account.

- ), - VERIFIED: ( -

- Your account has has been verified! Login Now. -

- ), - ERROR: ( -
- This email verification link is not valid. -
- ) - }[this.state.status]} + {this._getContent()}
); } } + +export default class VerifyEmailView extends Component { + + static propTypes = { + children: PropTypes.element + }; + + state = { + status: verificationStatus.VERIFYING + }; + + componentDidMount() { + UserActions.verifyEmail(this.props.spToken, (err) => { + const status = this.err + ? verificationStatus.ERROR + : verificationStatus.VERIFIED; + + this.setState({ + status + }); + }); + } + + _spIfHandler(action) { + const test = /\s*status\s*(===?|\!==?)\s*[\'\"](\w+)[\'\"]\s*/i; + const matches = action.match(test); + + if (!matches) { + return true; + } + + const inverted = matches[1][0] === '!'; + const isSame = this.state.status === matches[2]; + + return inverted ? !isSame : isSame; + } + + render() { + const childProps = utils.excludeProps( + ['className', 'spToken', 'children'], + {...this.props, ...this.state} + ); + + if (this.props.children) { + return utils.makeView(this, this._spIfHandler.bind(this)); + } + + return (); + } +} diff --git a/src/utils.js b/src/utils.js index db85aab..f5763b9 100644 --- a/src/utils.js +++ b/src/utils.js @@ -6,6 +6,10 @@ let jwtExpression = /^[a-zA-Z0-9+/_=-]+\.[a-zA-Z0-9+/_=-]+\.[a-zA-Z0-9+/_=-]+$/; class Utils { nopElement = ; + noop(arg) { + return arg; + } + uuid() { var s4 = () => Math.floor((1 + Math.random()) * 0x10000) .toString(16).substring(1); @@ -115,6 +119,7 @@ class Utils { ); } + console.log(newElement.props, newOptions, newChildren); return React.cloneElement(newElement, newOptions, newChildren); } @@ -215,17 +220,9 @@ class Utils { } } - makeForm(source, fieldMapFn, spIfFn, spBindFn) { - var root = React.cloneElement(
, {}, source.props.children); - var fieldMap = this.getFormFieldMap(root, fieldMapFn); - - source.state.fields = source.state.fields || {}; - - for (var key in fieldMap.defaultValues) { - this.setFieldValue(source.state.fields, key, fieldMap.defaultValues[key]); - } + makeElementFactory(spIfFn, spBindFn) { - var elementFactory = (element, parent) => { + return (element, parent) => { if (element.props) { var spIf = this.takeProp(element.props, 'spIf', 'data-spIf'); @@ -260,8 +257,30 @@ class Utils { } } } + return element; }; + } + + makeView(source, spIfFn, spBindFn = this.noop) { + const root = React.cloneElement(
, {}, source.props.children); + const elementFactory = this.makeElementFactory(spIfFn, spBindFn); + const optionsFactory = () => ({}); + + return this.buildElementTree(root, optionsFactory, elementFactory); + } + + makeForm(source, fieldMapFn, spIfFn, spBindFn) { + var root = React.cloneElement(
, {}, source.props.children); + var fieldMap = this.getFormFieldMap(root, fieldMapFn); + + source.state.fields = source.state.fields || {}; + + for (var key in fieldMap.defaultValues) { + this.setFieldValue(source.state.fields, key, fieldMap.defaultValues[key]); + } + + const elementFactory = this.makeElementFactory(spIfFn, spBindFn); var optionsFactory = (element, parent) => { var options = {}; From 195858c1e4f6f9452322b3266cb692198da5332c Mon Sep 17 00:00:00 2001 From: Luka Skukan Date: Wed, 8 Feb 2017 12:09:31 +0100 Subject: [PATCH 2/2] Clean up and fix issues with view construction --- src/utils.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/utils.js b/src/utils.js index f5763b9..e4a7ed8 100644 --- a/src/utils.js +++ b/src/utils.js @@ -119,7 +119,6 @@ class Utils { ); } - console.log(newElement.props, newOptions, newChildren); return React.cloneElement(newElement, newOptions, newChildren); } @@ -258,7 +257,17 @@ class Utils { } } - return element; + if (typeof element === 'string') { + return element; + } + + const newChildren = element.props.children || {}; + + return React.createElement( + element.type, + this.excludeProps(['spIf', 'data-spIf'], element.props), + ...newChildren + ); }; }