Просмотр исходного кода

Merge branch 'products-typescript' of ntasicc/coffee-ts into master

master
lazarkostic 3 лет назад
Родитель
Сommit
56e835ccf1

+ 1
- 0
components/company-info/CompanyInfo.tsx Просмотреть файл

import { Box } from '@mui/system'; import { Box } from '@mui/system';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import Image from 'next/image'; import Image from 'next/image';

const CompanyInfo: React.FC = () => { const CompanyInfo: React.FC = () => {
const { t } = useTranslation('home'); const { t } = useTranslation('home');
return ( return (

+ 3
- 2
components/filter-sort/FilterSort.tsx Просмотреть файл

import { Box } from '@mui/system'; import { Box } from '@mui/system';
import ProductType from '../product-type/ProductType'; import ProductType from '../product-type/ProductType';
import Sort from '../sort/Sort'; import Sort from '../sort/Sort';
import { SelectChangeEvent } from "@mui/material";


interface FilterSortProps { interface FilterSortProps {
sort: string; sort: string;
handleSortChange: () => void;
handleSortChange: (e: SelectChangeEvent) => void;
productType: string; productType: string;
handleProductTypeChange: () => void;
handleProductTypeChange: (e: SelectChangeEvent) => void;
} }


const FilterSort: React.FC<FilterSortProps> = ({ const FilterSort: React.FC<FilterSortProps> = ({

+ 2
- 2
components/forms/forgot-password/ForgotPasswordForm.tsx Просмотреть файл

import { forgotPasswordSchema } from '../../../schemas/forgotPasswordSchema'; import { forgotPasswordSchema } from '../../../schemas/forgotPasswordSchema';


const ForgotPasswordForm = () => { const ForgotPasswordForm = () => {
const { t } = useTranslation('forms', 'forgotPass', 'common');
const { t } = useTranslation(['forms', 'forgotPass', 'common']);


const handleSubmit = (values) => {
const handleSubmit = (values: {email: string}) => {
console.log('Values', values); console.log('Values', values);
}; };



+ 9
- 4
components/forms/login/LoginForm.tsx Просмотреть файл

import { loginSchema } from '../../../schemas/loginSchema'; import { loginSchema } from '../../../schemas/loginSchema';
import ErrorMessageComponent from '../../mui/ErrorMessageComponent'; import ErrorMessageComponent from '../../mui/ErrorMessageComponent';


interface Values {
username: string;
password: string;
}

const LoginForm = () => { const LoginForm = () => {
const { t } = useTranslation('forms', 'login');
const { t } = useTranslation(['forms', 'login']);
const [showPassword, setShowPassword] = useState(false); const [showPassword, setShowPassword] = useState(false);
const handleClickShowPassword = () => setShowPassword(!showPassword); const handleClickShowPassword = () => setShowPassword(!showPassword);
const handleMouseDownPassword = () => setShowPassword(!showPassword); const handleMouseDownPassword = () => setShowPassword(!showPassword);
const router = useRouter(); const router = useRouter();
const [error, setError] = useState({ hasError: false, errorMessage: '' }); const [error, setError] = useState({ hasError: false, errorMessage: '' });


const submitHandler = async (values) => {
const submitHandler = async (values: Values) => {
const result = await signIn('credentials', { const result = await signIn('credentials', {
redirect: false, redirect: false,
username: values.username, username: values.username,
password: values.password, password: values.password,
}); });
if (!result.error) {
if (!result?.error) {
router.replace(BASE_PAGE); router.replace(BASE_PAGE);
} else { } else {
setError({ hasError: true, errorMessage: result.error });
setError({ hasError: true, errorMessage: result?.error });
} }
}; };



+ 17
- 3
components/forms/register/RegisterForm.tsx Просмотреть файл

import { registerSchema } from '../../../schemas/registerSchema'; import { registerSchema } from '../../../schemas/registerSchema';
import ErrorMessageComponent from '../../mui/ErrorMessageComponent'; import ErrorMessageComponent from '../../mui/ErrorMessageComponent';


interface Values {
fullName: string;
username: string;
email: string;
password: string;
address: string;
address2: string;
city: string;
country: string;
postcode: string;
}

const RegisterForm = () => { const RegisterForm = () => {
const { t } = useTranslation('forms', 'register');
const { t } = useTranslation(['forms', 'register']);
const router = useRouter(); const router = useRouter();


const [showPassword, setShowPassword] = useState(false); const [showPassword, setShowPassword] = useState(false);


const [error, setError] = useState({ hasError: false, errorMessage: '' }); const [error, setError] = useState({ hasError: false, errorMessage: '' });


const submitHandler = async (values) => {
const submitHandler = async (values: Values) => {
try { try {
const result = await createUser( const result = await createUser(
values.fullName, values.fullName,
); );
router.push(LOGIN_PAGE); router.push(LOGIN_PAGE);
} catch (error) { } catch (error) {
setError({ hasError: true, errorMessage: error.message });
if (error instanceof Error) {
setError({ hasError: true, errorMessage: error?.message });
}
} }
}; };



+ 5
- 1
components/grid-item/GridItem.tsx Просмотреть файл

import { Grid } from '@mui/material'; import { Grid } from '@mui/material';


const GridItem = ({ children }) => {
interface Props {
children: JSX.Element
}

const GridItem: React.FC<Props> = ({ children }) => {
return ( return (
<Grid item md={4} sm={6} xs={12} sx={{ mb: '100px' }}> <Grid item md={4} sm={6} xs={12} sx={{ mb: '100px' }}>
{children} {children}

+ 1
- 1
components/hero/Hero.tsx Просмотреть файл

import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import { PRODUCTS_PAGE } from '../../constants/pages'; import { PRODUCTS_PAGE } from '../../constants/pages';


const Hero = () => {
const Hero: React.FC = () => {
const { t } = useTranslation('home'); const { t } = useTranslation('home');


const router = useRouter(); const router = useRouter();

+ 1
- 1
components/loader/basic-spinner/LoadSpinner.tsx Просмотреть файл

const { CircularProgress, Box } = require('@mui/material'); const { CircularProgress, Box } = require('@mui/material');


const LoadingSpinner = () => {
const LoadingSpinner: React.FC = () => {
return ( return (
<Box display="flex" justifyContent="center" sx={{ mt: 5 }}> <Box display="flex" justifyContent="center" sx={{ mt: 5 }}>
<CircularProgress /> <CircularProgress />

+ 2
- 2
components/product-type/ProductType.tsx Просмотреть файл

import { FormControl, InputLabel, MenuItem, Select } from '@mui/material';
import { FormControl, InputLabel, MenuItem, Select, SelectChangeEvent } from '@mui/material';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';


interface ProductTypeProps { interface ProductTypeProps {
productType: string; productType: string;
handleProductTypeChange: () => void;
handleProductTypeChange: (e: SelectChangeEvent) => void;
} }


const ProductType: React.FC<ProductTypeProps> = ({ productType, handleProductTypeChange }) => { const ProductType: React.FC<ProductTypeProps> = ({ productType, handleProductTypeChange }) => {

+ 8
- 13
components/products-content/ProductsContent.tsx Просмотреть файл

import { SelectChangeEvent } from '@mui/material';
import { Box } from '@mui/system'; import { Box } from '@mui/system';
import Head from 'next/head'; import Head from 'next/head';
import { useState } from 'react'; import { useState } from 'react';
import LoadingSpinner from '../loader/basic-spinner/LoadSpinner'; import LoadingSpinner from '../loader/basic-spinner/LoadSpinner';
import ProductsGrid from '../products-grid/ProductsGrid'; import ProductsGrid from '../products-grid/ProductsGrid';
import ProductsHero from '../products-hero/ProductsHero'; import ProductsHero from '../products-hero/ProductsHero';
import { SelectChangeEvent } from "@mui/material";


const ProductsContent = () => {
const ProductsContent: React.FC = () => {
const [filter, setFilter] = useState<string>(''); const [filter, setFilter] = useState<string>('');
const [sort, setSort] = useState<string>(''); const [sort, setSort] = useState<string>('');
const { data, isLoading, fetchNextPage, hasNextPage, isFetchingNextPage } = const { data, isLoading, fetchNextPage, hasNextPage, isFetchingNextPage } =
useInfiniteProducts(filter, sort); useInfiniteProducts(filter, sort);


const handleProductTypeChange = () => {
return (event: SelectChangeEvent) => {
const filterText = event.target.value;
setFilter(filterText);
}
const handleProductTypeChange = (event: SelectChangeEvent) => {
const filterText = event.target.value;
setFilter(filterText);
}; };


const handleSortChange = () => {
return (event: SelectChangeEvent) => {
const sort = event.target.value;
setSort(sort);
}

const handleSortChange = (event: SelectChangeEvent) => {
const sort = event.target.value;
setSort(sort);
}; };


return ( return (

+ 21
- 1
components/products-grid/ProductsGrid.tsx Просмотреть файл

import { Container, Grid } from '@mui/material'; import { Container, Grid } from '@mui/material';
import { Box } from '@mui/system'; import { Box } from '@mui/system';
import { ProductDataDB } from '../../utils/interface/productInterface';
import LoadMore from '../buttons/load-more/LoadMore'; import LoadMore from '../buttons/load-more/LoadMore';
import GridItem from '../grid-item/GridItem'; import GridItem from '../grid-item/GridItem';
import ProductCard from '../product-card/ProductCard'; import ProductCard from '../product-card/ProductCard';


const ProductsGrid = ({
interface PageProps {
message: string;
next: string;
prevous: string;
product: ProductDataDB[];
productCount: number;
}

interface ProductsProps {
pages: PageProps[];
}

interface Props {
allProducts: ProductsProps
hasNextPage: boolean;
isFetchingNextPage: boolean;
fetchNextPage: () => void;
}

const ProductsGrid: React.FC<Props> = ({
allProducts, allProducts,
hasNextPage, hasNextPage,
fetchNextPage, fetchNextPage,

+ 1
- 1
components/products-hero/ProductsHero.tsx Просмотреть файл

import { Box } from '@mui/system'; import { Box } from '@mui/system';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';


const ProductsHero = () => {
const ProductsHero: React.FC = () => {
const { t } = useTranslation('products'); const { t } = useTranslation('products');
return ( return (
<Box <Box

+ 0
- 1
components/products/featured-product/ProductInfo.tsx Просмотреть файл

import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import Image from 'next/image'; import Image from 'next/image';
import { useState } from 'react'; import { useState } from 'react';
import { ProductDataDB } from '../../../utils/interface/productInterface';


interface DataProps { interface DataProps {
name: string; name: string;

+ 2
- 2
components/sort/Sort.tsx Просмотреть файл

import { FormControl, InputLabel, MenuItem, Select } from '@mui/material';
import { FormControl, InputLabel, MenuItem, Select, SelectChangeEvent } from '@mui/material';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';


interface SortProps { interface SortProps {
sort: string; sort: string;
handleSortChange: () => void;
handleSortChange: (e: SelectChangeEvent) => void;
} }


const Sort: React.FC<SortProps> = ({ sort, handleSortChange }) => { const Sort: React.FC<SortProps> = ({ sort, handleSortChange }) => {

+ 1
- 1
hooks/useInfiniteQuery.ts Просмотреть файл

), ),
{ {
getNextPageParam: (lastPage, pages) => { getNextPageParam: (lastPage, pages) => {
if (lastPage.next !== null) {
if (lastPage.next !== '') {
return pages.length + 1; return pages.length + 1;
} }
}, },

+ 8
- 6
pages/index.tsx Просмотреть файл

import { useUserUpdate } from '../store/user-context'; import { useUserUpdate } from '../store/user-context';
import { getStorage } from '../utils/helpers/storage'; import { getStorage } from '../utils/helpers/storage';
import { useEffect } from 'react'; import { useEffect } from 'react';
import { ProductDataDB } from '../utils/interface/productInterface';


interface Props {
data: { featuredProducts: ProductDataDB[], message: string };
}


const Home: NextPage = ({ featuredProducts }) => {
const Home: NextPage<Props> = ({ data }) => {
const { data: session } = useSession(); const { data: session } = useSession();
const { addUser } = useUserUpdate(); const { addUser } = useUserUpdate();


</Head> </Head>
<Hero /> <Hero />
<FeaturedProductsList <FeaturedProductsList
featuredProducts={featuredProducts}
featuredProducts={data.featuredProducts}
></FeaturedProductsList> ></FeaturedProductsList>
<Features /> <Features />
<CompanyInfo /> <CompanyInfo />


export async function getStaticProps({ locale }: any) { export async function getStaticProps({ locale }: any) {
try { try {
const { message, featuredProducts } = await getFeaturedProducts();
const data = await getFeaturedProducts();
return { return {
props: { props: {
...(await serverSideTranslations(locale, ["home"])), ...(await serverSideTranslations(locale, ["home"])),
message,
featuredProducts,
data: data
}, },
}; };
} catch (error) { } catch (error) {
return { return {
props: { props: {
...(await serverSideTranslations(locale, ['home'])), ...(await serverSideTranslations(locale, ['home'])),
errorMessage: error,
featuredProducts: [], featuredProducts: [],
}, },
}; };

+ 21
- 13
pages/products/[customId].tsx Просмотреть файл

import { useFetchSingleProduct } from '../../hooks/useFetchProductData'; import { useFetchSingleProduct } from '../../hooks/useFetchProductData';
import { getProductData } from '../../requests/products/producDataRequest'; import { getProductData } from '../../requests/products/producDataRequest';
import { useStore, useStoreUpdate } from '../../store/cart-context'; import { useStore, useStoreUpdate } from '../../store/cart-context';
import { SingleProductResponseGet } from '../../utils/interface/productInterface';


const SingleProduct: NextPage = () => {
interface Props {
data: SingleProductResponseGet;
}

const SingleProduct: NextPage<Props> = ({ data }) => {
const { t } = useTranslation('products'); const { t } = useTranslation('products');
const { addCartValue } = useStoreUpdate(); const { addCartValue } = useStoreUpdate();
const { cartStorage } = useStore(); const { cartStorage } = useStore();


const router = useRouter(); const router = useRouter();


const { customId } = router.query;
const customId = router.query.customId ? router.query.customId as string : undefined;


const { data, isLoading } = useFetchSingleProduct(customId);
// const { data, isLoading } = useFetchSingleProduct(customId);


const addProductToCart = (quantity) => addCartValue(data.product, quantity);
const addProductToCart = (quantity: number) => addCartValue(data?.product, quantity);
const inCart = const inCart =
cartStorage?.length > 0 cartStorage?.length > 0
? cartStorage?.some((item) => item.product.customID === product.customID)
? cartStorage?.some((item) => item.product.customID === data?.product.customID)
? true ? true
: false : false
: false; : false;


if (isLoading) {
return <Loader loading={isLoading} />;
}

return ( return (
<Box <Box
sx={{ sx={{
fontSize="32px" fontSize="32px"
sx={{ mt: 25, height: '100%', color: 'primary.main' }} sx={{ mt: 25, height: '100%', color: 'primary.main' }}
> >
{data.product.name}
{data?.product.name}
</Typography> </Typography>
<Grid container spacing={2}> <Grid container spacing={2}>
<Grid sx={{ display: 'flex' }} item md={6} sm={12}> <Grid sx={{ display: 'flex' }} item md={6} sm={12}>
<Image <Image
src={data.product.image}
src={data?.product.image}
alt="product" alt="product"
width={900} width={900}
height={700} height={700}
{t('products:similar')} {t('products:similar')}
</Typography> </Typography>
<Grid container spacing={2}> <Grid container spacing={2}>
{data.similarProducts.map((product) => (
{data?.similarProducts.map((product) => (
<GridItem key={product._id}> <GridItem key={product._id}>
<ProductCard product={product} /> <ProductCard product={product} />
</GridItem> </GridItem>
const { params } = context; const { params } = context;
const { customId } = params; const { customId } = params;


console.log(customId);

const queryClient = new QueryClient(); const queryClient = new QueryClient();


await queryClient.prefetchQuery(
const data = await queryClient.fetchQuery(
['product', customId],
async () => await getProductData(customId)
);
await queryClient.fetchQuery(
['product', customId], ['product', customId],
async () => await getProductData(customId) async () => await getProductData(customId)
); );


return { return {
props: { props: {
data: data,
dehydratatedState: dehydrate(queryClient), dehydratatedState: dehydrate(queryClient),
...(await serverSideTranslations(context.locale, ['products'])), ...(await serverSideTranslations(context.locale, ['products'])),
}, },

+ 2
- 2
utils/interface/productInterface.ts Просмотреть файл

product: ProductData; product: ProductData;
} }


interface SingleProductResponseGet {
export interface SingleProductResponseGet {
message: string; message: string;
product: ProductDataDB; product: ProductDataDB;
similarProducts: Array<ProductDataDB>; similarProducts: Array<ProductDataDB>;
| ProductsResponseError; | ProductsResponseError;


export type FeaturedProductsResponse = export type FeaturedProductsResponse =
| FeaturedProductsResponseGet
FeaturedProductsResponseGet
| ProductsResponseError; | ProductsResponseError;

Загрузка…
Отмена
Сохранить