Skip to content
This repository has been archived by the owner on Jul 2, 2022. It is now read-only.

Commit

Permalink
[Feature Request] User account confirmation (#23)
Browse files Browse the repository at this point in the history
  • Loading branch information
Qolzam committed Nov 16, 2017
1 parent 5578996 commit f64b7bb
Show file tree
Hide file tree
Showing 26 changed files with 572 additions and 232 deletions.
5 changes: 5 additions & 0 deletions .firebaserc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"projects": {
"default": "love-social"
}
}
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@ config/
.vscode/
src/data/awsClient
src/components/AWS.tsx
.firebaserc
firebase.json
npm-debug.log
9 changes: 9 additions & 0 deletions firebase.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"hosting": {
"public": "public",
"rewrites": [{
"source": "**",
"destination": "/index.html"
}]
}
}
29 changes: 25 additions & 4 deletions src/actions/authorizeActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const dbLogin = (email: string, password: string) => {
dispatch(globalActions.showNotificationRequest())
return authorizeService.login(email, password).then((result) => {
dispatch(globalActions.showNotificationSuccess())
dispatch(login(result.uid))
dispatch(login(result.uid,result.emailVerified))
dispatch(push('/'))
}, (error: SocialError) => dispatch(globalActions.showErrorMessage(error.code)))
}
Expand Down Expand Up @@ -71,7 +71,8 @@ export const dbSignup = (user: UserRegisterModel) => {
userId: result.uid,
...user
}))
dispatch(push('/'))
dispatch(dbSendEmailVerfication())
dispatch(push('/emailVerification'))
})
.catch((error: SocialError) => dispatch(globalActions.showErrorMessage(error.code)))
}
Expand Down Expand Up @@ -129,16 +130,36 @@ export const dbResetPassword = (email: string) => {
}
}

/**
* Send email verification
*/
export const dbSendEmailVerfication = () => {
return (dispatch: any, getState: any) => {
dispatch(globalActions.showNotificationRequest())

return authorizeService.sendEmailVerification().then(() => {
// Send email verification successful.
dispatch(globalActions.showNotificationSuccess())
dispatch(push('/'))
})
.catch((error: SocialError) => {
// An error happened.
dispatch(globalActions.showErrorMessage(error.code))

})
}
}

/* _____________ CRUD State _____________ */

/**
* Loing user
* @param {string} uids
*/
export const login = (uid: string) => {
export const login = (uid: string, isVerifide: boolean) => {
return {
type: AuthorizeActionType.LOGIN,
payload: { authed: true, uid }
payload: { authed: true, isVerifide, uid }
}
}

Expand Down
132 changes: 132 additions & 0 deletions src/components/emailVerification/EmailVerificationComponent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// - Import external components
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { NavLink, withRouter } from 'react-router-dom'
import { push } from 'react-router-redux'
import Paper from 'material-ui/Paper'
import TextField from 'material-ui/TextField'
import RaisedButton from 'material-ui/RaisedButton'
import FlatButton from 'material-ui/FlatButton'
import { firebaseRef, firebaseAuth } from 'data/firebaseClient'

// - Import actions
import * as authorizeActions from 'actions/authorizeActions'
import { IEmailVerificationComponentProps } from './IEmailVerificationComponentProps'
import { IEmailVerificationComponentState } from './IEmailVerificationComponentState'

/**
* Create component class
*
* @export
* @class EmailVerificationComponent
* @extends {Component}
*/
export class EmailVerificationComponent extends Component<IEmailVerificationComponentProps,IEmailVerificationComponentState> {

styles = {
message: {
fontWeight: 100
},
sendButton: {
marginTop: 60
}
}

/**
* Component constructor
* @param {object} props is an object properties of component
*/
constructor (props: IEmailVerificationComponentProps) {
super(props)

// Binding function to `this`

}

/**
* Reneder component DOM
* @return {react element} return the DOM which rendered by component
*/
render () {

const paperStyle = {
minHeight: 370,
width: 450,
textAlign: 'center',
display: 'block',
margin: 'auto'
}
return (
<div>

<h1 style={{
textAlign: 'center',
padding: '20px',
fontSize: '30px',
fontWeight: 500,
lineHeight: '32px',
margin: 'auto',
color: 'rgba(138, 148, 138, 0.2)'
}}>Green</h1>

<div className='animate-bottom'>
<Paper style={paperStyle} zDepth={1} rounded={false} >
<div style={{ padding: '48px 40px 36px' }}>
<div style={{
paddingLeft: '40px',
paddingRight: '40px'
}}>

<h2 style={{
textAlign: 'left',
paddingTop: '16px',
fontSize: '24px',
fontWeight: 400,
lineHeight: '32px',
margin: 0
}} className='zoomOutLCorner animated'>Email Verification</h2>
</div>
<p style={this.styles.message as any}>
An verificiation email has been already sent to you. Please check your inbox. If you couldn't see the emai, please resend email verification.
</p>
<div style={this.styles.sendButton}>
<RaisedButton label='Send Email Verification' primary={true} onClick={() => this.props.sendEmailVerification()} />
</div>

</div>
</Paper>
</div>
</div>
)
}
}

/**
* Map dispatch to props
* @param {func} dispatch is the function to dispatch action to reducers
* @param {object} ownProps is the props belong to component
* @return {object} props of component
*/
const mapDispatchToProps = (dispatch: Function, ownProps: IEmailVerificationComponentProps) => {
return {
loginPage: () => {
dispatch(push('/login'))
},
sendEmailVerification: () => dispatch(authorizeActions.dbSendEmailVerfication())
}
}

/**
* Map state to props
* @param {object} state is the obeject from redux store
* @param {object} ownProps is the props belong to component
* @return {object} props of component
*/
const mapStateToProps = (state: any, ownProps: IEmailVerificationComponentProps) => {
return {

}
}

// - Connect component to redux store
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(EmailVerificationComponent as any))
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface IEmailVerificationComponentProps {

sendEmailVerification: () => any
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

export interface IEmailVerificationComponentState {


}
2 changes: 2 additions & 0 deletions src/components/emailVerification/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import EmailVerificationComponent from './EmailVerificationComponent'
export default EmailVerificationComponent
92 changes: 75 additions & 17 deletions src/components/home/HomeComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,18 @@ import People from 'components/people'
import CircleAPI from 'api/CircleAPI'

// - Import actions
import * as globalActions from 'actions/globalActions'
// - Import actions
import {
authorizeActions,
imageGalleryActions,
postActions,
commentActions,
voteActions,
userActions,
globalActions,
circleActions,
notifyActions
} from 'actions'

import { IHomeComponentProps } from './IHomeComponentProps'
import { IHomeComponentState } from './IHomeComponentState'
Expand Down Expand Up @@ -93,6 +104,24 @@ export class HomeComponent extends Component<IHomeComponentProps, IHomeComponent
})
}

