Dwayne Harris
5 years ago
26 changed files with 468 additions and 161 deletions
-
60src/actions/registration.ts
-
21src/api/fetch.ts
-
16src/api/groups.ts
-
20src/api/registration.ts
-
0src/api/users.ts
-
13src/components/app/app.scss
-
35src/components/create-group-step/create-group-step.tsx
-
25src/components/create-group-step/index.ts
-
2src/components/create-user-form/create-user-form.tsx
-
52src/components/create-user-step/create-user-step.tsx
-
66src/components/create-user-step/index.ts
-
14src/components/forms/password-field/password-field.tsx
-
2src/components/forms/text-field/text-field.tsx
-
19src/components/page-header/index.tsx
-
35src/components/pages/about/index.tsx
-
27src/components/pages/developers/index.tsx
-
22src/components/pages/directory/directory.tsx
-
24src/components/pages/home/index.tsx
-
23src/components/pages/login/login.tsx
-
41src/components/pages/register/index.ts
-
60src/components/pages/register/register.tsx
-
10src/components/pages/test/test.tsx
-
10src/constants/index.ts
-
1src/reducers/forms.ts
-
9src/selectors/forms.ts
-
22src/utils/index.ts
@ -1,20 +1,74 @@ |
|||
import { Dispatch } from 'redux' |
|||
import { connect } from 'react-redux' |
|||
import zxcvbn from 'zxcvbn' |
|||
|
|||
import { setFieldNotification } from 'src/actions/forms' |
|||
import { showNotification } from 'src/actions/notifications' |
|||
import { setStep } from 'src/actions/registration' |
|||
import { getFieldValue } from 'src/selectors/forms' |
|||
import { MAX_ID_LENGTH, MAX_NAME_LENGTH } from 'src/constants' |
|||
import { AppState, AppThunkDispatch } from 'src/types' |
|||
|
|||
import CreateUserStep from './create-user-step' |
|||
import CreateUserStep, { Props } from './create-user-step' |
|||
|
|||
const mapDispatchToProps = (dispatch: Dispatch) => ({ |
|||
const mapStateToProps = (state: AppState) => ({ |
|||
userId: getFieldValue<string>(state, 'user-id', ''), |
|||
name: getFieldValue<string>(state, 'user-name', ''), |
|||
email: getFieldValue<string>(state, 'user-email', ''), |
|||
password: getFieldValue<string>(state, 'password', ''), |
|||
agree: getFieldValue<boolean>(state, 'user-agree', false), |
|||
}) |
|||
|
|||
const mapDispatchToProps = (dispatch: AppThunkDispatch, ownProps: Props) => ({ |
|||
previous: () => { |
|||
dispatch(setStep(0)) |
|||
}, |
|||
next: () => { |
|||
|
|||
next: (userId: string, name: string, email: string, password: string, agree: boolean) => { |
|||
let invalid = false |
|||
|
|||
if (!userId) { |
|||
dispatch(setFieldNotification('user-id', 'error', 'This is required')) |
|||
invalid = true |
|||
} |
|||
|
|||
if (userId.length > MAX_ID_LENGTH) { |
|||
dispatch(setFieldNotification('user-id', 'error', `This must be less than ${MAX_ID_LENGTH} characters`)) |
|||
invalid = true |
|||
} |
|||
|
|||
if (name.length > MAX_NAME_LENGTH) { |
|||
dispatch(setFieldNotification('user-name', 'error', `This must be less than ${MAX_NAME_LENGTH} characters`)) |
|||
invalid = true |
|||
} |
|||
|
|||
if (email === '') { |
|||
dispatch(setFieldNotification('user-email', 'error', 'This is required')) |
|||
invalid = true |
|||
} |
|||
|
|||
if (!agree) { |
|||
dispatch(setFieldNotification('user-agree', 'error', 'You must agree to the terms and conditions to continue')) |
|||
dispatch(showNotification('error', 'You must agree to the terms and conditions to continue.')) |
|||
invalid = true |
|||
} |
|||
|
|||
if (password === '') { |
|||
dispatch(setFieldNotification('password', 'error', 'This is required')) |
|||
invalid = true |
|||
} else { |
|||
const { score } = zxcvbn(password) |
|||
|
|||
if (score === 0) { |
|||
dispatch(setFieldNotification('password', 'error', 'Try another password')) |
|||
invalid = true |
|||
} |
|||
} |
|||
|
|||
if (invalid) return |
|||
if (ownProps.register) ownProps.register() |
|||
}, |
|||
}) |
|||
|
|||
export default connect( |
|||
null, |
|||
mapStateToProps, |
|||
mapDispatchToProps |
|||
)(CreateUserStep) |
@ -0,0 +1,19 @@ |
|||
import React, { FC } from 'react' |
|||
|
|||
interface Props { |
|||
title: string |
|||
subtitle?: string |
|||
} |
|||
|
|||
const PageHeader: FC<Props> = ({ title, subtitle }) => ( |
|||
<section className="hero is-dark is-bold"> |
|||
<div className="hero-body"> |
|||
<div className="container"> |
|||
<h1 className="title">{title}</h1> |
|||
{subtitle && <h2 className="subtitle">{title}</h2>} |
|||
</div> |
|||
</div> |
|||
</section> |
|||
) |
|||
|
|||
export default PageHeader |
@ -1,21 +1,24 @@ |
|||
import React, { FC } from 'react' |
|||
import React, { FC, useEffect } from 'react' |
|||
import { setTitle } from 'src/utils' |
|||
|
|||
const About: FC = () => ( |
|||
<div> |
|||
<section className="hero is-dark is-bold"> |
|||
<div className="hero-body"> |
|||
<div className="container"> |
|||
<h1 className="title">About Flexor</h1> |
|||
</div> |
|||
</div> |
|||
</section> |
|||
import PageHeader from 'src/components/page-header' |
|||
|
|||
const About: FC = () => { |
|||
useEffect(() => { |
|||
setTitle('About Flexor', false) |
|||
}) |
|||
|
|||
return ( |
|||
<div> |
|||
<PageHeader title="About Flexor" /> |
|||
|
|||
<div className="main-content"> |
|||
<p> |
|||
Flexor is a website. |
|||
</p> |
|||
<div className="main-content"> |
|||
<p> |
|||
Flexor is a website. |
|||
</p> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
) |
|||
) |
|||
} |
|||
|
|||
export default About |
@ -1,13 +1,22 @@ |
|||
import React, { FC } from 'react' |
|||
import React, { FC, useEffect } from 'react' |
|||
import { setTitle } from 'src/utils' |
|||
|
|||
const Developers: FC = () => ( |
|||
<div className="main-content"> |
|||
<h1 className="title">Developers</h1> |
|||
import PageHeader from 'src/components/page-header' |
|||
|
|||
<p> |
|||
Developer documentation coming soon. |
|||
</p> |
|||
</div> |
|||
) |
|||
const Developers: FC = () => { |
|||
useEffect(() => { |
|||
setTitle('Developers') |
|||
}) |
|||
|
|||
return ( |
|||
<div> |
|||
<PageHeader title="Developers" /> |
|||
|
|||
<div className="main-content"> |
|||
Developer documentation coming soon. |
|||
</div> |
|||
</div> |
|||
) |
|||
} |
|||
|
|||
export default Developers |
@ -1,9 +1,21 @@ |
|||
import React, { FC } from 'react' |
|||
import React, { FC, useEffect } from 'react' |
|||
import { setTitle } from 'src/utils' |
|||
import PageHeader from 'src/components/page-header' |
|||
|
|||
const Home: FC = () => ( |
|||
<div className="main-content"> |
|||
<h1 className="title">Home</h1> |
|||
</div> |
|||
) |
|||
const Home: FC = () => { |
|||
useEffect(() => { |
|||
setTitle('Home') |
|||
}) |
|||
|
|||
return ( |
|||
<div> |
|||
<PageHeader title="Home" /> |
|||
|
|||
<div className="main-content"> |
|||
Hello. |
|||
</div> |
|||
</div> |
|||
) |
|||
} |
|||
|
|||
export default Home |
@ -0,0 +1,10 @@ |
|||
export const MAX_ID_LENGTH = 40 |
|||
export const MAX_NAME_LENGTH = 80 |
|||
|
|||
export const LOCAL_STORAGE_ACCESS_TOKEN_KEY = 'FLEXOR_ACCESS_TOKEN' |
|||
export const LOCAL_STORAGE_ACCESS_TOKEN_AT_KEY = 'FLEXOR_ACCESS_TOKEN_AT' |
|||
export const LOCAL_STORAGE_REFRESH_TOKEN_KEY = 'FLEXOR_REFRESH_TOKEN' |
|||
|
|||
export const REQUEST_KEYS = { |
|||
|
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue