Commit dd591871 authored by Nurasyl's avatar Nurasyl

Добавил компоненты для продуктов

parent 4fafab66
import { Link } from 'react-router-dom';
import { Grid, Card, CardHeader, CardContent, CardActions, IconButton, Typography } from '@mui/material';
import { ArrowForward } from '@mui/icons-material';
import { IProduct } from '@/interfaces/IProduct';
interface Props {
product: IProduct;
}
export function ProductItem({ product }: Props) {
const { title, price, id, description } = product;
return (
<Grid item xs={12} sm={12} md={6} lg={4}>
<Card sx={{ minWidth: 275 }}>
<CardHeader title={title} />
<CardContent>
<Typography variant="body2">{description}</Typography>
<strong style={{ marginLeft: '10px' }}>Price: {price} KZT</strong>
</CardContent>
<CardActions>
<IconButton component={Link} to={`/products/${id}`}>
<ArrowForward />
</IconButton>
</CardActions>
</Card>
</Grid>
);
}
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { Typography, Grid, Button } from '@mui/material'; import { Typography, Grid, Button } from '@mui/material';
import { useAppDispatch, useAppSelector } from '../../store';
import { shallowEqual } from 'react-redux';
import { useEffect } from 'react';
import { fetchProducts } from '../../features/productsSlice';
import { ProductItem } from './ProductItem';
export function Products() { export function Products() {
const dispatch = useAppDispatch();
const { products } = useAppSelector((state) => state.products, shallowEqual);
useEffect(() => {
dispatch(fetchProducts());
}, [dispatch]);
return ( return (
<Grid container direction="column" spacing={2}> <>
<Grid item container direction="row" justifyContent="space-between" alignItems="center"> <Grid container direction="column" spacing={2}>
<Grid item> <Grid item container direction="row" justifyContent="space-between" alignItems="center">
<Typography variant="h4">Products</Typography> <Grid item>
</Grid> <Typography variant="h4">Products</Typography>
</Grid>
<Grid item> <Grid item>
<Button color="primary" component={Link} to={'/products/new'}> <Button color="primary" component={Link} to={'/products/new'}>
Add product Add product
</Button> </Button>
</Grid>
</Grid> </Grid>
</Grid> </Grid>
</Grid>
<Grid item container direction="row" spacing={1}>
{products.map((product) => (
<ProductItem key={product.id} product={product} />
))}
</Grid>
</>
); );
} }
import { createSlice } from '@reduxjs/toolkit'; import { axiosApiClient } from "../helpers/axiosApiClient";
import { IProduct } from "../interfaces/IProduct";
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
const initialState = {};
interface State {
products: IProduct[];
error: Error | null;
loading: boolean;
}
const initialState: State = {
products: [],
error: null,
loading: false,
};
export const fetchProducts = createAsyncThunk('fetch/products', async () => {
return await axiosApiClient.get<IProduct[]>('/products').then((res) => res.data);
});
const productsSlice = createSlice({ const productsSlice = createSlice({
name: 'products', name: 'products',
initialState, initialState,
reducers: {}, reducers: {},
extraReducers: (builder) => {
builder
.addCase(fetchProducts.fulfilled, (state, action) => {
state.products = action.payload;
state.loading = false;
})
.addCase(fetchProducts.rejected, (state, action) => {
state.error = action.error as Error;
state.loading = false;
})
.addCase(fetchProducts.pending, (state) => {
state.loading = true;
});
},
}); });
export default productsSlice.reducer; export default productsSlice.reducer;
import axios from "axios"; import axios from 'axios';
export const axiosApiClient = axios.create({ export const axiosApiClient = axios.create({
baseURL: "http://localhost:8000" baseURL: 'http://localhost:8000',
}); });
\ No newline at end of file
export interface IProduct {
id: string;
title: string;
description: string;
price: number;
}
import { configureStore } from '@reduxjs/toolkit'; import { configureStore } from '@reduxjs/toolkit';
import productsReducer from '../features/productsSlice.ts'; import productsReducer from '../features/productsSlice.ts';
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';
const store = configureStore({ const store = configureStore({
reducer: { reducer: {
...@@ -7,4 +8,10 @@ const store = configureStore({ ...@@ -7,4 +8,10 @@ const store = configureStore({
}, },
}); });
type RootState = ReturnType<typeof store.getState>;
type AppDispatch = typeof store.dispatch;
export const useAppDispatch: () => AppDispatch = useDispatch;
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
export default store; export default store;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment