diff --git a/package-lock.json b/package-lock.json
index 640285a..36d8fe6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -16,12 +16,14 @@
"@reduxjs/toolkit": "^2.2.1",
"@vitejs/plugin-react-swc": "^3.3.2",
"axios": "^1.6.8",
+ "i18next": "^23.10.1",
"modern-normalize": "^2.0.0",
"normalize.css": "^8.0.1",
"react": "^18.2.0",
"react-datepicker": "^6.3.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.51.0",
+ "react-i18next": "^14.1.0",
"react-redux": "^9.1.0",
"react-responsive": "^9.0.2",
"react-router-dom": "^6.15.0",
@@ -5798,6 +5800,14 @@
"react-is": "^16.7.0"
}
},
+ "node_modules/html-parse-stringify": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz",
+ "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==",
+ "dependencies": {
+ "void-elements": "3.1.0"
+ }
+ },
"node_modules/http-cache-semantics": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
@@ -5846,6 +5856,28 @@
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz",
"integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ=="
},
+ "node_modules/i18next": {
+ "version": "23.10.1",
+ "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.10.1.tgz",
+ "integrity": "sha512-NDiIzFbcs3O9PXpfhkjyf7WdqFn5Vq6mhzhtkXzj51aOcNuPNcTwuYNuXCpHsanZGHlHKL35G7huoFeVic1hng==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://locize.com"
+ },
+ {
+ "type": "individual",
+ "url": "https://locize.com/i18next.html"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project"
+ }
+ ],
+ "dependencies": {
+ "@babel/runtime": "^7.23.2"
+ }
+ },
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
@@ -7329,6 +7361,27 @@
"react": "^16.8.0 || ^17 || ^18"
}
},
+ "node_modules/react-i18next": {
+ "version": "14.1.0",
+ "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-14.1.0.tgz",
+ "integrity": "sha512-3KwX6LHpbvGQ+sBEntjV4sYW3Zovjjl3fpoHbUwSgFHf0uRBcbeCBLR5al6ikncI5+W0EFb71QXZmfop+J6NrQ==",
+ "dependencies": {
+ "@babel/runtime": "^7.23.9",
+ "html-parse-stringify": "^3.0.1"
+ },
+ "peerDependencies": {
+ "i18next": ">= 23.2.3",
+ "react": ">= 16.8.0"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ },
+ "react-native": {
+ "optional": true
+ }
+ }
+ },
"node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
@@ -8657,6 +8710,14 @@
"vite": "^2.6.0 || 3 || 4"
}
},
+ "node_modules/void-elements": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
+ "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -12654,6 +12715,14 @@
"react-is": "^16.7.0"
}
},
+ "html-parse-stringify": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz",
+ "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==",
+ "requires": {
+ "void-elements": "3.1.0"
+ }
+ },
"http-cache-semantics": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
@@ -12687,6 +12756,14 @@
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz",
"integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ=="
},
+ "i18next": {
+ "version": "23.10.1",
+ "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.10.1.tgz",
+ "integrity": "sha512-NDiIzFbcs3O9PXpfhkjyf7WdqFn5Vq6mhzhtkXzj51aOcNuPNcTwuYNuXCpHsanZGHlHKL35G7huoFeVic1hng==",
+ "requires": {
+ "@babel/runtime": "^7.23.2"
+ }
+ },
"ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
@@ -13687,6 +13764,15 @@
"integrity": "sha512-BggOy5j58RdhdMzzRUHGOYhSz1oeylFAv6jUSG86OvCIvlAvS7KvnRY7yoAf2pfEiPN7BesnR0xx73nEk3qIiw==",
"requires": {}
},
+ "react-i18next": {
+ "version": "14.1.0",
+ "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-14.1.0.tgz",
+ "integrity": "sha512-3KwX6LHpbvGQ+sBEntjV4sYW3Zovjjl3fpoHbUwSgFHf0uRBcbeCBLR5al6ikncI5+W0EFb71QXZmfop+J6NrQ==",
+ "requires": {
+ "@babel/runtime": "^7.23.9",
+ "html-parse-stringify": "^3.0.1"
+ }
+ },
"react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
@@ -14568,6 +14654,11 @@
"@svgr/plugin-jsx": "^7.0.0"
}
},
+ "void-elements": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
+ "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w=="
+ },
"which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
diff --git a/package.json b/package.json
index ca0241f..32fa024 100644
--- a/package.json
+++ b/package.json
@@ -19,12 +19,14 @@
"@reduxjs/toolkit": "^2.2.1",
"@vitejs/plugin-react-swc": "^3.3.2",
"axios": "^1.6.8",
+ "i18next": "^23.10.1",
"modern-normalize": "^2.0.0",
"normalize.css": "^8.0.1",
"react": "^18.2.0",
"react-datepicker": "^6.3.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.51.0",
+ "react-i18next": "^14.1.0",
"react-redux": "^9.1.0",
"react-responsive": "^9.0.2",
"react-router-dom": "^6.15.0",
diff --git a/src/components/DailyNorma/DailyEdit.styled.js b/src/components/DailyNorma/DailyEdit.styled.js
index 9c69903..64986ce 100644
--- a/src/components/DailyNorma/DailyEdit.styled.js
+++ b/src/components/DailyNorma/DailyEdit.styled.js
@@ -5,12 +5,17 @@ export const DailyWrapper = styled.div`
display: flex;
flex-direction: column;
align-items: center;
- border: 1px solid #ecf2ff;
+
border-radius: 10px;
padding-top: 8px;
gap: 12px;
width: 164px;
height: 74px;
+
+ background-color: ${(props) => props.theme.dailyWrapperBackground};
+ border: ${(props) => props.theme.dailyWrapperBorder};
+ box-shadow: ${(props) => props.theme.dailyWrapperBoxShadow};
+
@media only screen and (min-width: 768px) {
margin-bottom: -45px;
}
diff --git a/src/components/DailyNorma/WaterRatio.styled.js b/src/components/DailyNorma/WaterRatio.styled.js
index c08b8cc..c4aebbe 100644
--- a/src/components/DailyNorma/WaterRatio.styled.js
+++ b/src/components/DailyNorma/WaterRatio.styled.js
@@ -75,7 +75,7 @@ export const Svg = styled.svg``;
export const StyledRangeInput = styled.input`
-webkit-appearance: none;
- /* width: 256px; */
+
width: 100%;
height: 8px;
border-radius: 10px;
diff --git a/src/components/Header/DivSetting.jsx b/src/components/Header/DivSetting.jsx
new file mode 100644
index 0000000..2f55476
--- /dev/null
+++ b/src/components/Header/DivSetting.jsx
@@ -0,0 +1,32 @@
+import { useEffect, useState } from 'react';
+import { useTranslation } from 'react-i18next';
+
+const DivSetting = () => {
+ const { t, i18n } = useTranslation();
+ const [currentLanguage, setCurrentLanguage] = useState(i18n.language);
+
+ useEffect(() => {
+ const language = localStorage.getItem('language');
+ if (language && language !== currentLanguage) {
+ i18n.changeLanguage(language);
+ setCurrentLanguage(language);
+ }
+ }, [i18n, currentLanguage]);
+
+ const handleChangeLanguage = (language) => {
+ i18n.changeLanguage(language);
+ setCurrentLanguage(language);
+ localStorage.setItem('language', language);
+ };
+
+ return (
+
+
+
+
+
+
+ );
+};
+
+export default DivSetting;
diff --git a/src/components/Header/Header.jsx b/src/components/Header/Header.jsx
index 2f281c3..4a67670 100644
--- a/src/components/Header/Header.jsx
+++ b/src/components/Header/Header.jsx
@@ -11,6 +11,7 @@ import { useSelector } from 'react-redux';
import { selectUser } from '../../store/auth/selectors';
import { HeaderUserName } from './HeaderModalStyled';
import { useEffect, useState } from 'react';
+import DivSetting from './DivSetting';
const Header = () => {
const userProfile = useSelector(selectUser);
@@ -36,7 +37,7 @@ const Header = () => {
-
+
{userProfile ? (
<>
diff --git a/src/components/Header/HeaderModalStyled.jsx b/src/components/Header/HeaderModalStyled.jsx
index eca5744..0a5e328 100644
--- a/src/components/Header/HeaderModalStyled.jsx
+++ b/src/components/Header/HeaderModalStyled.jsx
@@ -269,7 +269,7 @@ export const HeaderUserName = styled.span`
font-size: 18px;
text-align: right;
- color: #2f2f2f;
+
padding-right: 8px;
`;
diff --git a/src/components/Header/ThemeStyled/SwitchTheme/MoonIcon.jsx b/src/components/Header/ThemeStyled/SwitchTheme/MoonIcon.jsx
new file mode 100644
index 0000000..23ef09f
--- /dev/null
+++ b/src/components/Header/ThemeStyled/SwitchTheme/MoonIcon.jsx
@@ -0,0 +1,13 @@
+import { withTheme } from 'styled-components';
+
+function MoonIcon(props) {
+ return (
+
+ );
+}
+export default withTheme(MoonIcon);
diff --git a/src/components/Header/ThemeStyled/SwitchTheme/SunIcon.jsx b/src/components/Header/ThemeStyled/SwitchTheme/SunIcon.jsx
new file mode 100644
index 0000000..7fd003e
--- /dev/null
+++ b/src/components/Header/ThemeStyled/SwitchTheme/SunIcon.jsx
@@ -0,0 +1,16 @@
+import { useTheme } from 'styled-components';
+
+function SunIcon() {
+ const theme = useTheme();
+
+ return (
+
+ );
+}
+
+export default SunIcon;
diff --git a/src/components/Header/ThemeStyled/SwitchTheme/Switch.css b/src/components/Header/ThemeStyled/SwitchTheme/Switch.css
new file mode 100644
index 0000000..be3345d
--- /dev/null
+++ b/src/components/Header/ThemeStyled/SwitchTheme/Switch.css
@@ -0,0 +1,39 @@
+.toggle-switch {
+ position: relative;
+ display: inline-block;
+ width: 50px;
+ height: 25px;
+ margin: 0 0.75rem;
+}
+.toggle-switch input[type='checkbox'] {
+ display: none;
+}
+.toggle-switch .switch {
+ position: absolute;
+ cursor: pointer;
+ background-color: #b6b6b6;
+ border-radius: 25px;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ transition: background-color 0.2s ease;
+}
+.toggle-switch .switch::before {
+ position: absolute;
+ content: '';
+ left: 2px;
+ top: 2px;
+ width: 21px;
+ height: 21px;
+ background-color: #333;
+ border-radius: 50%;
+ transition: transform 0.3s ease;
+}
+.toggle-switch input[type='checkbox']:checked + .switch::before {
+ transform: translateX(25px);
+ background-color: #333;
+}
+.toggle-switch input[type='checkbox']:checked + .switch {
+ background-color: #2bc6ff;
+}
diff --git a/src/components/Header/ThemeStyled/SwitchTheme/Switch.jsx b/src/components/Header/ThemeStyled/SwitchTheme/Switch.jsx
new file mode 100644
index 0000000..5b2cb9a
--- /dev/null
+++ b/src/components/Header/ThemeStyled/SwitchTheme/Switch.jsx
@@ -0,0 +1,26 @@
+import React, { useState } from 'react';
+import './Switch.css';
+import MoonIcon from './MoonIcon';
+import SunIcon from './SunIcon';
+
+function Switch({ toggleTheme, isDarkTheme }) {
+ const [isToggled, setIsToggled] = useState(isDarkTheme);
+
+ const onToggle = () => {
+ setIsToggled(!isToggled);
+ toggleTheme();
+ };
+
+ return (
+ <>
+
+
+
+ >
+ );
+}
+
+export default Switch;
diff --git a/src/components/Header/ThemeStyled/Theme.styled.jsx b/src/components/Header/ThemeStyled/Theme.styled.jsx
new file mode 100644
index 0000000..6ab49bd
--- /dev/null
+++ b/src/components/Header/ThemeStyled/Theme.styled.jsx
@@ -0,0 +1,60 @@
+import styled, { createGlobalStyle } from 'styled-components';
+
+export const StyledApp = styled.div`
+ min-height: 100vh;
+ body {
+ background-color: ${(props) => props.theme.body};
+ color: ${(props) => props.theme.colorBody};
+ }
+`;
+
+export const GlobalStyles = createGlobalStyle`
+ body {
+ background-color: ${(props) => props.theme.body};
+ color: ${(props) => props.theme.colorBody};
+ }
+`;
+
+export const ThemeStyledButton = styled.button``;
+
+export const darkTheme = {
+ body: '#1c1c1c',
+
+ colorBody: '#d5dff5;',
+ test: '#ee1010',
+ icon: '#d5dff5',
+ iconHeader: '#D5DFF5',
+ buttonBackground: '#5082f2;',
+ buttonColor: '#1c1d26;',
+ welcomeWhyDrinkDivCantainerBackground: '#1f2438;',
+ BottleSVG: '#1B1B21;',
+
+ formInputBackground: '#1c1d26;',
+ formInputColor: '#5082f2;',
+ formInputColorPlaceholder: '#2f3875;',
+
+ dailyWrapperBorder: '1px solid #1f2438;',
+ dailyWrapperBackground: '#1c1d26;',
+ dailyWrapperBoxShadow: '0 4px 14px 0 rgba(0, 0, 0, 0.2);',
+};
+
+export const lightTheme = {
+ body: '#fff;',
+
+ colorBody: '#2f2f2f',
+ test: '#ee1010',
+ icon: '#2f2f2f',
+ iconHeader: '#2F2F2F',
+ buttonBackground: '#407bff',
+ buttonColor: '#fff',
+ welcomeWhyDrinkDivCantainerBackground: '#ecf2ff;',
+ BottleSVG: '#F5F5F5;',
+
+ formInputBackground: '#fff;',
+ formInputColor: '#407bff;',
+ formInputColorPlaceholder: '#9ebbff;',
+
+ dailyWrapperBorder: '1px solid #ecf2ff',
+ dailyWrapperBackground: '#fff;',
+ dailyWrapperBoxShadow: '0 4px 8px 0 rgba(158, 187, 255, 0.12);',
+};
diff --git a/src/components/Header/en.json b/src/components/Header/en.json
new file mode 100644
index 0000000..ad1002b
--- /dev/null
+++ b/src/components/Header/en.json
@@ -0,0 +1,5 @@
+{
+ "lightTheme": "Light Theme",
+ "darkTheme": "Dark Theme",
+ "waterconsumptiontracker": "Water consumption tracker"
+}
\ No newline at end of file
diff --git a/src/components/Header/i18n.js b/src/components/Header/i18n.js
new file mode 100644
index 0000000..db32b77
--- /dev/null
+++ b/src/components/Header/i18n.js
@@ -0,0 +1,42 @@
+import i18n from 'i18next';
+import { initReactI18next } from 'react-i18next';
+import enTranslation from './en.json';
+import ukTranslation from './uk.json';
+
+i18n.use(initReactI18next).init({
+ resources: {
+ en: {
+ translation: enTranslation,
+ },
+ uk: {
+ translation: ukTranslation,
+ },
+ },
+ lng: 'en',
+ fallbackLng: 'en',
+ interpolation: {
+ escapeValue: false,
+ },
+});
+
+export default i18n;
+
+// import i18n from 'i18next';
+// import { initReactI18next } from 'react-i18next';
+// import Backend from 'i18next-xhr-backend';
+
+// i18n
+// .use(Backend)
+// .use(initReactI18next)
+// .init({
+// lng: 'en',
+// fallbackLng: 'en',
+// interpolation: {
+// escapeValue: false,
+// },
+// backend: {
+// loadPath: 'http://localhost:5173/byte-my-water-app/',
+// },
+// });
+
+// export default i18n;
diff --git a/src/components/Header/uk.json b/src/components/Header/uk.json
new file mode 100644
index 0000000..ee4ba48
--- /dev/null
+++ b/src/components/Header/uk.json
@@ -0,0 +1,5 @@
+{
+ "lightTheme": "Світла тема",
+ "darkTheme": "Темна тема",
+ "waterconsumptiontracker": "Трекер споживання води"
+}
\ No newline at end of file
diff --git a/src/components/Layout/Layout.jsx b/src/components/Layout/Layout.jsx
index c90a283..33f3b43 100644
--- a/src/components/Layout/Layout.jsx
+++ b/src/components/Layout/Layout.jsx
@@ -3,20 +3,62 @@ import Header from '../Header/Header.jsx';
import { Container, Main } from './Layout.styled.js';
import { BackgraundContainer } from './BackgraundContainer.styled.js';
+import {
+ GlobalStyles,
+ StyledApp,
+ darkTheme,
+ lightTheme,
+} from '../Header/ThemeStyled/Theme.styled.jsx';
+
+import { ThemeProvider } from 'styled-components';
+import { useEffect, useState } from 'react';
+import Switch from '../Header/ThemeStyled/SwitchTheme/Switch.jsx';
+
const Layout = () => {
+ const storedTheme = localStorage.getItem('theme');
+ const [theme, setTheme] = useState(storedTheme || 'light');
+ const isDarkTheme = theme === 'dark';
+
+ const toggleTheme = () => {
+ const newTheme = isDarkTheme ? 'light' : 'dark';
+ setTheme(newTheme);
+ localStorage.setItem('theme', newTheme);
+ };
+
+ useEffect(() => {
+ const handleStorageChange = () => {
+ const storedTheme = localStorage.getItem('theme');
+ if (storedTheme && storedTheme !== theme) {
+ setTheme(storedTheme);
+ }
+ };
+
+ window.addEventListener('storage', handleStorageChange);
+
+ return () => {
+ window.removeEventListener('storage', handleStorageChange);
+ };
+ }, [theme]);
+
return (
<>
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
>
);
};
diff --git a/src/components/LoginForm/LoginForm.styled.js b/src/components/LoginForm/LoginForm.styled.js
index 646de3a..9788071 100644
--- a/src/components/LoginForm/LoginForm.styled.js
+++ b/src/components/LoginForm/LoginForm.styled.js
@@ -61,7 +61,8 @@ export const LoginInput = styled.input`
border-radius: 6px;
border: 1px solid var(--primary-mediumblue);
outline: none;
- color: var(--blue);
+ background-color: ${(props) => props.theme.formInputBackground};
+ color: ${(props) => props.theme.formInputColor};
&::placeholder {
color: var(--primary-blue);
@@ -80,15 +81,16 @@ export const Loginlabel = styled.label`
`;
export const LoginBtn = styled.button`
margin-bottom: 16px;
- background-color: var(--blue);
+
border: 1px solid var(--blue);
- color: var(--white);
+
padding: 8px 30px;
border-radius: 10px;
box-shadow: 0 4px 8px 0 rgba(64, 123, 255, 0.34);
transition: all 0.4s;
-
+ background: ${(props) => props.theme.buttonBackground};
+ color: ${(props) => props.theme.buttonColor};
&:hover,
&:focus {
box-shadow: 0 4px 14px 0 rgba(64, 123, 255, 0.54);
diff --git a/src/components/ModalAddWater/ModalAddWater.jsx b/src/components/ModalAddWater/ModalAddWater.jsx
index 598ce2a..e5df73e 100644
--- a/src/components/ModalAddWater/ModalAddWater.jsx
+++ b/src/components/ModalAddWater/ModalAddWater.jsx
@@ -15,11 +15,11 @@ import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
import useCounter from '../../hooks/modalHandleUpdate.js';
import { useDispatch } from 'react-redux';
-import { addWaterThunk } from '../../store/water/operations.js';
import {
- changeModalClose,
- changeTodayList,
-} from '../../store/water/waterSlice.js';
+ addWaterThunk,
+ fetchAllWaterThunk,
+} from '../../store/water/operations.js';
+import { changeModalClose } from '../../store/water/waterSlice.js';
import { toast } from 'react-toastify';
const ModalAddWater = () => {
@@ -42,7 +42,7 @@ const ModalAddWater = () => {
.unwrap()
.then(() => {
dispatch(changeModalClose(false));
- dispatch(changeTodayList({ ...water, _id: crypto.randomUUID() }));
+ dispatch(fetchAllWaterThunk());
toast.success('Water note was successfully added');
})
.catch((error) => {
diff --git a/src/components/ModalAddWater/ModalAddWater.styled.js b/src/components/ModalAddWater/ModalAddWater.styled.js
index 926e2c4..6476113 100644
--- a/src/components/ModalAddWater/ModalAddWater.styled.js
+++ b/src/components/ModalAddWater/ModalAddWater.styled.js
@@ -141,7 +141,8 @@ export const StyledModalAddInput = styled.input`
border-radius: 6px;
border: 1px solid var(--primary-mediumblue);
padding: 12px 10px 12px 10px;
- color: var(--blue);
+ background-color: ${(props) => props.theme.formInputBackground};
+ color: ${(props) => props.theme.formInputColor};
&::placeholder {
color: var(--blue);
font-size: 16px;
@@ -220,7 +221,8 @@ export const ModalAddDateWrap = styled.div`
border-radius: 6px;
border: 1px solid var(--primary-mediumblue);
padding: 12px 10px 12px 10px;
- color: var(--blue);
+ background-color: ${(props) => props.theme.formInputBackground};
+ color: ${(props) => props.theme.formInputColor};
&::placeholder {
color: var(--blue);
font-size: 16px;
diff --git a/src/components/ModalDailyNorma/ModalDailyNorma.styled.js b/src/components/ModalDailyNorma/ModalDailyNorma.styled.js
index fda52f4..029ff83 100644
--- a/src/components/ModalDailyNorma/ModalDailyNorma.styled.js
+++ b/src/components/ModalDailyNorma/ModalDailyNorma.styled.js
@@ -149,7 +149,8 @@ export const StyledInputBox = styled.div`
width: 100%;
border-radius: 6px;
border: 1px solid var(--primary-mediumblue);
- color: var(--blue);
+ background-color: ${(props) => props.theme.formInputBackground};
+ color: ${(props) => props.theme.formInputColor};
padding: 12px 10px 12px 10px;
margin-top: 8px;
margin-bottom: 16px;
diff --git a/src/components/ModalDeleteWater/ModalDeleteWater.jsx b/src/components/ModalDeleteWater/ModalDeleteWater.jsx
index a200cfb..7ce5557 100644
--- a/src/components/ModalDeleteWater/ModalDeleteWater.jsx
+++ b/src/components/ModalDeleteWater/ModalDeleteWater.jsx
@@ -20,7 +20,6 @@ import { toast } from 'react-toastify';
const ModalDeleteWater = () => {
const isModalOpen = useSelector(modalDeleteOpen);
const id = useSelector(modalId);
-
const dispatch = useDispatch();
const onSubmit = (e) => {
diff --git a/src/components/ModalEditWater/ModalEditWater.styled.js b/src/components/ModalEditWater/ModalEditWater.styled.js
index ca3cf54..da67812 100644
--- a/src/components/ModalEditWater/ModalEditWater.styled.js
+++ b/src/components/ModalEditWater/ModalEditWater.styled.js
@@ -33,7 +33,8 @@ export const StyledModalEditInput = styled.input`
border-radius: 6px;
border: 1px solid var(--primary-mediumblue);
padding: 12px 10px 12px 10px;
- color: var(--blue);
+ background-color: ${(props) => props.theme.formInputBackground};
+ color: ${(props) => props.theme.formInputColor};
&::placeholder {
color: var(--blue);
font-size: 16px;
@@ -64,7 +65,8 @@ export const ModalEditDateWrap = styled.div`
border-radius: 6px;
border: 1px solid var(--primary-mediumblue);
padding: 12px 10px 12px 10px;
- color: var(--blue);
+ background-color: ${(props) => props.theme.formInputBackground};
+ color: ${(props) => props.theme.formInputColor};
&::placeholder {
color: var(--blue);
font-size: 16px;
diff --git a/src/components/SettingModal/SettingModal.styled.js b/src/components/SettingModal/SettingModal.styled.js
index cd65437..3b99472 100644
--- a/src/components/SettingModal/SettingModal.styled.js
+++ b/src/components/SettingModal/SettingModal.styled.js
@@ -215,6 +215,8 @@ export const InputFild = styled.input`
font-family: 'Roboto', sans-serif;
color: var(--blue);
caret-color: var(--black);
+ background-color: ${(props) => props.theme.formInputBackground};
+ color: ${(props) => props.theme.formInputColor};
outline: none;
&::placeholder {
font-size: 16px;
@@ -286,13 +288,14 @@ export const SaveButton = styled.button`
max-width: 392px;
height: 36px;
box-shadow: 0 4px 8px 0 rgba(64, 123, 255, 0.34);
- background: #407bff;
+
font-size: 16px;
font-weight: 500;
line-height: 1.25;
font-family: 'Roboto', sans-serif;
text-align: center;
- color: var(--white);
+ background: ${(props) => props.theme.buttonBackground};
+ color: ${(props) => props.theme.buttonColor};
@media only screen and (min-width: 768px) {
font-size: 18px;
diff --git a/src/components/TodayElement/TodayElement.jsx b/src/components/TodayElement/TodayElement.jsx
index f81b120..0297e39 100644
--- a/src/components/TodayElement/TodayElement.jsx
+++ b/src/components/TodayElement/TodayElement.jsx
@@ -1,4 +1,3 @@
-// import { useState } from 'react';
import {
AddBtnWrapper,
Amount,
@@ -26,22 +25,16 @@ import {
import ModalDeleteWater from '../ModalDeleteWater/ModalDeleteWater.jsx';
import { useEffect } from 'react';
import { fetchAllWaterThunk } from '../../store/water/operations.js';
-import { selectUser } from '../../store/auth/selectors.js';
import { format } from 'date-fns';
const TodayElement = () => {
const isModalOpen = useSelector(modalDeleteOpen);
- const isUser = useSelector(selectUser);
-
const waterTodayList = useSelector(selectorWaterToday);
-
const dispatch = useDispatch();
useEffect(() => {
- if (isUser) {
- dispatch(fetchAllWaterThunk());
- }
- }, [dispatch, isUser]);
+ dispatch(fetchAllWaterThunk());
+ }, [dispatch]);
return (
<>
@@ -67,6 +60,7 @@ const TodayElement = () => {
{
+ dispatch(changeModalId(item._id));
dispatch(changeModalDeleteForm(true));
dispatch(changeModalId(item._id));
}}
diff --git a/src/components/Welcome/Welcome.jsx b/src/components/Welcome/Welcome.jsx
index 5d697d7..7ba05b3 100644
--- a/src/components/Welcome/Welcome.jsx
+++ b/src/components/Welcome/Welcome.jsx
@@ -1,3 +1,4 @@
+import { useTranslation } from 'react-i18next';
import DesctopWoter from '../../images/backgroundImg/backgraundSvg/DesctopWoter';
import TabletWoter from '../../images/backgroundImg/backgraundSvg/TabletWoter';
import SvgHabit from '../../images/svg/svgWelcome/SvgHabit';
@@ -23,9 +24,11 @@ import {
} from './Welcome.styled';
const Welcome = () => {
+ const { t } = useTranslation();
+
return (
<>
-
+ {/*
*/}
@@ -35,7 +38,7 @@ const Welcome = () => {
-
Water consumption tracker
+
{t('waterconsumptiontracker')}
Record daily water intake and track
Tracker Benefits
diff --git a/src/components/Welcome/Welcome.styled.js b/src/components/Welcome/Welcome.styled.js
index 6477317..181e507 100644
--- a/src/components/Welcome/Welcome.styled.js
+++ b/src/components/Welcome/Welcome.styled.js
@@ -151,7 +151,7 @@ export const WelcomeWhyDrinkDivCantainer = styled.div`
padding: 32px 24px;
box-shadow: 0 4px 14px 0 rgba(64, 123, 255, 0.3);
- background: #ecf2ff;
+ background: ${(props) => props.theme.welcomeWhyDrinkDivCantainerBackground};
max-width: 380px;
margin-bottom: 20px;
@media only screen and (min-width: 768px) {
@@ -171,13 +171,15 @@ export const WelcomeNavLink = styled(NavLink)`
width: 100%;
box-shadow: 0 4px 8px 0 rgba(64, 123, 255, 0.34);
- background: #407bff;
font-weight: 500;
font-size: 16px;
text-align: center;
- color: #fff;
+
+ background: ${(props) => props.theme.buttonBackground};
+ color: ${(props) => props.theme.buttonColor};
+
border: none;
@media only screen and (min-width: 768px) {
max-width: 336px;
diff --git a/src/images/AuthImg/BottleSVG.jsx b/src/images/AuthImg/BottleSVG.jsx
index 1bfddb3..391cc2e 100644
--- a/src/images/AuthImg/BottleSVG.jsx
+++ b/src/images/AuthImg/BottleSVG.jsx
@@ -1,85 +1,92 @@
import * as React from 'react';
-const BottleSVG = (props) => (
-
-);
+import { useTheme } from 'styled-components';
+
+const BottleSVG = (props) => {
+ const theme = useTheme();
+
+ return (
+
+ );
+};
+
export default BottleSVG;
diff --git a/src/images/AuthImg/BottleSVGDesktop.jsx b/src/images/AuthImg/BottleSVGDesktop.jsx
index 44ae6eb..65e7354 100644
--- a/src/images/AuthImg/BottleSVGDesktop.jsx
+++ b/src/images/AuthImg/BottleSVGDesktop.jsx
@@ -1,90 +1,95 @@
-const BottleSVGDesktop = (props) => (
-
-);
+const BottleSVGDesktop = (props) => {
+ const theme = useTheme();
+ return (
+
+ );
+};
export default BottleSVGDesktop;
diff --git a/src/images/AuthImg/BottleSVGTablet.jsx b/src/images/AuthImg/BottleSVGTablet.jsx
index edfc330..c163e40 100644
--- a/src/images/AuthImg/BottleSVGTablet.jsx
+++ b/src/images/AuthImg/BottleSVGTablet.jsx
@@ -1,91 +1,95 @@
import * as React from 'react';
-const BottleSVGTablet = (props) => (
-
+ );
+};
export default BottleSVGTablet;
diff --git a/src/images/backgroundImg/backgraundSvg/DesctopWoter.jsx b/src/images/backgroundImg/backgraundSvg/DesctopWoter.jsx
index 8a0db4d..4e53d01 100644
--- a/src/images/backgroundImg/backgraundSvg/DesctopWoter.jsx
+++ b/src/images/backgroundImg/backgraundSvg/DesctopWoter.jsx
@@ -1,90 +1,94 @@
-const DesctopWoter = (props) => (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+import { useTheme } from 'styled-components';
+const DesctopWoter = (props) => {
+ const theme = useTheme();
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-);
+
+
+
+
+
+
+ );
+};
export default DesctopWoter;
diff --git a/src/images/backgroundImg/backgraundSvg/TabletWoter.jsx b/src/images/backgroundImg/backgraundSvg/TabletWoter.jsx
index 0f81b8d..472b358 100644
--- a/src/images/backgroundImg/backgraundSvg/TabletWoter.jsx
+++ b/src/images/backgroundImg/backgraundSvg/TabletWoter.jsx
@@ -1,84 +1,90 @@
-const TabletWoter = (props) => (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-);
+import * as React from 'react';
+import { useTheme } from 'styled-components';
+
+const TabletWoter = (props) => {
+ const theme = useTheme();
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
export default TabletWoter;
diff --git a/src/images/svg/svgDailyNorma/BottleDesctop.jsx b/src/images/svg/svgDailyNorma/BottleDesctop.jsx
index 2ea77b6..87ef8ff 100644
--- a/src/images/svg/svgDailyNorma/BottleDesctop.jsx
+++ b/src/images/svg/svgDailyNorma/BottleDesctop.jsx
@@ -1,6 +1,7 @@
import React from 'react';
-
+import { useTheme } from 'styled-components';
function BottleDesctop() {
+ const theme = useTheme();
return (
(
-
-
-
-
-
-
-
-
-
-
-
-);
+import { useTheme } from 'styled-components';
+
+const HeaderSVGPhoto = (props) => {
+ const theme = useTheme();
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
export default HeaderSVGPhoto;
+// 2F2F2F
diff --git a/src/main.jsx b/src/main.jsx
index e7fcf25..202f207 100644
--- a/src/main.jsx
+++ b/src/main.jsx
@@ -1,19 +1,22 @@
-import { BrowserRouter } from 'react-router-dom';
import ReactDOM from 'react-dom/client';
+import { BrowserRouter } from 'react-router-dom';
import App from './components/App/App.jsx';
import './index.css';
import { Provider } from 'react-redux';
import { persistor, store } from './store/store.js';
import { PersistGate } from 'redux-persist/integration/react';
-
+import i18n from './components/Header/i18n.js';
import { ToastContainer } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
+import { I18nextProvider } from 'react-i18next';
ReactDOM.createRoot(document.getElementById('root')).render(
-
+
+
+
diff --git a/src/store/water/selectors.js b/src/store/water/selectors.js
index a25ab38..0d69d9f 100644
--- a/src/store/water/selectors.js
+++ b/src/store/water/selectors.js
@@ -5,7 +5,6 @@ export const modalIsAdd = (state) => state.waterSlice.modal?.modalAddForm;
export const modalIsEdit = (state) => state.waterSlice.modal?.modalEditForm;
export const isModalDayNorm = (state) => state.waterSlice.modal?.isModalDayNorm;
export const modalDayNorma = (state) => state.waterSlice.modal?.modalDayNorma;
-// export const modalIsDelete = (state) => state.waterSlice.modal?.modalDeleteForm;
export const modalId = (state) => state.waterSlice.modal?.modalId;
export const showDaysGenStats = (state) => state.waterSlice.daysGenStats;
diff --git a/src/store/water/waterSlice.js b/src/store/water/waterSlice.js
index 54f8160..b0affac 100644
--- a/src/store/water/waterSlice.js
+++ b/src/store/water/waterSlice.js
@@ -11,7 +11,6 @@ const waterSlice = createSlice({
modalEditForm: false,
isModalDayNorm: false,
modalDayNorma: false,
- modalDeleteForm: false,
modalId: '',
},
daysGenStats: false,
@@ -25,7 +24,6 @@ const waterSlice = createSlice({
state.modal.modalEditForm = payload;
state.modal.isModalDayNorm = payload;
state.modal.modalDayNorma = payload;
- state.modal.modalDeleteForm = payload;
state.modal.modalDeleteOpen = payload;
},
changeModalAddForm: (state, { payload }) => {
@@ -38,7 +36,6 @@ const waterSlice = createSlice({
},
changeModalDeleteForm: (state, { payload }) => {
state.modal.modalDeleteOpen = payload;
- state.modal.modalDeleteForm = payload;
},
changeModalDailyNorma: (state, { payload }) => {
state.modal.isModalDayNorm = payload;
@@ -70,7 +67,7 @@ const waterSlice = createSlice({
extraReducers: (builder) => {
builder
.addCase(fetchAllWaterThunk.fulfilled, (state, { payload }) => {
- state.waterTodayList.push(...payload);
+ state.waterTodayList = payload;
})
.addCase(fetchAllWaterThunk.rejected, (state, { payload }) => {
state.error = payload;