Skip to content

Commit

Permalink
#10 Exercise 3 useState
Browse files Browse the repository at this point in the history
  • Loading branch information
TruongTanNghia committed Oct 2, 2023
1 parent dc777b2 commit 5e85eb7
Show file tree
Hide file tree
Showing 4 changed files with 193 additions and 0 deletions.
53 changes: 53 additions & 0 deletions src/component/useState/exercise3/data/form_data.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { v4 as uuidv4 } from 'uuid';

export const inputs = [
{
id: uuidv4(),
name: 'username',
type: 'text',
placeholder: 'Username',
errorMessage:
"Username should be 3-16 characters and shouldn't include any special character!",
label: 'Username',
pattern: '^[A-Za-z0-9]{3,16}$',
required: true,
},
{
id: uuidv4(),
name: 'email',
type: 'email',
placeholder: 'Email',
errorMessage: 'It should be a valid email address!',
label: 'Email',
required: true,
},
{
id: uuidv4(),
name: 'birthday',
type: 'date',
placeholder: 'Birthday',
label: 'Birthday',
},
{
id: uuidv4(),
name: 'password',
type: 'password',
placeholder: 'Password',
errorMessage:
'Password should be 8-20 characters and include at least 1 letter, 1 number and 1 special character!',
label: 'Password',
pattern: `^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[!@#$%^&*])[a-zA-Z0-9!@#$%^&*]{8,20}$`,
required: true,
},
{
id: uuidv4(),
name: 'confirmPassword',
type: 'password',
placeholder: 'Confirm Password',
errorMessage: "Passwords don't match!",
label: 'Confirm Password',
// pattern: values.password,
required: true,
},

];
32 changes: 32 additions & 0 deletions src/component/useState/exercise3/form.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/* eslint-disable react/prop-types */
import { useState } from 'react';
// import '../styles/From.css';
const Form = (props) => {
const [focused, setFocused] = useState(false);

const { label, errorMessage, onChange, ...inputProps } = props;

const handleFocus = () => {
setFocused(true);
};

return (
<>
<div className="formInput">
<lable> {label} </lable>
<input
className="inputform"
{...inputProps}
onChange={onChange}
onBlur={handleFocus}
onFocus={() => inputProps.name === 'confirmPassword' && setFocused(true)}
// eslint-disable-next-line react/no-unknown-property
focused={focused.toString()}
/>
<span>{errorMessage}</span>
</div>
</>
);
};

export default Form;
39 changes: 39 additions & 0 deletions src/component/useState/exercise3/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { useState } from 'react';
import Form from './form.jsx';
// import {Form1} from '@/imports'
import { inputs } from './data/form_data.jsx';
import './styles/form.css';
const Index = () => {
const [values, setValues] = useState({
username: '',
email: '',
birthday: '',
password: '',
confirmPassword: '',
});

const handleSubmit = (e) => {
e.preventDefault();
};

const onChange = (e) => {
setValues({ ...values, [e.target.name]: e.target.value });
console.log(values);
};

return (
<>
<div className="app">
<form onSubmit={handleSubmit}>
<h1>Register</h1>
{inputs.map((input) => (
<Form key={input.id} {...input} value={values[input.name]} onChange={onChange} />
))}
<button>Submit</button>
</form>
</div>
</>
);
};

export default Index;
69 changes: 69 additions & 0 deletions src/component/useState/exercise3/styles/form.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
.app {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
background: linear-gradient(rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0.3)),
url("https://images.pexels.com/photos/114979/pexels-photo-114979.jpeg?auto=compress&cs=tinysrgb&dpr=2&w=500");
background-size: cover;
background-position: center;
}

form {
background-color: white;
padding: 0px 60px;
border-radius: 10px;
}

h1 {
color: rgb(77, 1, 77);
text-align: center;
}

/* button {
width: 100%;
height: 50px;
padding: 10px;
border: none;
background-color: rebeccapurple;
color: white;
border-radius: 5px;
font-weight: bold;
font-size: 18px;
cursor: pointer;
margin-top: 15px;
margin-bottom: 30px;
} */

.formInput {
display: flex;
flex-direction: column;
width: 280px;
}

.inputform {
padding: 15px;
margin: 10px 0px;
border-radius: 5px;
border: 1px solid gray;
}

label {
font-size: 12px;
color: gray;
}

span {
font-size: 12px;
padding: 3px;
color: red;
display: none;
}

input:invalid[focused="true"] {
border: 1px solid red;
}

input:invalid[focused="true"] ~ span {
display: block;
}

0 comments on commit 5e85eb7

Please sign in to comment.