componentWillMount () {

const {global, clearData, loadData, authed, defaultDataEnable, isVerifide, goTo } = this.props
if (!authed) {
goTo!('/login')
return
}
if (!isVerifide) {
goTo!('/emailVerification')

} else if (!global.defaultLoadDataStatus) {

clearData!()
loadData!()
defaultDataEnable!()
}
}

/**
* Render DOM component
*
Expand All @@ -101,7 +130,7 @@ export class HomeComponent extends Component<IHomeComponentProps, IHomeComponent
* @memberof Home
*/
render () {

const {loaded} = this.props
return (
<div id='home'>
<HomeHeader sidebar={this.state.sidebarOpen} sidebarStatus={this.state.sidebarStatus} />
Expand All @@ -123,7 +152,7 @@ export class HomeComponent extends Component<IHomeComponentProps, IHomeComponent
</SidebarContent>

<SidebarMain>
<Switch>
{loaded ? (<Switch>
<Route path='/people/:tab?' render={() => {
return (
this.props.authed
Expand All @@ -150,7 +179,8 @@ export class HomeComponent extends Component<IHomeComponentProps, IHomeComponent
: <Redirect to='/login' />
)
}} />
</Switch>
</Switch>)
: ''}
</SidebarMain>
</Sidebar>

Expand All @@ -160,16 +190,40 @@ export class HomeComponent extends Component<IHomeComponentProps, IHomeComponent
}
}

/**
* Map dispatch to props
* @param {func} dispatch is the function to dispatch action to reducers
* @param {object} ownProps is the props belong to component
* @return {object} props of component
*/
// - Map dispatch to props
const mapDispatchToProps = (dispatch: any, ownProps: IHomeComponentProps) => {

return {
loadData: () => {
dispatch(commentActions.dbGetComments())
dispatch(imageGalleryActions.dbGetImageGallery())
dispatch(postActions.dbGetPosts())
dispatch(userActions.dbGetUserInfo())
dispatch(voteActions.dbGetVotes())
dispatch(notifyActions.dbGetNotifications())
dispatch(circleActions.dbGetCircles())

},
clearData: () => {
dispatch(imageGalleryActions.clearAllData())
dispatch(postActions.clearAllData())
dispatch(userActions.clearAllData())
dispatch(commentActions.clearAllData())
dispatch(voteActions.clearAllvotes())
dispatch(notifyActions.clearAllNotifications())
dispatch(circleActions.clearAllCircles())
dispatch(globalActions.clearTemp())

},
defaultDataDisable: () => {
dispatch(globalActions.defaultDataDisable())
},
defaultDataEnable: () => {
dispatch(globalActions.defaultDataEnable())
},
goTo: (url: string) => dispatch(push(url))
}

}

/**
Expand All @@ -179,20 +233,24 @@ const mapDispatchToProps = (dispatch: any, ownProps: IHomeComponentProps) => {
* @return {object} props of component
*/
const mapStateToProps = (state: any, ownProps: IHomeComponentProps) => {
const { uid } = state.authorize
const { authorize, global, user, post, comment, imageGallery, vote, notify, circle } = state
const { uid } = authorize
let mergedPosts = {}
const circles = state.circle ? (state.circle.userCircles[uid] || {}) : {}
const circles = circle ? (circle.userCircles[uid] || {}) : {}
const followingUsers = CircleAPI.getFollowingUsers(circles)
const posts = state.post.userPosts ? state.post.userPosts[state.authorize.uid] : {}
const posts = post.userPosts ? post.userPosts[authorize.uid] : {}
Object.keys(followingUsers).forEach((userId) => {
let newPosts = state.post.userPosts ? state.post.userPosts[userId] : {}
let newPosts = post.userPosts ? post.userPosts[userId] : {}
_.merge(mergedPosts,newPosts)
})
_.merge(mergedPosts,posts)
return {
authed: state.authorize.authed,
mainStyle: state.global.sidebarMainStyle,
mergedPosts
authed: authorize.authed,
isVerifide: authorize.isVerifide,
mainStyle: global.sidebarMainStyle,
mergedPosts,
global,
loaded: user.loaded && post.loaded && comment.loaded && imageGallery.loaded && vote.loaded && notify.loaded && circle.loaded
}
}

Expand Down
Loading

0 comments on commit f64b7bb

Please sign in to comment.