mirror of
https://github.com/wassname/talk.git
synced 2026-07-29 11:28:24 +08:00
Sign Up Form, Cross Validations for Username, Email, Password, and more added.
This commit is contained in:
@@ -2,7 +2,14 @@ import * as React from "react";
|
||||
import { StatelessComponent } from "react";
|
||||
import { Field, Form } from "react-final-form";
|
||||
import { OnSubmit } from "talk-framework/lib/form";
|
||||
import { required } from "talk-framework/lib/validation";
|
||||
import {
|
||||
composeValidators,
|
||||
required,
|
||||
validateEmail,
|
||||
validateEqualPasswords,
|
||||
validatePassword,
|
||||
validateUsername,
|
||||
} from "talk-framework/lib/validation";
|
||||
import * as styles from "./SignUp.css";
|
||||
|
||||
import {
|
||||
@@ -12,6 +19,7 @@ import {
|
||||
InputLabel,
|
||||
TextField,
|
||||
Typography,
|
||||
ValidationMessage,
|
||||
} from "talk-ui/components";
|
||||
|
||||
interface FormProps {
|
||||
@@ -36,7 +44,10 @@ const SignUp: StatelessComponent<SignUpForm> = props => {
|
||||
Sign up to join the conversation
|
||||
</Typography>
|
||||
|
||||
<Field name="email" validate={required}>
|
||||
<Field
|
||||
name="email"
|
||||
validate={composeValidators(required, validateEmail)}
|
||||
>
|
||||
{({ input, meta }) => (
|
||||
<FormField>
|
||||
<InputLabel>Email Address</InputLabel>
|
||||
@@ -46,29 +57,100 @@ const SignUp: StatelessComponent<SignUpForm> = props => {
|
||||
value={input.value}
|
||||
placeholder="Email Address"
|
||||
/>
|
||||
{meta.touched &&
|
||||
(meta.error || meta.submitError) && (
|
||||
<ValidationMessage>
|
||||
{meta.error || meta.submitError}
|
||||
</ValidationMessage>
|
||||
)}
|
||||
</FormField>
|
||||
)}
|
||||
</Field>
|
||||
|
||||
<FormField>
|
||||
<InputLabel>Username</InputLabel>
|
||||
<Typography variant="inputDescription">
|
||||
A unique identifier displayed on your comments. You may use
|
||||
“_” and “.”
|
||||
</Typography>
|
||||
<TextField />
|
||||
</FormField>
|
||||
<FormField>
|
||||
<InputLabel>Password</InputLabel>
|
||||
<Typography variant="inputDescription">
|
||||
Must be at least 8 characters
|
||||
</Typography>
|
||||
<TextField />
|
||||
</FormField>
|
||||
<FormField>
|
||||
<InputLabel>Confirm Password</InputLabel>
|
||||
<TextField />
|
||||
</FormField>
|
||||
<Field
|
||||
name="username"
|
||||
validate={composeValidators(required, validateUsername)}
|
||||
>
|
||||
{({ input, meta }) => (
|
||||
<FormField>
|
||||
<InputLabel>Username</InputLabel>
|
||||
<Typography variant="inputDescription">
|
||||
A unique identifier displayed on your comments. You may
|
||||
use “_” and “.”
|
||||
</Typography>
|
||||
<TextField
|
||||
name={input.name}
|
||||
onChange={input.onChange}
|
||||
value={input.value}
|
||||
placeholder="Username"
|
||||
/>
|
||||
{meta.touched &&
|
||||
(meta.error || meta.submitError) && (
|
||||
<ValidationMessage>
|
||||
{meta.error || meta.submitError}
|
||||
</ValidationMessage>
|
||||
)}
|
||||
</FormField>
|
||||
)}
|
||||
</Field>
|
||||
|
||||
<Field
|
||||
name="password"
|
||||
validate={composeValidators(required, validatePassword)}
|
||||
>
|
||||
{({ input, meta }) => (
|
||||
<FormField>
|
||||
<InputLabel>Password</InputLabel>
|
||||
<Typography variant="inputDescription">
|
||||
Must be at least 8 characters
|
||||
</Typography>
|
||||
<TextField
|
||||
name={input.name}
|
||||
onChange={input.onChange}
|
||||
value={input.value}
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
/>
|
||||
{meta.touched &&
|
||||
(meta.error || meta.submitError) && (
|
||||
<ValidationMessage>
|
||||
{meta.error || meta.submitError}
|
||||
</ValidationMessage>
|
||||
)}
|
||||
</FormField>
|
||||
)}
|
||||
</Field>
|
||||
|
||||
<Field
|
||||
name="confirmPassword"
|
||||
validate={composeValidators(
|
||||
required,
|
||||
validatePassword,
|
||||
validateEqualPasswords
|
||||
)}
|
||||
>
|
||||
{({ input, meta }) => (
|
||||
<FormField>
|
||||
<InputLabel>Confirm Password</InputLabel>
|
||||
<Typography variant="inputDescription">
|
||||
Must be at least 8 characters
|
||||
</Typography>
|
||||
<TextField
|
||||
name={input.name}
|
||||
onChange={input.onChange}
|
||||
value={input.value}
|
||||
placeholder="Confirm Password"
|
||||
type="password"
|
||||
/>
|
||||
{meta.touched &&
|
||||
(meta.error || meta.submitError) && (
|
||||
<ValidationMessage>
|
||||
{meta.error || meta.submitError}
|
||||
</ValidationMessage>
|
||||
)}
|
||||
</FormField>
|
||||
)}
|
||||
</Field>
|
||||
</Flex>
|
||||
<div className={styles.footer}>
|
||||
<Button variant="filled" color="primary" size="large" fullWidth>
|
||||
|
||||
@@ -17,3 +17,27 @@ export const VALIDATION_TOO_SHORT = () => (
|
||||
<span>This field is too short.</span>
|
||||
</Localized>
|
||||
);
|
||||
|
||||
export const INVALID_EMAIL = () => (
|
||||
<Localized id="framework-validation-invalidEmail">
|
||||
<span>Please enter a valid email address.</span>
|
||||
</Localized>
|
||||
);
|
||||
|
||||
export const INVALID_USERNAME = () => (
|
||||
<Localized id="framework-validation-invalidUsername">
|
||||
<span>Please enter a valid username.</span>
|
||||
</Localized>
|
||||
);
|
||||
|
||||
export const INVALID_PASSWORD = () => (
|
||||
<Localized id="framework-validation-invalidUsername">
|
||||
<span>Please enter a valid password.</span>
|
||||
</Localized>
|
||||
);
|
||||
|
||||
export const PASSWORDS_DO_NOT_MATCH = () => (
|
||||
<Localized id="framework-validation-passwordsDoNotMatch">
|
||||
<span>Passwords do not match. Try again.</span>
|
||||
</Localized>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import { ReactNode } from "react";
|
||||
import { VALIDATION_REQUIRED } from "./messages";
|
||||
import {
|
||||
INVALID_EMAIL,
|
||||
INVALID_PASSWORD,
|
||||
INVALID_USERNAME,
|
||||
PASSWORDS_DO_NOT_MATCH,
|
||||
VALIDATION_REQUIRED,
|
||||
} from "./messages";
|
||||
|
||||
type Validator<T, V> = (v: T, values: V) => ReactNode;
|
||||
|
||||
@@ -31,3 +37,35 @@ export function composeValidators<T = any, V = any>(
|
||||
* required is a Validator that checks that the value is truthy.
|
||||
*/
|
||||
export const required = createValidator(v => !!v, VALIDATION_REQUIRED());
|
||||
|
||||
/**
|
||||
* validateEmail is a Validator that checks that the value is an email.
|
||||
*/
|
||||
export const validateEmail = createValidator(
|
||||
v => /^.+@.+\..+$/.test(v),
|
||||
INVALID_EMAIL()
|
||||
);
|
||||
|
||||
/**
|
||||
* validateUsername is a Validator that checks that the value is a valid username.
|
||||
*/
|
||||
export const validateUsername = createValidator(
|
||||
v => /^[a-zA-Z0-9_.]+$/.test(v),
|
||||
INVALID_USERNAME()
|
||||
);
|
||||
|
||||
/**
|
||||
* validateUsername is a Validator that checks that the value is a valid username.
|
||||
*/
|
||||
export const validatePassword = createValidator(
|
||||
v => /^(?=.{8,}).*$/.test(v),
|
||||
INVALID_PASSWORD()
|
||||
);
|
||||
|
||||
/**s
|
||||
* validateUsername is a Validator that checks that the value is a valid username.
|
||||
*/
|
||||
export const validateEqualPasswords = createValidator(
|
||||
(v, values) => v === values.password,
|
||||
PASSWORDS_DO_NOT_MATCH()
|
||||
);
|
||||
|
||||
@@ -41,6 +41,10 @@ export interface TextFieldProps {
|
||||
* Name
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* type
|
||||
*/
|
||||
type?: string;
|
||||
/**
|
||||
* onChange
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user