diff --git a/package-lock.json b/package-lock.json
index 74a711b..ea854d8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,15 +11,19 @@
"@fortawesome/free-brands-svg-icons": "^5.15.4",
"@fortawesome/free-solid-svg-icons": "^5.15.4",
"@fortawesome/react-fontawesome": "^0.1.16",
+ "@reduxjs/toolkit": "^1.7.1",
"@testing-library/jest-dom": "^5.16.1",
"@testing-library/react": "^12.1.2",
"@testing-library/user-event": "^13.5.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-icons": "^4.3.1",
+ "react-redux": "^7.2.6",
"react-scripts": "5.0.0",
"react-tooltip": "^4.2.21",
+ "redux": "^4.1.2",
"sass": "^1.45.0",
+ "sweetalert2": "^11.3.4",
"web-vitals": "^2.1.2"
},
"devDependencies": {
@@ -2751,6 +2755,29 @@
"node": ">= 8"
}
},
+ "node_modules/@reduxjs/toolkit": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.7.1.tgz",
+ "integrity": "sha512-wXwXYjBVz/ItxB7SMzEAMmEE/FBiY1ze18N+VVVX7NtVbRUrdOGKhpQMHivIJfkbJvSdLUU923a/yAagJQzY0Q==",
+ "dependencies": {
+ "immer": "^9.0.7",
+ "redux": "^4.1.2",
+ "redux-thunk": "^2.4.1",
+ "reselect": "^4.1.5"
+ },
+ "peerDependencies": {
+ "react": "^16.9.0 || ^17.0.0 || 18.0.0-beta",
+ "react-redux": "^7.2.1 || ^8.0.0-beta"
+ },
+ "peerDependenciesMeta": {
+ "react": {
+ "optional": true
+ },
+ "react-redux": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@rollup/plugin-babel": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.0.tgz",
@@ -3401,6 +3428,15 @@
"@types/node": "*"
}
},
+ "node_modules/@types/hoist-non-react-statics": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
+ "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
+ "dependencies": {
+ "@types/react": "*",
+ "hoist-non-react-statics": "^3.3.0"
+ }
+ },
"node_modules/@types/html-minifier-terser": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
@@ -3469,11 +3505,37 @@
"resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.2.tgz",
"integrity": "sha512-ekoj4qOQYp7CvjX8ZDBgN86w3MqQhLE1hczEJbEIjgFEumDy+na/4AJAbLXfgEWFNB2pKadM5rPFtuSGMWK7xA=="
},
+ "node_modules/@types/prop-types": {
+ "version": "15.7.4",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz",
+ "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ=="
+ },
"node_modules/@types/q": {
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz",
"integrity": "sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ=="
},
+ "node_modules/@types/react": {
+ "version": "17.0.38",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.38.tgz",
+ "integrity": "sha512-SI92X1IA+FMnP3qM5m4QReluXzhcmovhZnLNm3pyeQlooi02qI7sLiepEYqT678uNiyc25XfCqxREFpy3W7YhQ==",
+ "dependencies": {
+ "@types/prop-types": "*",
+ "@types/scheduler": "*",
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/@types/react-redux": {
+ "version": "7.1.21",
+ "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.21.tgz",
+ "integrity": "sha512-bLdglUiBSQNzWVVbmNPKGYYjrzp3/YDPwfOH3nLEz99I4awLlaRAPWjo6bZ2POpxztFWtDDXIPxBLVykXqBt+w==",
+ "dependencies": {
+ "@types/hoist-non-react-statics": "^3.3.0",
+ "@types/react": "*",
+ "hoist-non-react-statics": "^3.3.0",
+ "redux": "^4.0.0"
+ }
+ },
"node_modules/@types/resolve": {
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
@@ -3487,6 +3549,11 @@
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz",
"integrity": "sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g=="
},
+ "node_modules/@types/scheduler": {
+ "version": "0.16.2",
+ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
+ "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
+ },
"node_modules/@types/stack-utils": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
@@ -5656,6 +5723,11 @@
"resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
"integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg=="
},
+ "node_modules/csstype": {
+ "version": "3.0.10",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.10.tgz",
+ "integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA=="
+ },
"node_modules/damerau-levenshtein": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz",
@@ -7871,6 +7943,19 @@
"he": "bin/he"
}
},
+ "node_modules/hoist-non-react-statics": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+ "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+ "dependencies": {
+ "react-is": "^16.7.0"
+ }
+ },
+ "node_modules/hoist-non-react-statics/node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ },
"node_modules/hoopy": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
@@ -13213,6 +13298,30 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
},
+ "node_modules/react-redux": {
+ "version": "7.2.6",
+ "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.6.tgz",
+ "integrity": "sha512-10RPdsz0UUrRL1NZE0ejTkucnclYSgXp5q+tB5SWx2qeG2ZJQJyymgAhwKy73yiL/13btfB6fPr+rgbMAaZIAQ==",
+ "dependencies": {
+ "@babel/runtime": "^7.15.4",
+ "@types/react-redux": "^7.1.20",
+ "hoist-non-react-statics": "^3.3.2",
+ "loose-envify": "^1.4.0",
+ "prop-types": "^15.7.2",
+ "react-is": "^17.0.2"
+ },
+ "peerDependencies": {
+ "react": "^16.8.3 || ^17"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ },
+ "react-native": {
+ "optional": true
+ }
+ }
+ },
"node_modules/react-refresh": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
@@ -13364,6 +13473,22 @@
"node": ">=8"
}
},
+ "node_modules/redux": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/redux/-/redux-4.1.2.tgz",
+ "integrity": "sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==",
+ "dependencies": {
+ "@babel/runtime": "^7.9.2"
+ }
+ },
+ "node_modules/redux-thunk": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.1.tgz",
+ "integrity": "sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q==",
+ "peerDependencies": {
+ "redux": "^4"
+ }
+ },
"node_modules/regenerate": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
@@ -13505,6 +13630,11 @@
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
},
+ "node_modules/reselect": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.5.tgz",
+ "integrity": "sha512-uVdlz8J7OO+ASpBYoz1Zypgx0KasCY20H+N8JD13oUMtPvSHQuscrHop4KbXrbsBcdB9Ds7lVK7eRkBIfO43vQ=="
+ },
"node_modules/resolve": {
"version": "1.20.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
@@ -14527,6 +14657,14 @@
"boolbase": "~1.0.0"
}
},
+ "node_modules/sweetalert2": {
+ "version": "11.3.4",
+ "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.3.4.tgz",
+ "integrity": "sha512-o7owEtVtpqnB8y3BDCRn2taYb7URcf6RIUm120LjFxt8IHfPIm0UeHuiS3nEp5r9RKm5GlSSJOh/yuapUQcYcQ==",
+ "funding": {
+ "url": "https://sweetalert2.github.io/#donations"
+ }
+ },
"node_modules/symbol-tree": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
@@ -17990,6 +18128,17 @@
}
}
},
+ "@reduxjs/toolkit": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.7.1.tgz",
+ "integrity": "sha512-wXwXYjBVz/ItxB7SMzEAMmEE/FBiY1ze18N+VVVX7NtVbRUrdOGKhpQMHivIJfkbJvSdLUU923a/yAagJQzY0Q==",
+ "requires": {
+ "immer": "^9.0.7",
+ "redux": "^4.1.2",
+ "redux-thunk": "^2.4.1",
+ "reselect": "^4.1.5"
+ }
+ },
"@rollup/plugin-babel": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.0.tgz",
@@ -18439,6 +18588,15 @@
"@types/node": "*"
}
},
+ "@types/hoist-non-react-statics": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
+ "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
+ "requires": {
+ "@types/react": "*",
+ "hoist-non-react-statics": "^3.3.0"
+ }
+ },
"@types/html-minifier-terser": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
@@ -18507,11 +18665,37 @@
"resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.2.tgz",
"integrity": "sha512-ekoj4qOQYp7CvjX8ZDBgN86w3MqQhLE1hczEJbEIjgFEumDy+na/4AJAbLXfgEWFNB2pKadM5rPFtuSGMWK7xA=="
},
+ "@types/prop-types": {
+ "version": "15.7.4",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz",
+ "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ=="
+ },
"@types/q": {
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz",
"integrity": "sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ=="
},
+ "@types/react": {
+ "version": "17.0.38",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.38.tgz",
+ "integrity": "sha512-SI92X1IA+FMnP3qM5m4QReluXzhcmovhZnLNm3pyeQlooi02qI7sLiepEYqT678uNiyc25XfCqxREFpy3W7YhQ==",
+ "requires": {
+ "@types/prop-types": "*",
+ "@types/scheduler": "*",
+ "csstype": "^3.0.2"
+ }
+ },
+ "@types/react-redux": {
+ "version": "7.1.21",
+ "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.21.tgz",
+ "integrity": "sha512-bLdglUiBSQNzWVVbmNPKGYYjrzp3/YDPwfOH3nLEz99I4awLlaRAPWjo6bZ2POpxztFWtDDXIPxBLVykXqBt+w==",
+ "requires": {
+ "@types/hoist-non-react-statics": "^3.3.0",
+ "@types/react": "*",
+ "hoist-non-react-statics": "^3.3.0",
+ "redux": "^4.0.0"
+ }
+ },
"@types/resolve": {
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
@@ -18525,6 +18709,11 @@
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz",
"integrity": "sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g=="
},
+ "@types/scheduler": {
+ "version": "0.16.2",
+ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
+ "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
+ },
"@types/stack-utils": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
@@ -20139,6 +20328,11 @@
}
}
},
+ "csstype": {
+ "version": "3.0.10",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.10.tgz",
+ "integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA=="
+ },
"damerau-levenshtein": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz",
@@ -21748,6 +21942,21 @@
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="
},
+ "hoist-non-react-statics": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+ "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+ "requires": {
+ "react-is": "^16.7.0"
+ },
+ "dependencies": {
+ "react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ }
+ }
+ },
"hoopy": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
@@ -25463,6 +25672,19 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
},
+ "react-redux": {
+ "version": "7.2.6",
+ "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.6.tgz",
+ "integrity": "sha512-10RPdsz0UUrRL1NZE0ejTkucnclYSgXp5q+tB5SWx2qeG2ZJQJyymgAhwKy73yiL/13btfB6fPr+rgbMAaZIAQ==",
+ "requires": {
+ "@babel/runtime": "^7.15.4",
+ "@types/react-redux": "^7.1.20",
+ "hoist-non-react-statics": "^3.3.2",
+ "loose-envify": "^1.4.0",
+ "prop-types": "^15.7.2",
+ "react-is": "^17.0.2"
+ }
+ },
"react-refresh": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
@@ -25574,6 +25796,20 @@
"strip-indent": "^3.0.0"
}
},
+ "redux": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/redux/-/redux-4.1.2.tgz",
+ "integrity": "sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==",
+ "requires": {
+ "@babel/runtime": "^7.9.2"
+ }
+ },
+ "redux-thunk": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.1.tgz",
+ "integrity": "sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q==",
+ "requires": {}
+ },
"regenerate": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
@@ -25684,6 +25920,11 @@
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
},
+ "reselect": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.5.tgz",
+ "integrity": "sha512-uVdlz8J7OO+ASpBYoz1Zypgx0KasCY20H+N8JD13oUMtPvSHQuscrHop4KbXrbsBcdB9Ds7lVK7eRkBIfO43vQ=="
+ },
"resolve": {
"version": "1.20.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
@@ -26453,6 +26694,11 @@
}
}
},
+ "sweetalert2": {
+ "version": "11.3.4",
+ "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.3.4.tgz",
+ "integrity": "sha512-o7owEtVtpqnB8y3BDCRn2taYb7URcf6RIUm120LjFxt8IHfPIm0UeHuiS3nEp5r9RKm5GlSSJOh/yuapUQcYcQ=="
+ },
"symbol-tree": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
diff --git a/package.json b/package.json
index b4815cc..be0d853 100644
--- a/package.json
+++ b/package.json
@@ -6,15 +6,19 @@
"@fortawesome/free-brands-svg-icons": "^5.15.4",
"@fortawesome/free-solid-svg-icons": "^5.15.4",
"@fortawesome/react-fontawesome": "^0.1.16",
+ "@reduxjs/toolkit": "^1.7.1",
"@testing-library/jest-dom": "^5.16.1",
"@testing-library/react": "^12.1.2",
"@testing-library/user-event": "^13.5.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-icons": "^4.3.1",
+ "react-redux": "^7.2.6",
"react-scripts": "5.0.0",
"react-tooltip": "^4.2.21",
+ "redux": "^4.1.2",
"sass": "^1.45.0",
+ "sweetalert2": "^11.3.4",
"web-vitals": "^2.1.2"
},
"scripts": {
diff --git a/src/App.js b/src/App.js
index 9ae8cc3..6f7926f 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,4 +1,8 @@
import "./App.scss";
+
+import { Provider } from "react-redux";
+import store from "./redux/store";
+
import ButtonDesign from "./components/buttonDesign/ButtonDesign";
import ProductDesign from "./components/productDesign/ProductDesign";
import ProductTags from "./components/productTags/ProductTags";
@@ -18,30 +22,36 @@ import Testttt from "./components/testtttt/Testttt";
import Design2D from "./components/Design2D/Design2D";
import Features from "./components/Features/index";
import Feedback from "./components/Feedback/index";
+import Alert from "./components/Alert";
+import Toast from "./components/Toast";
function App() {
return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {/*
*/}
-
-
-
-
+
+
+ {/*
*/}
+ {/*
*/}
+ {/*
*/}
+ {/*
*/}
+ {/*
*/}
+ {/*
*/}
+ {/*
*/}
+ {/*
*/}
+ {/*
*/}
+ {/*
*/}
+ {/*
*/}
+ {/*
*/}
+ {/*
*/}
+ {/*
*/}
+ {/*
*/}
+ {/*
*/}
+ {/*
*/}
+ {/*
*/}
+ {/*
*/}
+
+
+
+
);
}
diff --git a/src/components/Alert/index.js b/src/components/Alert/index.js
new file mode 100644
index 0000000..1ce02e3
--- /dev/null
+++ b/src/components/Alert/index.js
@@ -0,0 +1,248 @@
+import React from "react";
+import "./index.scss";
+
+import { infoAlert } from "../../redux/actions/modalActions";
+import { connect } from "react-redux";
+
+function Alert(props) {
+ return (
+
+ {/* 1 */}
+
+ {/* 2 */}
+
+ {/* 3 */}
+
+ {/* 4 */}
+
+ {/* 5 */}
+
+ {/* 6 */}
+
+ {/* 7 */}
+
+ {/* 8 */}
+
+ {/* 9 */}
+
+ {/* 10 */}
+
+
+ );
+}
+
+const mapStateToProps = (state) => {
+ return {};
+};
+
+// export default Alert;
+
+export default connect(mapStateToProps, { customAlert: infoAlert })(Alert);
diff --git a/src/components/Alert/index.scss b/src/components/Alert/index.scss
new file mode 100644
index 0000000..e23a8eb
--- /dev/null
+++ b/src/components/Alert/index.scss
@@ -0,0 +1,255 @@
+/* TODO common styles */
+.swal2-container.swal2-center > .swal2-popup {
+ border: solid 2px #707070 !important;
+ padding: 10px !important;
+}
+/* ? کلاس تمامی تایتل ها */
+.swal2-title {
+ text-align: right !important;
+ font-size: 26px !important;
+}
+/* ? کلاس متن داخل الرت باکس */
+.swal2-html-container {
+ text-align: justify !important;
+ line-height: 1.8 !important;
+ color: $contentcolor !important;
+ font-weight: 600 !important;
+}
+/* ? کلاس ایکن کنسل یا ضربدر بالا سمت چپ الرت باکس */
+.swal2-rtl .swal2-close {
+ border-radius: 10px !important;
+ margin-left: 10px !important;
+ margin-top: 13px !important;
+ transition: all 0.4s !important;
+}
+/* ? کلاس کانفرم باتن */
+.swal2-styled.swal2-confirm {
+ transition: all 0.4s !important;
+ outline: none !important;
+}
+/* ? کلاس هاور کانفرم باتن */
+.swal2-styled.swal2-confirm:hover {
+ transform: translateY(-5px) !important;
+}
+/* ? کلاس کنسل باتن */
+.swal2-styled.swal2-cancel {
+ transition: all 0.4s !important;
+}
+/* ? کلاس هاور کنسل باتن */
+.swal2-styled.swal2-cancel:hover {
+ transform: translateY(-5px) !important;
+}
+/* ? ایکن اررور */
+.swal2-icon.swal2-error {
+ border-color: var(--error-color7-button) !important;
+ color: var(--error-color7-button) !important;
+}
+/* !error 1 */
+/* به اررور های ابی رنگ کلاس هایی دادم که اخرش با 1 تمام میشود */
+/* TODO باکس اول از سمت راست در فایل پی اس دی */
+/* ? تایتل */
+.title-error-1 {
+ color: var(--error-color1) !important;
+}
+
+.eroorr:focus {
+ outline: none !important;
+ box-shadow: 0px 0px 0px black !important;
+ border: 0px !important;
+}
+/* ? دکمه ضربدر بالا سمت چپ */
+.close-button-1 {
+ background-color: var(--error-color1) !important;
+ color: var(--white) !important;
+}
+/* ? هاور دکمه ضربدر بالا سمت چپ */
+.close-button-1:hover {
+ background-color: var(--white) !important;
+ color: var(--error-color1) !important;
+ border: solid 4px var(--error-color1) !important;
+}
+/* ? کانفرم باتن */
+.confirm-button-1 {
+ background-color: var(--white) !important;
+ border: solid 2px var(--error-color1) !important;
+ color: var(--error-color1) !important;
+ text-align: left !important;
+}
+/* ? هاور کانفرم باتن */
+.confirm-button-1:hover {
+ background-color: var(--error-color1) !important;
+ color: var(--white) !important;
+}
+/* !error 2 */
+/* ? کنسل باتن */
+.cancle-button1 {
+ background-color: var(--error-color1) !important;
+ color: var(--white) !important;
+ border: solid 2px var(--error-color1) !important;
+}
+/* ? هاور کنسل باتن */
+.cancle-button1:hover {
+ background-color: var(--white) !important;
+ color: var(--error-color1) !important;
+}
+/* !error3 */
+/* ? تایتل */
+.title-error-2 {
+ color: var(--error-color2) !important;
+}
+/* ? دکمه ضربدر بالا سمت چپ */
+.close-button-2 {
+ background-color: var(--error-color2) !important;
+ color: var(--white) !important;
+}
+/* ? هاور دکمه ضربدر بالا سمت چپ */
+.close-button-2:hover {
+ background-color: var(--white) !important;
+ color: var(--error-color2) !important;
+ border: solid 4px var(--error-color2) !important;
+}
+/* ? کانفرم باتن */
+.confirm-button-2 {
+ background-color: var(--white) !important;
+ border: solid 2px var(--error-color2) !important;
+ color: var(--error-color2) !important;
+}
+/* ? هاور کانفرم باتن */
+.confirm-button-2:hover {
+ background-color: var(--error-color2) !important;
+ color: var(--white) !important;
+}
+/* ? کنسل باتن */
+.cancle-button2 {
+ background-color: var(--error-color2) !important;
+ color: var(--white) !important;
+ border: solid 2px var(--error-color2) !important;
+}
+/* ? هاور کنسل باتن */
+.cancle-button2:hover {
+ background-color: var(--white) !important;
+ color: var(--error-color2) !important;
+}
+/* !error4 */
+/* ? تایتل */
+.title-error-4 {
+ text-align: center !important;
+ color: var(--error-color2) !important;
+}
+.alert-popup4 {
+ width: 440px !important;
+}
+/* !error5 */
+/* ? کانفرم باتن */
+.confirm-button-5 {
+ background-color: var(--error-color2) !important;
+ margin-top: -81px !important;
+ margin-left: -260px !important;
+ padding: 12px 15px !important;
+ border-top-right-radius: 0px !important;
+ border-bottom-right-radius: 0px !important;
+}
+/* ? اینپوت فیلد */
+.input-error-5 {
+ width: 70% !important;
+ height: 47px !important ;
+ border-top-left-radius: 0px !important;
+ border-bottom-left-radius: 0px !important;
+}
+/* !error6 */
+/* ? دکمه ضربدر بالا سمت چپ */
+.close-button-6 {
+ color: var(--error-color1) !important;
+}
+/* ? هاور دکمه ضربدر بالا سمت چپ */
+.close-button-6:hover {
+ background-color: var(--error-color1) !important;
+ color: var(--white) !important;
+ border: solid 4px var(--error-color1) !important;
+}
+/* !error7 */
+/* ? تایتل */
+.title-error-7 {
+ color: var(--error-color7) !important;
+}
+/* ? دکمه ضربدر بالا سمت چپ */
+.close-button-7 {
+ background-color: var(--error-color7-button) !important;
+ color: var(--white) !important;
+}
+/* ? هاور دکمه ضربدر بالا سمت چپ */
+.close-button-7:hover {
+ background-color: var(--white) !important;
+ color: var(--error-color7) !important;
+ border: solid 4px var(--error-color7-button) !important;
+}
+/* ? کانفرم باتن */
+.confirm-button-7 {
+ background-color: var(--white) !important;
+ border: solid 2px var(--error-color7-button) !important;
+ color: var(--error-color7) !important;
+}
+/* ? هاور کانفرم باتن */
+.confirm-button-7:hover {
+ background-color: var(--error-color7-button) !important;
+ color: var(--white) !important;
+}
+/* ? کنسل باتن */
+.cancle-button7 {
+ background-color: var(--error-color7-button) !important;
+ color: var(--white) !important;
+ border: solid 2px var(--error-color7-button) !important;
+}
+/* ? هاور کنسل باتن */
+.cancle-button7:hover {
+ background-color: var(--white) !important;
+ color: var(--error-color7-button) !important;
+}
+/* !error8 */
+.title-error-8 {
+ color: var(--error-color7-button) !important;
+ text-align: center !important;
+}
+.alert-popup8 {
+ width: 440px !important;
+}
+/* !error9 */
+.title-error-9 {
+ color: var(--white) !important;
+}
+.alert-popup9 {
+ background-color: var(--error-color2) !important;
+ border-color: var(--error-color2) !important;
+}
+.close-button-9 {
+ background-color: var(--toast-bg-success) !important;
+ color: var(--toast-success-color) !important;
+}
+.confirm-button-9 {
+ background-color: #35bb20 !important;
+}
+.cancle-button9 {
+ background-color: var(--white) !important;
+ color: var(--error-color2) !important;
+}
+.footer-error-9 a {
+ color: var(--white) !important;
+ border-bottom-color: var(--white) !important;
+ font-size: 18px !important;
+}
+/* !error10 */
+.alert-popup10 {
+ background-color: var(--error-color7-button) !important;
+ border-color: var(--error-color7-button) !important;
+}
+.close-button-10 {
+ background-color: #fd6a6a !important;
+ color: var(--white) !important;
+}
+.confirm-button-10 {
+ background-color: #bb2020 !important;
+}
+.cancle-button10 {
+ background-color: var(--white) !important;
+ color: var(--error-color7-button) !important;
+}
diff --git a/src/components/Toast/index.js b/src/components/Toast/index.js
new file mode 100644
index 0000000..87c43fb
--- /dev/null
+++ b/src/components/Toast/index.js
@@ -0,0 +1,157 @@
+import React from "react";
+// import "./SweetAlert.css";
+import { toastAlert } from "../../redux/actions/modalActions";
+import { connect } from "react-redux";
+
+function Toast(props) {
+ return (
+
+ {/* toast1 */}
+
+ {/* toast2 */}
+
+ {/* toast3 */}
+
+ {/* toast4 */}
+
+ {/* toast5 */}
+
+ {/* toast6 */}
+
+
+ );
+}
+
+const mapStateToProps = (state) => {
+ return {};
+};
+
+export default connect(mapStateToProps, { customAlert: toastAlert })(Toast);
diff --git a/src/index.scss b/src/index.scss
index e3004a8..aa220f6 100644
--- a/src/index.scss
+++ b/src/index.scss
@@ -23,3 +23,14 @@ body {
padding-right: 4px;
border-radius: 50%;
}
+
+$errorcolor1: #06bace;
+$errorcolor2: #3ee924;
+$errorcolor7: #c70000;
+$errorcolor7button: #e92424;
+$white: #fff;
+$black: #000;
+$contentcolor: #646464;
+$toastbgerror: #ffeaea;
+$toastbgsuccess: #c3ffb9;
+$toastsuccesscolor: #21ae0b;
diff --git a/src/redux/actions/modalActions.js b/src/redux/actions/modalActions.js
new file mode 100644
index 0000000..544b87d
--- /dev/null
+++ b/src/redux/actions/modalActions.js
@@ -0,0 +1,15 @@
+import { INFO_ALERT, TOAST_ALERT } from "./types";
+
+export const infoAlert = (data) => (dispatch) => {
+ dispatch({
+ type: INFO_ALERT,
+ data: data,
+ });
+};
+
+export const toastAlert = (data) => (dispatch) => {
+ dispatch({
+ type: TOAST_ALERT,
+ data: data,
+ });
+};
diff --git a/src/redux/actions/types.js b/src/redux/actions/types.js
new file mode 100644
index 0000000..9e388f9
--- /dev/null
+++ b/src/redux/actions/types.js
@@ -0,0 +1,2 @@
+export const INFO_ALERT = "INFO_ALERT";
+export const TOAST_ALERT = "TOAST_ALERT";
diff --git a/src/redux/reducers/modalReducer.js b/src/redux/reducers/modalReducer.js
new file mode 100644
index 0000000..6f685bb
--- /dev/null
+++ b/src/redux/reducers/modalReducer.js
@@ -0,0 +1,44 @@
+import { INFO_ALERT } from "../actions/types";
+import Swal from "sweetalert2";
+
+const initialState = {};
+
+const modalReducer = (state = initialState, action) => {
+ const { type, data } = action;
+ switch (type) {
+ case INFO_ALERT:
+ Swal.fire({
+ icon: data.icon,
+ title: data.title,
+ text: data.text,
+ input: data.input,
+ inputPlaceholder: data.inputPlaceholder,
+ imageUrl: data.imageUrl,
+ imageAlt: data.imageAlt,
+ imageWidth: data.imageWidth,
+ imageHeight: data.imageHeight,
+ confirmButtonText: data.confirmButtonText,
+ showCloseButton: data.showCloseButton,
+ showCancelButton: data.showCancelButton,
+ cancelButtonText: data.cancelButtonText,
+ html: data.html,
+ footer: data.footer,
+ customClass: {
+ title: data.customClass.title,
+ closeButton: data.customClass.closeButton,
+ confirmButton: data.customClass.confirmButton,
+ cancelButton: data.customClass.cancelButton,
+ popup: data.customClass.popup,
+ input: data.customClass.input,
+ footer: data.customClass.footer,
+ },
+ });
+ return {
+ ...state,
+ };
+ default:
+ return state;
+ }
+};
+
+export default modalReducer;
diff --git a/src/redux/reducers/rootReducer.js b/src/redux/reducers/rootReducer.js
new file mode 100644
index 0000000..4e1f863
--- /dev/null
+++ b/src/redux/reducers/rootReducer.js
@@ -0,0 +1,10 @@
+import modalReducer from "./modalReducer";
+import toastReducer from "./toastReducer";
+import { combineReducers } from "redux";
+
+const rootReducer = combineReducers({
+ modalReducer: modalReducer,
+ toastReducer: toastReducer,
+});
+
+export default rootReducer;
diff --git a/src/redux/reducers/toastReducer.js b/src/redux/reducers/toastReducer.js
new file mode 100644
index 0000000..f4fd787
--- /dev/null
+++ b/src/redux/reducers/toastReducer.js
@@ -0,0 +1,34 @@
+import { INFO_ALERT, TOAST_ALERT } from "../actions/types";
+import Swal from "sweetalert2";
+
+const initialState = {};
+
+const toastReducer = (state = initialState, action) => {
+ const { type, data } = action;
+ switch (type) {
+ case TOAST_ALERT:
+ Swal.fire({
+ icon: data.icon,
+ title: data.title,
+ showCloseButton: data.showCloseButton,
+ toast: data.toast,
+ position: data.position,
+ showConfirmButton: data.showConfirmButton,
+ timer: data.timer,
+ timerProgressBar: data.timerProgressBar,
+ customClass: {
+ title: data.customClass.title,
+ closeButton: data.customClass.closeButton,
+ popup: data.customClass.popup,
+ footer: data.customClass.footer,
+ },
+ });
+ return {
+ ...state,
+ };
+ default:
+ return state;
+ }
+};
+
+export default toastReducer;
diff --git a/src/redux/store.js b/src/redux/store.js
new file mode 100644
index 0000000..405ef0a
--- /dev/null
+++ b/src/redux/store.js
@@ -0,0 +1,6 @@
+import { createStore, applyMiddleware } from "redux";
+import thunk from "redux-thunk";
+import rootReducer from "./reducers/rootReducer";
+
+const store = createStore(rootReducer, applyMiddleware(thunk));
+export default store;