Merge pull request 'development' (#9) from development into feature/header

Reviewed-on: #9
This commit is contained in:
Savio Carvalho Moraes 2023-01-16 22:25:15 +00:00
commit fa4aecebe0
9 changed files with 465 additions and 71 deletions

20
package-lock.json generated
View File

@ -23,6 +23,7 @@
"react-bootstrap": "^2.7.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"react-text-mask": "^5.5.0",
"typescript": "^4.9.4",
"web-vitals": "^2.1.4",
"yup": "^0.32.11"
@ -15398,6 +15399,17 @@
}
}
},
"node_modules/react-text-mask": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/react-text-mask/-/react-text-mask-5.5.0.tgz",
"integrity": "sha512-SLJlJQxa0uonMXsnXRpv5abIepGmHz77ylQcra0GNd7Jtk4Wj2Mtp85uGQHv1avba2uI8ZvRpIEQPpJKsqRGYw==",
"dependencies": {
"prop-types": "^15.5.6"
},
"peerDependencies": {
"react": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/react-transition-group": {
"version": "4.4.5",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
@ -29686,6 +29698,14 @@
"workbox-webpack-plugin": "^6.4.1"
}
},
"react-text-mask": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/react-text-mask/-/react-text-mask-5.5.0.tgz",
"integrity": "sha512-SLJlJQxa0uonMXsnXRpv5abIepGmHz77ylQcra0GNd7Jtk4Wj2Mtp85uGQHv1avba2uI8ZvRpIEQPpJKsqRGYw==",
"requires": {
"prop-types": "^15.5.6"
}
},
"react-transition-group": {
"version": "4.4.5",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",

View File

@ -17,6 +17,7 @@
"react-bootstrap": "^2.7.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"react-text-mask": "^5.5.0",
"typescript": "^4.9.4",
"web-vitals": "^2.1.4",
"yup": "^0.32.11"

View File

@ -0,0 +1,36 @@
import Col from "react-bootstrap/Col";
import ListGroup from "react-bootstrap/ListGroup";
import Row from "react-bootstrap/Row";
import Tab from "react-bootstrap/Tab";
import styles from "./accordionBody.module.scss";
const AccordionBody = () => {
return (
<Tab.Container id="list-group-tabs" defaultActiveKey="#link1">
<Row>
<Col sm={4}>
<ListGroup>
<ListGroup.Item className={styles["acc-item"]} action href="#link1">
Link 1
</ListGroup.Item>
<ListGroup.Item action href="#link2">
Link 2
</ListGroup.Item>
</ListGroup>
</Col>
<Col sm={8}>
<Tab.Content>
<Tab.Pane eventKey="#link1">
<p>oi</p>
</Tab.Pane>
<Tab.Pane eventKey="#link2">
<p>tchau</p>
</Tab.Pane>
</Tab.Content>
</Col>
</Row>
</Tab.Container>
);
};
export { AccordionBody };

View File

@ -0,0 +1,17 @@
.accordion-wrapper {
display: flex;
flex-direction: column;
}
.accordion-item {
display: flex;
flex-direction: row;
}
.accordion-header {
}
/*
.list-group-tabs.active {
background-color: red;
}*/
.acc-item .active {
background-color: red;
}

View File

@ -1,9 +1,35 @@
import React from "react";
import { useFormik } from "formik";
import {
useFormik,
Formik,
Form,
Field,
ErrorMessage,
FormikHelpers,
} from "formik";
import * as Yup from "yup";
import styles from "./formInput.module.scss";
interface IFormikValues {
nome: string;
email: string;
cpf: string;
nascimento: string;
tel: string;
instagram: string;
termos: boolean;
}
const FormInput = () => {
const initialValues = {
nome: "",
email: "",
cpf: "",
nascimento: "",
tel: "",
instagram: "",
termos: false,
}; /*
const formik = useFormik({
initialValues: {
nome: "",
@ -12,78 +38,245 @@ const FormInput = () => {
nascimento: "",
tel: "",
instagram: "",
},
validationSchema: Yup.object({
nome: Yup.string().label("Seu nome completo").required(),
email: Yup.string().email().required(),
cpf: Yup.string().required(),
nascimento: Yup.string().required(),
tel: Yup.string().required(),
instagram: Yup.string().required(),
}),
termos: false,
},*/
validationSchema: Yup.object({
nome: Yup.string()
.required("*Campo Obrigatório")
.test(
"is-full-name",
"Please enter both your first and last name",
function (value: any) {
const nameArr = value.split(" ");
return nameArr.length >= 2;
}
),
email: Yup.string().required("*Campo Obrigatório"),
cpf: Yup.string().required("*Campo Obrigatório"),
nascimento: Yup.string().required("*Campo Obrigatório"),
tel: Yup.string().required("*Campo Obrigatório"),
instagram: Yup.string().required("*Campo Obrigatório"),
termos: Yup.boolean().required("*").isTrue(),
}); /*
onSubmit: function (values) {
alert(`You are registered! Name: ${values.nome}. Email: ${values.email}. Profession: ${values.cpf}.
Age: ${values.nascimento}`);
Age: ${values.nascimento},${values.tel},${values.instagram}`);
},
});*/
const validacao = Yup.object().shape({
nome: Yup.string()
.required("*Campo Obrigatório")
.test(
"Nome Completo",
"Preencha com um nome e sobrenome válido.",
function (value: any) {
if (value === "" || value === undefined) {
return false;
} else {
const nameArr = value.split(" ");
return nameArr.length >= 2;
}
}
),
email: Yup.string().required("*Campo Obrigatório").email("E-mail inválido"),
cpf: Yup.string()
.required("*Campo Obrigatório")
.test("cpf", "Preencha com um cpf válido.", function (value: any) {
if (value === "" || value === undefined) {
return false;
} else {
const cpfRegex = /^\d{3}\.\d{3}\.\d{3}\-\d{2}$/;
const regex = new RegExp(cpfRegex);
return regex.test(value);
}
}),
nascimento: Yup.string()
.required("*Campo Obrigatório")
.test(
"nascimento",
"Preencha com uma data válida.",
function (value: any) {
if (value === "" || value === undefined) {
return false;
} else {
const nascimentoRegex =
"^(0[1-9]|[12][0-9]|3[01]).(0[1-9]|1[012]).[12][0-9]{3}$";
const regex = new RegExp(nascimentoRegex);
return regex.test(value);
}
}
),
tel: Yup.string()
.required("*Campo Obrigatório")
.test(
"telefone",
"Preencha com um telefone válido.",
function (value: any) {
if (value === "" || value === undefined) {
return false;
} else {
const telefoneRegex =
"^((\\+\\d{2}\\s)?\\(\\d{2}\\)\\s?\\d{4}\\d?\\-\\d{4})?$";
const regex = new RegExp(telefoneRegex);
return regex.test(value);
}
}
),
instagram: Yup.string(),
termos: Yup.boolean().oneOf([true], "*"),
});
const handleFormikSubmit = (values: IFormikValues) => {
console.log(values);
};
return (
<div className={styles["form"]}>
<form onSubmit={formik.handleSubmit}>
<h2>Preencha o formulário</h2>
<ul className={styles["form-itens"]}>
<li className={styles["form-item"]}>
<label>Nome</label>
<input
type="text"
placeholder="Seu nome completo"
value={formik.values.nome}
/>
</li>
<li className={styles["form-item"]}>
<label>E-mail</label>
<input
type="text"
placeholder="Seu email"
value={formik.values.email}
/>
</li>
<li className={styles["form-item"]}>
<label>CPF</label>
<input
type="text"
placeholder="000.000.000-00"
value={formik.values.cpf}
/>
</li>
<div className={styles["form-wrapper"]}>
<h2>Preencha o formulário</h2>
<Formik
onSubmit={handleFormikSubmit}
initialValues={initialValues}
validationSchema={validacao}
>
{({ errors, touched }) => (
<Form>
<div className={styles["form-col"]}>
<div className={styles["form-text"]}>
<label htmlFor="nome">Nome</label>
<ErrorMessage
component="span"
name="nome"
className={styles["form-error"]}
/>
</div>
<li className={styles["form-item"]}>
<label>Data de Nascimento</label>
<input
type="text"
placeholder="00.00.00"
value={formik.values.nascimento}
/>
</li>
<li className={styles["form-item"]}>
<label>Telefone</label>
<input
type="text"
placeholder="(00)00000-0000"
value={formik.values.tel}
/>
</li>
<li className={styles["form-item"]}>
<label>Instagram</label>
<input
type="text"
placeholder="@seuuser"
value={formik.values.instagram}
/>
</li>
</ul>
<button>Cadastre-se</button>
</form>
<Field
type="text"
id="nome"
name="nome"
placeholder="Seu nome completo"
className={errors.nome && touched.nome && "invalid"}
/>
</div>
<div className={styles["form-col"]}>
<div className={styles["form-text"]}>
<label htmlFor="email">E-mail</label>
<ErrorMessage
component="span"
name="email"
className={styles["form-error"]}
/>
</div>
<Field
type="text"
id="email"
name="email"
placeholder="Seu e-mail"
className={errors.email && touched.email && "invalid"}
/>
</div>
<div className={styles["form-col"]}>
<div className={styles["form-text"]}>
<label htmlFor="cpf">CPF</label>
<ErrorMessage
component="span"
name="cpf"
className={styles["form-error"]}
/>
</div>
<Field
type="text"
id="cpf"
name="cpf"
placeholder="000.000.000-00"
className={errors.cpf && touched.cpf && "invalid"}
/>
</div>
<div className={styles["form-col"]}>
<div className={styles["form-text"]}>
<label htmlFor="nascimento">Data de Nascimento:</label>
<ErrorMessage
component="span"
name="nascimento"
className={styles["form-error"]}
/>
</div>
<Field
type="text"
id="nascimento"
name="nascimento"
placeholder="00.00.0000"
className={errors.nascimento && touched.nascimento && "invalid"}
/>
</div>
<div className={styles["form-col"]}>
<div className={styles["form-text"]}>
<label htmlFor="tel">Telefone</label>
<ErrorMessage
component="span"
name="tel"
className={styles["form-error"]}
/>
</div>
<Field
type="text"
id="tel"
name="tel"
placeholder="(00) 00000-0000"
className={errors.tel && touched.tel && "invalid"}
/>
</div>
<div className={styles["form-col"]}>
<div className={styles["form-text"]}>
<label htmlFor="instagram">Instagram</label>
<ErrorMessage
component="span"
name="instagram"
className={styles["form-error"]}
/>
</div>
<Field
type="text"
id="instagram"
name="instagram"
placeholder="@seuuser"
className={errors.instagram && touched.instagram && "invalid"}
/>
</div>
<div className={styles["form-col"] && styles["form-check"]}>
<div className={styles["form-text-check"]}>
<ErrorMessage
component="span"
name="termos"
className={styles["form-error"]}
/>
<label htmlFor="check">
<a href="/">Declaro que li e aceito</a>
</label>
</div>
<Field
type="checkbox"
id="check"
name="termos"
className={
errors.termos &&
touched.termos &&
"invalid" &&
styles["form-checkbox"]
}
/>
</div>
<button className={styles["form-btn"]} type="submit">
Cadastre-se
</button>
</Form>
)}
</Formik>
</div>
);
};

View File

@ -1,4 +1,4 @@
.form {
/*.form {
display: flex;
flex-direction: column;
}
@ -7,3 +7,114 @@
flex-direction: column;
margin-bottom: 10px;
}
.textForm {
display: flex;
flex-direction: row;
}
.errorFormik {
margin-left: 80px;
color: red;
}
*/
.form-wrapper {
width: 100%;
max-width: 720px;
min-height: 100vh;
margin: 0 auto;
padding: 0 12px;
display: flex;
justify-content: center;
flex-direction: column;
}
.form-wrapper h2 {
font-weight: 700;
font-size: 27px;
margin: 0 0 12px 0;
@media screen and (min-width: 2500px) {
font-size: 48px;
}
}
.form-wrapper form {
width: 100%;
}
.form-col {
display: flex;
flex-direction: column;
margin-bottom: 12px;
}
.form-col label {
font-weight: 400;
font-size: 14px;
color: #100d0e;
margin: 0 0 4px 0;
@media screen and (min-width: 2500px) {
font-size: 28px;
}
}
.form-col input {
background: #ffffff;
border: 1px solid #100d0e;
border-radius: 25px;
height: 46px;
padding: 10px 0 15px 20px;
&::placeholder {
font-family: "Roboto";
font-size: 14px;
color: #b9b7b7;
}
@media screen and (min-width: 2500px) {
height: 63px;
&::placeholder {
font-size: 28px;
}
}
}
.form-wrapper button {
width: 100%;
height: 52.44px;
background: #000000;
border-radius: 25px;
color: #ffffff;
font-family: "Roboto";
font-size: 16px;
text-transform: uppercase;
letter-spacing: 0.05em;
font-weight: 400;
@media screen and (min-width: 2500px) {
height: 71px;
font-size: 32px;
}
}
.form-text {
display: flex;
justify-content: space-between;
}
.form-error {
color: red;
}
.form-check {
display: flex;
flex-direction: rows;
justify-content: center;
align-items: center;
}
.form-check label {
a {
color: #000;
}
margin-right: 5px;
}
.form-checkbox {
}
#check {
font-size: 15px;
border: 1px solid #000000;
border-radius: 3px;
}
.form-btn {
margin-top: 12px;
}

View File

@ -1,11 +1,11 @@
import React from "react";
import { NavigationBar } from "../components/NavigationBar/NavigationBar";
import { AccordionBody } from "../components/AccordionBody/AccordionBody";
const Home = () => {
//const style = { background: "black" };
return (
<div /*style={style}*/>
<NavigationBar></NavigationBar>
<AccordionBody />
</div>
);
};

View File

@ -18,3 +18,12 @@ button {
li {
list-style-type: none;
}
/*
$grid-breakpoints: (
xs: 0,
sm: 375px,
md: 768px,
lg: 1025px,
xl: 1280px,
xxl: 2500px,
);*/

View File

@ -8183,7 +8183,7 @@
"react-is" "^16.3.2"
"warning" "^4.0.0"
"prop-types@^15.6.2", "prop-types@^15.8.1":
"prop-types@^15.5.6", "prop-types@^15.6.2", "prop-types@^15.8.1":
"integrity" "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="
"resolved" "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz"
"version" "15.8.1"
@ -8449,6 +8449,13 @@
optionalDependencies:
"fsevents" "^2.3.2"
"react-text-mask@^5.5.0":
"integrity" "sha512-SLJlJQxa0uonMXsnXRpv5abIepGmHz77ylQcra0GNd7Jtk4Wj2Mtp85uGQHv1avba2uI8ZvRpIEQPpJKsqRGYw=="
"resolved" "https://registry.npmjs.org/react-text-mask/-/react-text-mask-5.5.0.tgz"
"version" "5.5.0"
dependencies:
"prop-types" "^15.5.6"
"react-transition-group@^4.4.2":
"integrity" "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g=="
"resolved" "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz"
@ -8459,7 +8466,7 @@
"loose-envify" "^1.4.0"
"prop-types" "^15.6.2"
"react@^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", "react@^18.0.0", "react@^18.2.0", "react@>= 16", "react@>=0.14.0", "react@>=15.0.0", "react@>=16.14.0", "react@>=16.6.0", "react@>=16.8.0":
"react@^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", "react@^18.0.0", "react@^18.2.0", "react@>= 16", "react@>=0.14.0", "react@>=15.0.0", "react@>=16.14.0", "react@>=16.6.0", "react@>=16.8.0":
"integrity" "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ=="
"resolved" "https://registry.npmjs.org/react/-/react-18.2.0.tgz"
"version" "18.2.0"