Skip to content

Commit

Permalink
form is added
Browse files Browse the repository at this point in the history
  • Loading branch information
Blenemy committed Aug 7, 2023
1 parent 6fcd98f commit 069d51e
Show file tree
Hide file tree
Showing 9 changed files with 2,705 additions and 435 deletions.
2,815 changes: 2,455 additions & 360 deletions package-lock.json

Large diffs are not rendered by default.

9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@
"@fortawesome/fontawesome-svg-core": "^6.4.0",
"@fortawesome/free-solid-svg-icons": "^6.4.0",
"@fortawesome/react-fontawesome": "^0.2.0",
"@material-ui/core": "^4.12.4",
"@mui/material": "^5.13.4",
"@mui/material": "^5.14.3",
"@reduxjs/toolkit": "^1.9.5",
"@uidotdev/usehooks": "^2.0.1",
"bulma": "^0.9.3",
"classnames": "^2.3.2",
"react": "^17.0.2",
"react-bootstrap": "^2.8.0",
"react-dom": "^17.0.2",
"react-redux": "^8.1.2",
"react-router-dom": "^6.10.0",
Expand All @@ -35,6 +34,9 @@
"@types/node": "^17.0.23",
"@types/react": "^17.0.43",
"@types/react-dom": "^17.0.14",
"@typescript-eslint/eslint-plugin": "^6.2.1",
"@typescript-eslint/parser": "^6.2.1",
"autoprefixer": "^10.4.14",
"cypress": "^9.5.3",
"eslint": "^7.32.0",
"eslint-plugin-cypress": "^2.11.2",
Expand All @@ -43,6 +45,7 @@
"mochawesome-merge": "^4.2.0",
"mochawesome-report-generator": "^6.2.0",
"node-sass": "^6.0.1",
"postcss": "^8.4.27",
"stylelint": "^13.13.1",
"typescript": "^4.6.3"
},
Expand Down
4 changes: 4 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {
import { NotFound } from './components/NotFound/NotFound';
import { useAppDispatch } from './app/hooks';
import { set } from './features/productsSlice';
import { AuthForm } from './components/AuthForm/AuthForm';
import { CreateAccount } from './components/CreateAccount/CreateAccount';

const App = () => {
const dispatch = useAppDispatch();
Expand Down Expand Up @@ -81,6 +83,8 @@ const App = () => {
path="home"
element={<Navigate to="/" replace />}
/>
<Route path="authentication" element={<AuthForm />} />
<Route path="create-account" element={<CreateAccount />} />
</Routes>
<Footer />
</div>
Expand Down
27 changes: 27 additions & 0 deletions src/components/AuthForm/AuthForm.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
$width-var: 320px;

.form {
display: flex;
flex-direction: column;
max-width: 700px;
margin: 0 auto 20px;

&__button {
min-width: 400px !important;
}

&__title {
margin-bottom: 20px;
}
}

.register {
display: flex;
justify-content: center;
gap: 20px;
&__button {
text-align: center;
color: #42aa19 !important;
}

}
83 changes: 83 additions & 0 deletions src/components/AuthForm/AuthForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { useState } from 'react';
import { TextField, Button } from '@mui/material';
import './AuthForm.scss';
import { Link } from 'react-router-dom';

export const AuthForm = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [emailError, setEmailError] = useState(false);
const [passwordError, setPasswordError] = useState(false);

const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();

setEmailError(false);
setPasswordError(false);

if (email === '') {
setEmailError(true);
}

if (password === '') {
setPasswordError(true);
}

if (email && password) {
setEmail('');
setPassword('');
}
};

return (
<>
<form className="form" autoComplete="off" onSubmit={handleSubmit}>
<h2 className="form__title">Login Form</h2>
<TextField
label="Email"
onChange={e => setEmail(e.target.value)}
required
variant="outlined"
color="secondary"
type="email"
sx={{ mb: 3 }}
fullWidth
value={email}
error={emailError}
className="form__input"
/>
<TextField
label="Password"
onChange={e => setPassword(e.target.value)}
required
variant="outlined"
color="secondary"
type="password"
value={password}
error={passwordError}
fullWidth
sx={{ mb: 3 }}
className="form__input"
/>
<Button
variant="outlined"
color="secondary"
type="submit"
className="form__button"
>
Login
</Button>
</form>
<small className="register">
Need an account?
{' '}
<Link
className="register__button"
to="/create-account"
>
Register here
</Link>
</small>
</>
);
};
90 changes: 90 additions & 0 deletions src/components/CreateAccount/CreateAccount.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import React, { useState } from 'react';
import {
TextField, Button, Stack,
} from '@mui/material';
import { Link } from 'react-router-dom';

export const CreateAccount = () => {
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');

function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
event.preventDefault();
}

return (
<>
<form className="form" onSubmit={handleSubmit} action="POST">
<h2 className="form__title">Register Form</h2>
<Stack spacing={2} direction="row" sx={{ marginBottom: 4 }}>
<TextField
type="text"
variant="outlined"
color="secondary"
label="First Name"
onChange={e => setFirstName(e.target.value)}
value={firstName}
fullWidth
required
className="form__input"
/>
<TextField
type="text"
variant="outlined"
color="secondary"
label="Last Name"
onChange={e => setLastName(e.target.value)}
value={lastName}
fullWidth
required
className="form__input"
/>
</Stack>
<TextField
type="email"
variant="outlined"
color="secondary"
label="Email"
onChange={e => setEmail(e.target.value)}
value={email}
fullWidth
required
sx={{ mb: 4 }}
className="form__input"
/>
<TextField
type="password"
variant="outlined"
color="secondary"
label="Password"
onChange={e => setPassword(e.target.value)}
value={password}
required
fullWidth
sx={{ mb: 4 }}
className="form__input"
/>
<Button
variant="outlined"
color="secondary"
type="submit"
className="form__button"
>
Register
</Button>
</form>
<small className="register">
Already have an account?
<Link
className="register__button"
to="/authentication"
>
Login Here
</Link>
</small>

</>
);
};
2 changes: 1 addition & 1 deletion src/components/NoResults/NoResults.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import './NoResults.scss';

