diff --git a/package-lock.json b/package-lock.json index 2da10d3..c8ee2a6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "formik": "^2.2.9", "lodash": "^4.17.21", "modern-normalize": "^1.1.0", + "moment": "^2.29.4", "notiflix": "^3.2.6", "react": "^18.2.0", "react-bootstrap": "^2.7.4", @@ -12389,6 +12390,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "engines": { + "node": "*" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", diff --git a/package.json b/package.json index 4dbc8ff..8dec600 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "formik": "^2.2.9", "lodash": "^4.17.21", "modern-normalize": "^1.1.0", + "moment": "^2.29.4", "notiflix": "^3.2.6", "react": "^18.2.0", "react-bootstrap": "^2.7.4", diff --git a/src/components/DateInput/DateInput.jsx b/src/components/DateInput/DateInput.jsx index 7e97782..368570f 100644 --- a/src/components/DateInput/DateInput.jsx +++ b/src/components/DateInput/DateInput.jsx @@ -18,18 +18,11 @@ export const Calendar = ({onDate}) => { const year = startDate.getFullYear(); const month =startDate.getMonth()+1 - // const month_ =()=>{ - // if(month<10){ - // return ("0"+month) - // } - // } useEffect(()=>{ onDate({month, year}) },[onDate, year, month]) - - // console.log(getMonth, getYear); return ( { showMonthYearPicker customInput={} wrapperClassName={s.calendar} + // minDate={subDays(new Date(), 5)} // add start tarnsaction + maxDate={new Date()} /> ); }; diff --git a/src/components/DateInput/DateInput.module.scss b/src/components/DateInput/DateInput.module.scss index 65ae336..90b055a 100644 --- a/src/components/DateInput/DateInput.module.scss +++ b/src/components/DateInput/DateInput.module.scss @@ -2,23 +2,23 @@ @import 'src/assets/styles/utils/vars'; .calendar { - position: absolute; - - top: -114px; - left: 0px; + position: absolute; + top: -114px; + left: 0px; + z-index: 1; + width: 217px; + @include tablet { + top: -54px; + left: 484px; + z-index: 1; + } + @include desktop { + top: -54px; + left: 550px; z-index: 1; - @include tablet { - top: -54px; - left: 484px; - z-index: 1; - } - @include desktop { - top: -54px; - left: 550px; - z-index: 1; - } } - +} + .input_field { display: flex; justify-content: space-between; @@ -35,7 +35,7 @@ border-radius: 16px; border: none; - font-family: 'Lato'; + font-family: 'Lato-Regular'; font-style: normal; font-weight: 400; font-size: 16px; @@ -44,57 +44,82 @@ /* white */ color: $main-white; } -.month{ +.month { margin-bottom: 15px; } -.popper{ +.popper { width: 217px; height: 220px; } -:global .react-datepicker{ +:global .react-datepicker { border-radius: 15px; width: 217px; + border:none; } -:global .react-datepicker__triangle{ - display:none; +:global .react-datepicker__triangle { + display: none; } :global .react-datepicker__header { -border-radius: 15px; -outline: none; -border: none; -margin-left: auto; -margin-right: auto; -width: 215px; - -font-family: 'Lato'; -font-style: normal; -font-weight: 700; -font-size: 16px; -line-height: 19px; + display: flex; + align-items: center; + justify-content: space-around; + border-radius: 0; + outline: none; + border-bottom: 1px solid #2424240D; + margin-left: auto; + margin-right: auto; + height: 60px; + background: none; + font-family: 'Lato-Regular'; + font-style: normal; + font-weight: 700; + font-size: 16px; + line-height: 19px; } +:global .react-datepicker__navigation{ + height:60px; +} +:global .react-datepicker__month .react-datepicker__month-text { - -:global .react-datepicker__month-container{ - float: none; + padding: 6px 18px; + margin: 0; + width: 57px; + + font-family: 'Lato-Regular'; + font-style: normal; + font-weight: 700; + font-size: 16px; + line-height: 19px; } -:global .react-datepicker__header{ - border-radius: 15px; +:global .react-datepicker__month-container { + float: none; } -:global .react-datepicker__month{ - font-family: 'Lato'; -font-style: normal; -font-weight: 400; -font-size: 14px; -line-height: 17px; +:global .react-datepicker__month-text{ + width: 57px; + border-radius: 50px; + font-style: normal; + font-weight: 400; + font-size: 14px; + line-height: 17px; -color: #242424; + /* identical to box height */ + display: flex; + align-items: center; } +:global .react-datepicker__month-text--keyboard-selected { + padding: 6px 18px; + width: 57px; + background: #3a6af5; + border-radius: 50px; + font-style: normal; + font-weight: 400; + font-size: 14px; + line-height: 17px; + /* identical to box height */ + display: flex; + align-items: center; -:global .react-datepicker__month-wrapper{ - margin-bottom: 15px; + color: #f3f3f3; } -:global .global .react-datepicker-popper{ - padding: 0; -} \ No newline at end of file diff --git a/src/components/StatisticsComponents/CategoryBoard/CategoryBoard.jsx b/src/components/StatisticsComponents/CategoryBoard/CategoryBoard.jsx index 0026b54..5d66dcb 100644 --- a/src/components/StatisticsComponents/CategoryBoard/CategoryBoard.jsx +++ b/src/components/StatisticsComponents/CategoryBoard/CategoryBoard.jsx @@ -4,7 +4,7 @@ import { Calendar } from '../../DateInput/DateInput'; import { useEffect, useState } from 'react'; import { useDispatch } from 'react-redux'; import { getCashflowStat } from '../../../redux/operations/cashflowOperations'; -import shortid from 'shortid'; +// import shortid from 'shortid'; // import {Notify} from "notiflix" export const Item = ({ id, amount, category, percentage }) => { @@ -24,26 +24,30 @@ export const Item = ({ id, amount, category, percentage }) => { export const CategoriesList = () => { const dispatch = useDispatch(); const [dateFilter, setDateFilter] = useState(); //обрані дати - const [transactionData, setTransactionData] = useState(); //отримання транзакцій + const [transactionData, setTransactionData] = useState([]); //отримання транзакцій useEffect(() => { dispatch(getCashflowStat(dateFilter)).then(data => { - if (typeof data.payload === 'object') {setTransactionData(data.payload)} - else {setTransactionData([]) - // Notify.failure("You don't have transaction on this period") - }; + setTransactionData(data.payload); }); }, [dateFilter, dispatch]); +// console.log('cat', transactionData) + if (transactionData?.length === 0) return; return ( -
-
- - -
    - {transactionData?.map(item => )} -
+ //
+
+
+ + +
    + {(typeof(transactionData)==='object')? (transactionData?.map(item => ( + + ))):(

    You didn't have transaction on this period

    ) + } +
+
-
+ //
); }; diff --git a/src/components/StatisticsComponents/CategoryBoard/CategoryBoard.module.scss b/src/components/StatisticsComponents/CategoryBoard/CategoryBoard.module.scss index a284763..8b73d6f 100644 --- a/src/components/StatisticsComponents/CategoryBoard/CategoryBoard.module.scss +++ b/src/components/StatisticsComponents/CategoryBoard/CategoryBoard.module.scss @@ -3,7 +3,32 @@ .container { @include container; -} + + @include tablet { + background-image: url('../../../assets/img/bg-tablet.png'); + background-repeat: no-repeat; + background-size: 100%; + background-position: bottom; + height: calc(100vh - 72px); + } + + @include desktop { + background-image: url('../../../assets/img/bg-desktop.png'); + background-repeat: no-repeat; + background-size: 100%; + background-position: bottom; + } +} +// .background_img{ +// @include tablet{ +// background-image: url(../../../assets/img/bg-tablet.png); +// background-size: contain +// } +// @include desktop{ +// background-image: url(../../../assets/img/bg-desktop.png); +// background-size: contain +// } +// } .wrapper{ position: relative; position: relative; @@ -177,3 +202,21 @@ background-color: black; } +.expense_block { + @include desktop { + height: 420px; + overflow-y: scroll; + } + @include tablet { + height: 420px; + overflow-y: scroll; + } +} +// .expense_block::-webkit-scrollbar { +// width: 2px; /* ширина всей полосы прокрутки */ +// } +.error_mes{ + padding-top: 30px; + text-align: center; + font-size: 15px; +} \ No newline at end of file diff --git a/src/components/StatisticsComponents/ExpensesBoard/ExpenseBoardItem.jsx b/src/components/StatisticsComponents/ExpensesBoard/ExpenseBoardItem.jsx index f813c0b..c82d9af 100644 --- a/src/components/StatisticsComponents/ExpensesBoard/ExpenseBoardItem.jsx +++ b/src/components/StatisticsComponents/ExpensesBoard/ExpenseBoardItem.jsx @@ -2,6 +2,7 @@ import { useDispatch } from 'react-redux'; import s from './ExpensesBoard.module.scss'; import { deleteOneTransaction } from '../../../redux/operations/cashflowOperations'; import iconSvg from '../Svg'; +import moment from 'moment'; export const Item = ({ _id, @@ -18,13 +19,14 @@ export const Item = ({ setActive(true); setData(setTransData); }; +const newDate =moment().format("DD MM YYYY"); return ( <>
  • -

    {date}

    +

    {newDate}

    {comment}

    {sum} UAH

    diff --git a/src/components/StatisticsComponents/ExpensesBoard/ExpensesBoard.jsx b/src/components/StatisticsComponents/ExpensesBoard/ExpensesBoard.jsx index f841671..3628942 100644 --- a/src/components/StatisticsComponents/ExpensesBoard/ExpensesBoard.jsx +++ b/src/components/StatisticsComponents/ExpensesBoard/ExpensesBoard.jsx @@ -1,63 +1,68 @@ import s from './ExpensesBoard.module.scss'; import { StatisticsNav } from '../StatisticsNav/StatisticsNav'; -import { - useDispatch, - // useSelector -} from 'react-redux'; +import { useDispatch } from 'react-redux'; import { PopUp } from '../PopUp/PopUp'; import { useEffect, useState } from 'react'; import { Calendar } from '../../DateInput/DateInput'; import { getListOfTransactions } from '../../../redux/operations/cashflowOperations'; -import {Item} from './ExpenseBoardItem' -import {Notify} from "notiflix" +import { Item } from './ExpenseBoardItem'; import { getListOfCategory } from '../../../redux/operations/categoriesOperations'; - export const ExpensesList = () => { const [popupActive, setPopupActive] = useState(false); //активація модального const [dataIn, setDataIn] = useState(''); //данні по обраній транзакції const [dateFilter, setDateFilter] = useState(''); //обрані дати const [transactionData, setTransactionData] = useState([]); //отримання транзакцій - // const [form, setForm] = useState(); const dispatch = useDispatch(); useEffect(() => { - dispatch(getListOfCategory()); - }, [dispatch]); + dispatch(getListOfCategory()); + }); useEffect(() => { dispatch(getListOfTransactions(dateFilter)).then(data => { setTransactionData(data.payload); - }) - }, [dispatch, dateFilter]); + }); + }, [dateFilter, dispatch, popupActive]); + + // console.log('on board', transactionData); + + if (transactionData?.length === 0) return; -if (!transactionData || transactionData===[]) return; + // console.log('board'); return ( -
    -
    - - -
      - {(typeof(transactionData)==='object')?(transactionData?.map(item => ( - +
      +
      + + +
        + {typeof transactionData === 'object' ? ( + transactionData?.map(item => ( + + )) + ) : ( +

        + You didn't have transaction on this period +

        + )} +
      + {popupActive && ( + - ))):(Notify.failure("You don't have transactions for this period"))} -
    - {popupActive && ( - - )} + )} +
    -
    + //
  • ); }; diff --git a/src/components/StatisticsComponents/ExpensesBoard/ExpensesBoard.module.scss b/src/components/StatisticsComponents/ExpensesBoard/ExpensesBoard.module.scss index 3ca187c..433d136 100644 --- a/src/components/StatisticsComponents/ExpensesBoard/ExpensesBoard.module.scss +++ b/src/components/StatisticsComponents/ExpensesBoard/ExpensesBoard.module.scss @@ -1,8 +1,32 @@ @import 'src/assets/styles/utils/mixins'; @import 'src/assets/styles/utils/vars'; - +// .background_img{ +// @include tablet{ +// background-image: url(../../../assets/img/bg-tablet.png); +// background-size: contain +// } +// @include desktop{ +// background-image: url(../../../assets/img/bg-desktop.png); +// background-size: contain +// } +// } .container { @include container; + + @include tablet { + background-image: url('../../../assets/img/bg-tablet.png'); + background-repeat: no-repeat; + background-size: 100%; + background-position: bottom; + height: calc(100vh - 72px); + } + + @include desktop { + background-image: url('../../../assets/img/bg-desktop.png'); + background-repeat: no-repeat; + background-size: 100%; + background-position: bottom; + } } .wrapper { position: relative; @@ -183,11 +207,19 @@ } .expense_block { @include desktop { - height: 420px; - overflow: scroll; + max-height: 420px; + overflow-y: scroll; } @include tablet { - height: 420px; - overflow: scroll; + max-height: 420px; + overflow-y: scroll; } } +// .expense_block::-webkit-scrollbar { +// width: 2px; /* ширина всей полосы прокрутки */ +// } +.error_mes{ + padding-top: 30px; + text-align: center; + font-size: 15px; +} diff --git a/src/components/StatisticsComponents/PopUp/PopUp.jsx b/src/components/StatisticsComponents/PopUp/PopUp.jsx index a72732a..677b431 100644 --- a/src/components/StatisticsComponents/PopUp/PopUp.jsx +++ b/src/components/StatisticsComponents/PopUp/PopUp.jsx @@ -1,7 +1,4 @@ -import { - // useEffect, - useState -} from 'react'; +import { useState } from 'react'; import s from './Popup.module.scss'; import iconSvg from '../Svg'; import clsx from 'clsx'; @@ -10,7 +7,7 @@ import SelectCategory from './Select'; import { Notify } from 'notiflix'; import { useDispatch } from 'react-redux'; -export const PopUp = ({ isActive, setActive, setData, formChange }) => { +export const PopUp = ({ isActive, setActive, setData }) => { const { _id, date, comment, category, sum, type } = setData; const dispatch = useDispatch(); const initialValues = { @@ -23,12 +20,10 @@ export const PopUp = ({ isActive, setActive, setData, formChange }) => { }; const [form, setForm] = useState(initialValues); - // console.log(categories); const getBackdropClass = () => clsx(s.backdrop, isActive && s.active); const handleChange = e => { const { name, value } = e.target; - // console.log('name, value ', name, value); if (name === 'sum') { if (Boolean(Number(value)) === false) { Notify.warning('Please, input number'); @@ -44,20 +39,18 @@ export const PopUp = ({ isActive, setActive, setData, formChange }) => { setForm(prevForm => { return { ...prevForm, - [name]: (value), + [name]: value, }; }); }; const handleSelect = data => { - // console.log(data) + if (!data) return; - // const { name, value } = data; - // console.log(name, value); setForm(prevForm => { return { ...prevForm, - // ['category']: value, + "category": data.value, }; }); }; @@ -66,9 +59,9 @@ export const PopUp = ({ isActive, setActive, setData, formChange }) => { e.preventDefault(); console.log('form', form); dispatch(putOneTransaction(form)); - // formChange(form) setActive(false); }; + return (
    { Per category
    diff --git a/src/components/StatisticsComponents/PopUp/Select.jsx b/src/components/StatisticsComponents/PopUp/Select.jsx index 2d515a5..e307d60 100644 --- a/src/components/StatisticsComponents/PopUp/Select.jsx +++ b/src/components/StatisticsComponents/PopUp/Select.jsx @@ -1,18 +1,13 @@ -import { useEffect, useState } from 'react'; -import { - // useDispatch, - useSelector -} from 'react-redux'; +import { useSelector } from 'react-redux'; import Select from 'react-select'; import '../../../components/Select/SelectCategory.scss'; -// import s from './Popup.module.scss'; const colourStyles = { control: styles => ({ ...styles, width: '275px', border: 'none', - boxShadow: "none", + boxShadow: 'none', backgroundColor: '#252C4180', height: '74px', outline: 'none', @@ -26,26 +21,17 @@ const colourStyles = { color: '#fff', }), option: (styles, { data, isDisabled, isFocused, isSelected }) => { - // const color = chroma(data.color); return { ...styles, backgroundColor: ' #fff', - // cursor: isDisabled ? 'not-allowed' : 'default', fontFamily: 'Lato', }; }, }; -export default function SelectCategory({ currentCategory, changeCategory }) { - const [categoryValue, setCategoryValue] = useState(''); - // const dispatch = useDispatch(); - +export default function SelectCategory({ currentCategory, setCategory }) { const categories = useSelector(state => state?.categories?.categories); - useEffect(() => { - changeCategory(categoryValue); - }, [categoryValue, changeCategory]); - const category = categories?.map(({ name, title }) => { return { value: name, @@ -53,13 +39,9 @@ export default function SelectCategory({ currentCategory, changeCategory }) { }; }); - useEffect(() => { - setCategoryValue( - category.find(categoryId => { - return categoryId.value === currentCategory; - }) - ); - }, [setCategoryValue, category, currentCategory]); + const defaultcategory = category.find(categoryId => { + return categoryId.value === currentCategory; + }); return (