Skip to content

Commit

Permalink
Merge pull request #15 from MargoMarm/feature/authForm
Browse files Browse the repository at this point in the history
Feature/auth form
  • Loading branch information
MargoMarm authored Sep 16, 2023
2 parents 1dfe2ba + 082ceec commit 6cab03c
Show file tree
Hide file tree
Showing 19 changed files with 330 additions and 24 deletions.
17 changes: 17 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@vitejs/plugin-react-swc": "^3.3.2",
"axios": "^1.5.0",
"formik": "^2.4.4",
"modern-normalize": "^2.0.0",
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
14 changes: 14 additions & 0 deletions src/assets/sprite.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions src/components/AuthButton/AuthButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import PropTypes from 'prop-types';
import { AuthBtn } from './AuthButton.styled';

export default function AuthButton({ title }) {
return <AuthBtn type="submit">{title}</AuthBtn>;
}

AuthButton.propTypes = {
title: PropTypes.string.isRequired,
};
21 changes: 21 additions & 0 deletions src/components/AuthButton/AuthButton.styled.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import styled from '@emotion/styled';
import { colors, mq } from '../../utils';

export const AuthBtn = styled.button`
display: inline-flex;
align-items: center;
justify-content: center;
padding: 12px 40px;
outline: none;
background-color: ${colors.orange};
border-radius: 12px;
border: none;
color: ${colors.white};
font-size: 16px;
font-weight: 500;
line-height: 112.5%;
${mq.tablet} {
padding: 16px 60px;
}
`;
1 change: 1 addition & 0 deletions src/components/AuthButton/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './AuthButton';
Empty file removed src/components/AuthForm/.gitkeep
Empty file.
147 changes: 147 additions & 0 deletions src/components/AuthForm/AuthForm.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import PropTypes from 'prop-types';
import * as Yup from 'yup';
import { Formik, ErrorMessage } from 'formik';
import sprite from '../../assets/sprite.svg';

import {
TextInput,
FormContainer,
Error,
InputContainer,
InputWrapper,
HidePasswordbtn,
Warning,
} from './AuthForm.styled';
import AuthButton from '../AuthButton';
import { useState } from 'react';

const authSchema = Yup.object().shape({
name: Yup.string().required('Name is required'),
email: Yup.string()
.matches(/^\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,3}$/, {
message: 'Email must be valid',
})
.email('Invalid email')
.required('Email is required'),
password: Yup.string()
.matches(/^(&=.*[a-zA-Z]{6})(?=.*\d)[a-zA-Z\d]{7}$/, {
message: 'password must have ...',
})
.required('Password is required'),
});

export default function AuthForm({ nameIsShown, btnTitle }) {
const [isPasswordShown, setIsPasswordShown] = useState(false);
const [typePasswordInput, setTypePasswordInput] = useState('password');

const initialValues = nameIsShown
? {
name: '',
email: '',
password: '',
}
: { email: '', password: '' };

const toglePassword = () => {
setIsPasswordShown(prevstate => {
return !prevstate;
});
setTypePasswordInput(prevstate => {
if (prevstate === 'password') {
return 'text';
}
if (prevstate === 'text') {
return 'password';
}
});
};

return (
<Formik
initialValues={initialValues}
onSubmit={values => {
console.log(values);
}}
validationSchema={authSchema}
>
<FormContainer>
<InputContainer>
{nameIsShown && (
<InputWrapper>
<TextInput id="name" type="text" placeholder="name" name="name" />
<Warning>
<ErrorMessage name="name">
{msg => (
<Error>
<svg width="20" height="20">
<use href={sprite + `#icon-checkbox-circle-fill`}></use>
</svg>
{msg}
</Error>
)}
</ErrorMessage>
</Warning>
</InputWrapper>
)}
<InputWrapper>
<TextInput
id="email"
type="email"
placeholder="email"
name="email"
/>
<Warning>
<ErrorMessage name="email">
{msg => (
<Error>
<svg width="20" height="20">
<use href={sprite + `#icon-checkbox-circle-fill`}></use>
</svg>
{msg}
</Error>
)}
</ErrorMessage>
</Warning>
</InputWrapper>
<InputWrapper>
<TextInput
id="password"
type={typePasswordInput}
placeholder="password"
name="password"
/>
<HidePasswordbtn onClick={toglePassword}>
<svg width="20" height="20">
<use
href={
sprite +
`${isPasswordShown ? `#icon-eye-off` : `#icon-eye`}`
}
></use>
</svg>
</HidePasswordbtn>
<Warning>
<ErrorMessage name="password">
{msg => (
<Error>
<svg width="20" height="20">
<use href={sprite + `#icon-checkbox-circle-fill`}></use>
</svg>
{msg}
</Error>
)}
</ErrorMessage>
</Warning>
</InputWrapper>
</InputContainer>
<AuthButton title={btnTitle} />
</FormContainer>
</Formik>
);
}