export const NoResults: React.FC<{ category: string }> = ({ category }) => {
return (
<div className="results-not-found">
<div className="results-not-found bg-blue-500">
{category === 'cart' ? (
'Your cart is empty'
) : (
Expand Down
57 changes: 20 additions & 37 deletions src/pages/AccessoriesPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,27 @@ import {
useEffect, useState, useCallback, useMemo,
} from 'react';
import { useSearchParams } from 'react-router-dom';
import {
updateSearchParams, sortProducts,
} from '../helpers/helper';
import { Pagination } from '../components/Pagination/Pagination';
import { updateSearchParams, sortProducts } from '../helpers/helper';
import { useAppSelector } from '../app/hooks';
import { Product } from '../types/Products';
import { SortOption } from '../types/SortOption';
import { ItemsPerPage } from '../types/ItemsPerPage';
import { ProductCard } from '../components/ProductCard/ProductCard';
import { PageIndicator } from '../components/PageIndicator/PageIndicator';
import './ProductPage.scss';
import { NoResults } from '../components/NoResults/NoResults';
import { useAppSelector } from '../app/hooks';
import { SortOption } from '../types/SortOption';

type ItemsPerPage = '4' | '8' | '16' | 'All';
import { Pagination } from '../components/Pagination/Pagination';
import { SelectTemplate } from '../components/SelectTemplate/SelectTemplate';

export const AccessoriesPage: React.FC = () => {
const category = 'accessories';
const { products } = useAppSelector(state => state.products);
const [searchParams, setSearchParams] = useSearchParams();
const itemsPerPage = searchParams.get('perPage') as ItemsPerPage || '4';
const sortPage = searchParams.get('sort') as SortOption || 'age';
const query = searchParams.get('query');
const currentPageFromParams = Number(searchParams.get('page') || '1');
const [currentPage, setCurrentPage] = useState(currentPageFromParams);
const { products } = useAppSelector(state => state.products);

const handleOnChange = useCallback((
event: React.ChangeEvent<HTMLSelectElement>,
Expand Down Expand Up @@ -104,34 +103,18 @@ export const AccessoriesPage: React.FC = () => {
{product.length > 0 ? (
<>
<div className={`${category}-page__navigation-filter`}>
<div className={`${category}-page__sort-by`}>
<label className={`${category}-page__label`} htmlFor="sort-by">Sort by:</label>
<select
className={`${category}-page__select`}
id="sort-by"
name="sort-by"
onChange={handleOnChange}
>
<option value="age">Newest</option>
<option value="price">Cheapest</option>
<option value="name">Alphabetically</option>
</select>
</div>
<div className={`${category}-page__items-per-page`}>
<label className={`${category}-page__label`} htmlFor="items-per-page">Items per page:</label>
<select
className={`${category}-page__select`}
id="items-per-page"
name="items-per-page"
onChange={handleItemsPerPage}
value={itemsPerPage}
>
<option value="4">4</option>
<option value="8">8</option>
<option value="16">16</option>
<option value="All">All</option>
</select>
</div>
<SelectTemplate
category={category}
onChange={handleOnChange}
value={sortPage}
sortBy="age"
/>
<SelectTemplate
category={category}
onChange={handleItemsPerPage}
value={itemsPerPage}
sortBy="page"
/>
</div>
<div data-cy="productList" className={`${category}-page__row`}>
{paginatedProducts?.map((item) => (
Expand Down
Loading

0 comments on commit 069d51e

Please sign in to comment.