From f66b1da0ec09ab6f5517eeb93db18a77d548b0e0 Mon Sep 17 00:00:00 2001
From: TaurusVB <114020229+TaurusVB@users.noreply.github.com>
Date: Wed, 27 Sep 2023 15:57:38 +0300
Subject: [PATCH] added dynamic changes to VideoCountExercises and
BurnedCalories statisticts on Home, Sign In, Sign Up page
---
.../ParamsBlockCard.jsx" | 4 +-
src/components/headersComp/Logo/Logo.jsx | 9 +--
src/pages/Home/Home.jsx | 31 ++++++++++
src/pages/SignIn/SignIn.jsx | 23 +++++++-
src/pages/SignUp/SignUp.jsx | 24 +++++++-
src/redux/statistic/operations.js | 26 +++++++++
src/redux/statistic/selectors.js | 13 +++++
src/redux/statistic/slice.js | 56 +++++++++++++++++++
src/redux/store.js | 4 +-
src/utils/formatNumberStatistics.js | 11 ++++
10 files changed, 188 insertions(+), 13 deletions(-)
create mode 100644 src/redux/statistic/operations.js
create mode 100644 src/redux/statistic/selectors.js
create mode 100644 src/redux/statistic/slice.js
create mode 100644 src/utils/formatNumberStatistics.js
diff --git "a/src/components/ParamsBlock\320\241ard/ParamsBlockCard.jsx" "b/src/components/ParamsBlock\320\241ard/ParamsBlockCard.jsx"
index 93339258..91f6fcfe 100644
--- "a/src/components/ParamsBlock\320\241ard/ParamsBlockCard.jsx"
+++ "b/src/components/ParamsBlock\320\241ard/ParamsBlockCard.jsx"
@@ -25,7 +25,7 @@ const ParamsBlockCard = ({ data, measure, type, step, page }) => {
- {data}+
+ {data}
Video tutorial
@@ -51,7 +51,7 @@ const ParamsBlockCard = ({ data, measure, type, step, page }) => {
};
ParamsBlockCard.propTypes = {
- data: PropTypes.number,
+ data: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
type: PropTypes.string,
measure: PropTypes.string,
step: PropTypes.string,
diff --git a/src/components/headersComp/Logo/Logo.jsx b/src/components/headersComp/Logo/Logo.jsx
index 4fafbe8b..a38a1958 100644
--- a/src/components/headersComp/Logo/Logo.jsx
+++ b/src/components/headersComp/Logo/Logo.jsx
@@ -1,7 +1,8 @@
-import { Button, WrapLogo, Svg } from './Logo.styled';
+import { WrapLogo, Svg } from './Logo.styled';
import sprite from '../../../assets/sprite.svg';
import { UseAuth } from '../../../hooks/useAuth';
+import { NavLink } from 'react-router-dom';
export const Logo = () => {
const { isLoggedIn } = UseAuth();
@@ -9,13 +10,13 @@ export const Logo = () => {
return (
<>
-
{' '}
-
+
>
);
diff --git a/src/pages/Home/Home.jsx b/src/pages/Home/Home.jsx
index 2951bcb9..d554fcc7 100644
--- a/src/pages/Home/Home.jsx
+++ b/src/pages/Home/Home.jsx
@@ -1,8 +1,26 @@
+import { useEffect } from 'react';
import CustomNavLink from '../../components/CustomNavLink/CustomNavLink';
import MainTitle from '../../components/MainTitle/MainTitle';
+import ParamsBlockCard from '../../components/ParamsBlockСard/ParamsBlockCard';
import { LinkList, Wrapper, WrapperDesktop } from './Home.styled';
+import { useDispatch, useSelector } from 'react-redux';
+import { getVideoCountAndBurnedCaloriesStatistics } from '../../redux/statistic/operations';
+import {
+ getAllExercises,
+ getUsersBurnedCalories,
+} from '../../redux/statistic/selectors';
+import formatNumber from '../../utils/formatNumberStatistics';
const Home = () => {
+ const dispatch = useDispatch();
+
+ const videoExercisesCount = useSelector(getAllExercises);
+ const allBurnedCalories = useSelector(getUsersBurnedCalories);
+
+ useEffect(() => {
+ dispatch(getVideoCountAndBurnedCaloriesStatistics());
+ }, [dispatch]);
+
return (
<>
@@ -16,6 +34,19 @@ const Home = () => {
+
+
+
+
>
);
diff --git a/src/pages/SignIn/SignIn.jsx b/src/pages/SignIn/SignIn.jsx
index 24208364..5874c7b2 100644
--- a/src/pages/SignIn/SignIn.jsx
+++ b/src/pages/SignIn/SignIn.jsx
@@ -1,4 +1,4 @@
-import { useDispatch } from 'react-redux';
+import { useDispatch, useSelector } from 'react-redux';
import Title from '../../components/Title/Title';
import SubTitle from '../../components/SubTitle/SubTitle';
import AuthForm from '../../components/AuthForm/AuthForm';
@@ -7,10 +7,23 @@ import { Wrapper, WrapperDesktop } from '../Home/Home.styled';
import ParamsBlockCard from '../../components/ParamsBlockСard';
import { logInUser } from '../../redux/auth/operation';
import { mg } from '../../utils';
+import {
+ getAllExercises,
+ getUsersBurnedCalories,
+} from '../../redux/statistic/selectors';
+import { useEffect } from 'react';
+import { getVideoCountAndBurnedCaloriesStatistics } from '../../redux/statistic/operations';
const SignIn = () => {
const dispatch = useDispatch();
+ const videoExercisesCount = useSelector(getAllExercises);
+ const allBurnedCalories = useSelector(getUsersBurnedCalories);
+
+ useEffect(() => {
+ dispatch(getVideoCountAndBurnedCaloriesStatistics());
+ }, [dispatch]);
+
const logIn = (user, { resetForm }) => {
dispatch(logInUser(user));
resetForm();
@@ -33,12 +46,16 @@ const SignIn = () => {
linkText={'Sign Up'}
/>
-
+
diff --git a/src/pages/SignUp/SignUp.jsx b/src/pages/SignUp/SignUp.jsx
index c417b1c3..1d8da957 100644
--- a/src/pages/SignUp/SignUp.jsx
+++ b/src/pages/SignUp/SignUp.jsx
@@ -1,15 +1,29 @@
import Title from '../../components/Title/Title';
import SubTitle from '../../components/SubTitle/SubTitle';
import AuthForm from '../../components/AuthForm';
-import { useDispatch } from 'react-redux';
+import { useDispatch, useSelector } from 'react-redux';
import { authUser } from '../../redux/auth/operation';
import BtnSubtitle from '../../components/BtnSubtitle/BtnSubtitle';
import { Wrapper, WrapperDesktop } from '../Home/Home.styled';
import ParamsBlockCard from '../../components/ParamsBlockСard/ParamsBlockCard';
import { mg } from '../../utils';
+import {
+ getAllExercises,
+ getUsersBurnedCalories,
+} from '../../redux/statistic/selectors';
+import { useEffect } from 'react';
+import { getVideoCountAndBurnedCaloriesStatistics } from '../../redux/statistic/operations';
const SignUp = () => {
const dispatch = useDispatch();
+
+ const videoExercisesCount = useSelector(getAllExercises);
+ const allBurnedCalories = useSelector(getUsersBurnedCalories);
+
+ useEffect(() => {
+ dispatch(getVideoCountAndBurnedCaloriesStatistics());
+ }, [dispatch]);
+
const handleSubmit = (user, { resetForm }) => {
dispatch(authUser(user));
resetForm();
@@ -37,12 +51,16 @@ const SignUp = () => {
linkText={'Sign In'}
/>
-
+
diff --git a/src/redux/statistic/operations.js b/src/redux/statistic/operations.js
new file mode 100644
index 00000000..d4680a4d
--- /dev/null
+++ b/src/redux/statistic/operations.js
@@ -0,0 +1,26 @@
+import { createAsyncThunk } from '@reduxjs/toolkit';
+import axios from 'axios';
+import { toast } from 'react-toastify';
+
+axios.defaults.baseURL = 'https://power-pulse-rest-api.onrender.com';
+
+export const getVideoCountAndBurnedCaloriesStatistics = createAsyncThunk(
+ 'getVideoCountAndBurnedCaloriesStatistics',
+ async (_, { rejectWithValue }) => {
+ try {
+ const { data } = await axios.get('/api/statistics');
+ return data;
+ } catch (error) {
+ toast.error('Oops... Something went wrong! Try again!');
+ return rejectWithValue('Oops... Something went wrong!');
+ }
+ },
+ {
+ condition: (_, { getState }) => {
+ const state = getState();
+ if (state.statistics.allExercises > 1) {
+ return false;
+ }
+ },
+ },
+);
diff --git a/src/redux/statistic/selectors.js b/src/redux/statistic/selectors.js
new file mode 100644
index 00000000..27fb4374
--- /dev/null
+++ b/src/redux/statistic/selectors.js
@@ -0,0 +1,13 @@
+export const getAllExercises = state => state.statistics.allExercises;
+
+export const getAllUsers = state => state.statistics.allUsers;
+
+export const getUsersBurnedCalories = state => state.statistics.usersBurnedCalories;
+
+export const getUsersTimeTraining = state => state.statistics.usersTimeTraining;
+
+export const getUsersTraining = state => state.statistics.usersTraining;
+
+export const isLoadingStatictics = state => state.statistics.isLoading;
+
+export const getErrorStatistics = state => state.statistics.error;
diff --git a/src/redux/statistic/slice.js b/src/redux/statistic/slice.js
new file mode 100644
index 00000000..17f46e8a
--- /dev/null
+++ b/src/redux/statistic/slice.js
@@ -0,0 +1,56 @@
+import { createSlice } from '@reduxjs/toolkit';
+import { getVideoCountAndBurnedCaloriesStatistics } from './operations';
+import formatNumber from '../../utils/formatNumberStatistics';
+
+const contactsInitialValue = {
+ isLoading: false,
+ error: null,
+ allExercises: 0,
+ allUsers: 0,
+ usersBurnedCalories: 0,
+ usersTimeTraining: 0,
+ usersTraining: 0,
+};
+
+const handlePending = state => {
+ state.isLoading = true;
+ state.error = null;
+};
+
+const handleFullfield = state => {
+ state.isLoading = false;
+ state.error = null;
+};
+
+const handleRejected = (state, payload) => {
+ state.isLoading = false;
+ state.error = payload.error;
+};
+
+const getStatistics = createSlice({
+ name: 'statistics',
+ initialState: contactsInitialValue,
+ extraReducers: builder => {
+ builder.addCase(
+ getVideoCountAndBurnedCaloriesStatistics.pending,
+ handlePending,
+ );
+ builder.addCase(
+ getVideoCountAndBurnedCaloriesStatistics.fulfilled,
+ (state, { payload }) => {
+ handleFullfield(state, payload);
+ state.allExercises = payload.AllExercises;
+ state.allUsers = payload.AllUsers;
+ state.usersBurnedCalories = formatNumber(payload.usersBurnedCalories);
+ state.usersTimeTraining = payload.usersTimeTraining;
+ state.usersTraining = payload.usersTraining;
+ },
+ );
+ builder.addCase(
+ getVideoCountAndBurnedCaloriesStatistics.rejected,
+ handleRejected,
+ );
+ },
+});
+
+export const statisticsReducer = getStatistics.reducer;
diff --git a/src/redux/store.js b/src/redux/store.js
index 13611fe1..ee480e4f 100644
--- a/src/redux/store.js
+++ b/src/redux/store.js
@@ -15,7 +15,8 @@ import { authSlice } from './auth/slice';
import filterSlice from './exerciseFilters/slice';
import exercisesSlice from './exercises/slice';
import { diaryReducer } from './diary/slice';
-import productsSlice from './productsFilter/slice';
+import productsSlice from './productsFilter/slice';
+import { statisticsReducer } from './statistic/slice';
const persistConfig = {
key: 'token',
@@ -29,6 +30,7 @@ const rootReducer = combineReducers({
exercises: exercisesSlice,
diary: diaryReducer,
products: productsSlice,
+ statistics: statisticsReducer,
});
export const store = configureStore({
diff --git a/src/utils/formatNumberStatistics.js b/src/utils/formatNumberStatistics.js
new file mode 100644
index 00000000..5bfcdf83
--- /dev/null
+++ b/src/utils/formatNumberStatistics.js
@@ -0,0 +1,11 @@
+function formatNumber(number) {
+ if (number >= 1e6) {
+ return (number / 1e6).toFixed(1) + 'M';
+ } else if (number >= 1e3) {
+ return (number / 1e3).toFixed(1) + 'K';
+ } else {
+ return number.toString();
+ }
+}
+
+export default formatNumber;