AuthForm.propTypes = {
nameIsShown: PropTypes.bool.isRequired,
btnTitle: PropTypes.string.isRequired,
onSubmit: PropTypes.func.isRequired,
};
87 changes: 87 additions & 0 deletions src/components/AuthForm/AuthForm.styled.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import styled from '@emotion/styled';
import { colors, mq } from '../../utils';
import { Form, Field } from 'formik';

export const FormContainer = styled(Form)`
width: 335px;
margin-top: 28px;
${mq.tablet} {
margin-top: 32px;
width: 364px;
}
`;

export const InputContainer = styled.div`
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 14px;
margin-bottom: 28px;
${mq.tablet} {
gap: 20px;
margin-bottom: 64px;
}
`;

export const InputWrapper = styled.div`
position: relative;
width: 100%;
`;

export const TextInput = styled(Field)`
height: 42px;
width: 100%;
${mq.tablet} {
height: 48px;
}
padding-left: 14px;
padding-right: 14px;
border-radius: 12px;
border: 1px solid ${colors.textWhite03};
font-size: 16px;
font-weight: 400;
line-height: 150%;
outline: none;
color: ${colors.textWhite06};
background-color: transparent;
&:focus-visible {
border: 1px solid ${colors.orange};
}
`;

export const Warning = styled.div`
position: absolute;
`;

export const Error = styled.div`
display: flex;
align-items: center;
justify-content: center;
gap: 4px;
font-size: 12px;
color: ${colors.textError};
`;

export const HidePasswordbtn = styled.button`
position: absolute;
top: 50%;
right: 16px;
transform: translateY(-50%);
width: 20px;
height: 20px;
padding: 0;
border: none;
outline: none;
display: inline-flex;
align-items: center;
justify-content: center;
${mq.tablet} {
right: 14px;
}
background-color: transparent;
stroke: ${colors.white};
`;
1 change: 1 addition & 0 deletions src/components/AuthForm/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './AuthForm';
2 changes: 1 addition & 1 deletion src/components/SharedLayout/SheradLayout.styled.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { mq } from '../../utils';

export const Container = styled.div`
margin: 0px auto;
/* padding: 0px 20px; */
padding: 0px 20px;
${mq.mobile} {
width: 375px;
Expand Down
1 change: 1 addition & 0 deletions src/components/SubTitle/SubTitle.styled.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export const SubStyle = styled.p`
${mq.tablet} {
max-width: 496px;
font-size: 16px;
line-height: 1.5;
}
Expand Down
6 changes: 5 additions & 1 deletion src/components/Title/Title.styled.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@ export const StyledTitle = styled.h2`
${mq.tablet} {
margin-bottom: ${props => props.margin + 2}px;
margin-top: 105px;
font-size: 32px;
line-height: 1.11;
letter-spacing: 0.7px;
}
${mq.desktop} {
margin-top: 116px;
}
`;
2 changes: 2 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@import 'node_modules/modern-normalize/modern-normalize.css';

@font-face {
font-family: 'Roboto';
font-weight: 400;
Expand Down
8 changes: 4 additions & 4 deletions src/pages/Home/Home.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import CustomNavLink from "../../components/CustomNavLink/CustomNavLink";
import MainTitle from "../../components/MainTitle/MainTitle";
import Header from "../../components/headersComp/Header/Header";
import { LinkList, Wrapper } from "./Home.styled";
import CustomNavLink from '../../components/CustomNavLink/CustomNavLink';
import MainTitle from '../../components/MainTitle/MainTitle';
import Header from '../../components/headersComp/Header/Header';
import { LinkList, Wrapper } from './Home.styled';

const Home = () => {
return (
Expand Down
1 change: 0 additions & 1 deletion src/pages/Home/Home.styled.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ export const Wrapper = styled.div`
}
}
${mq.desktop} {
height: 800px;
background-image: url(${imgForHome.imgDx1});
background-size: 670px 800px;
Expand Down
Loading

0 comments on commit 6cab03c

Please sign in to comment.