From 3091043e08bce7676610058c0be25e566200d9bc Mon Sep 17 00:00:00 2001
From: Ylva Karlsson <121539816+YlvaKarlsson@users.noreply.github.com>
Date: Tue, 18 Apr 2023 10:29:19 +0200
Subject: [PATCH 01/28] Initial commit
---
code/.eslintrc.json | 4 +
code/package-lock.json | 263 +++++++++++++++++++++++++++++++++++++++--
code/package.json | 4 +-
3 files changed, 261 insertions(+), 10 deletions(-)
diff --git a/code/.eslintrc.json b/code/.eslintrc.json
index c9c0675c3..81138c66f 100644
--- a/code/.eslintrc.json
+++ b/code/.eslintrc.json
@@ -42,6 +42,10 @@
"allowSingleLine": true
}
],
+ "linebreak-style":[
+ "off",
+ "unix"
+ ],
"comma-dangle": [
"error",
"never"
diff --git a/code/package-lock.json b/code/package-lock.json
index bb51e893e..292180b53 100644
--- a/code/package-lock.json
+++ b/code/package-lock.json
@@ -9,6 +9,7 @@
"version": "1.0.0",
"dependencies": {
"@babel/eslint-parser": "^7.18.9",
+ "@reduxjs/toolkit": "^1.9.5",
"eslint": "^8.21.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-plugin-import": "^2.26.0",
@@ -16,7 +17,8 @@
"eslint-plugin-react": "^7.30.1",
"eslint-plugin-react-hooks": "^4.6.0",
"react": "^18.2.0",
- "react-dom": "^18.2.0"
+ "react-dom": "^18.2.0",
+ "react-redux": "^8.0.5"
},
"devDependencies": {
"react-scripts": "5.0.1"
@@ -3124,6 +3126,29 @@
}
}
},
+ "node_modules/@reduxjs/toolkit": {
+ "version": "1.9.5",
+ "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.5.tgz",
+ "integrity": "sha512-Rt97jHmfTeaxL4swLRNPD/zV4OxTes4la07Xc4hetpUW/vc75t5m1ANyxG6ymnEQ2FsLQsoMlYB2vV1sO3m8tQ==",
+ "dependencies": {
+ "immer": "^9.0.21",
+ "redux": "^4.2.1",
+ "redux-thunk": "^2.4.2",
+ "reselect": "^4.1.8"
+ },
+ "peerDependencies": {
+ "react": "^16.9.0 || ^17.0.0 || ^18",
+ "react-redux": "^7.2.1 || ^8.0.2"
+ },
+ "peerDependenciesMeta": {
+ "react": {
+ "optional": true
+ },
+ "react-redux": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@rollup/plugin-babel": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
@@ -3621,6 +3646,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",
@@ -3695,6 +3729,11 @@
"integrity": "sha512-fOwvpvQYStpb/zHMx0Cauwywu9yLDmzWiiQBC7gJyq5tYLUXFZvDG7VK1B7WBxxjBJNKFOZ0zLoOQn8vmATbhw==",
"dev": true
},
+ "node_modules/@types/prop-types": {
+ "version": "15.7.5",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
+ "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
+ },
"node_modules/@types/q": {
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz",
@@ -3713,6 +3752,16 @@
"integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==",
"dev": true
},
+ "node_modules/@types/react": {
+ "version": "18.0.37",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.37.tgz",
+ "integrity": "sha512-4yaZZtkRN3ZIQD3KSEwkfcik8s0SWV+82dlJot1AbGYHCzJkWP3ENBY6wYeDRmKZ6HkrgoGAmR2HqdwYGp6OEw==",
+ "dependencies": {
+ "@types/prop-types": "*",
+ "@types/scheduler": "*",
+ "csstype": "^3.0.2"
+ }
+ },
"node_modules/@types/resolve": {
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
@@ -3728,6 +3777,11 @@
"integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==",
"dev": true
},
+ "node_modules/@types/scheduler": {
+ "version": "0.16.3",
+ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
+ "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ=="
+ },
"node_modules/@types/serve-index": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz",
@@ -3768,6 +3822,11 @@
"integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==",
"dev": true
},
+ "node_modules/@types/use-sync-external-store": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
+ "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
+ },
"node_modules/@types/ws": {
"version": "8.5.3",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz",
@@ -6095,6 +6154,11 @@
"integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==",
"dev": true
},
+ "node_modules/csstype": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
+ "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
+ },
"node_modules/damerau-levenshtein": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
@@ -8515,6 +8579,14 @@
"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/hoopy": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
@@ -8800,10 +8872,9 @@
}
},
"node_modules/immer": {
- "version": "9.0.15",
- "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.15.tgz",
- "integrity": "sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ==",
- "dev": true,
+ "version": "9.0.21",
+ "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz",
+ "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/immer"
@@ -14375,6 +14446,49 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
+ "node_modules/react-redux": {
+ "version": "8.0.5",
+ "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.5.tgz",
+ "integrity": "sha512-Q2f6fCKxPFpkXt1qNRZdEDLlScsDWyrgSj0mliK59qU6W5gvBiKkdMEG2lJzhd1rCctf0hb6EtePPLZ2e0m1uw==",
+ "dependencies": {
+ "@babel/runtime": "^7.12.1",
+ "@types/hoist-non-react-statics": "^3.3.1",
+ "@types/use-sync-external-store": "^0.0.3",
+ "hoist-non-react-statics": "^3.3.2",
+ "react-is": "^18.0.0",
+ "use-sync-external-store": "^1.0.0"
+ },
+ "peerDependencies": {
+ "@types/react": "^16.8 || ^17.0 || ^18.0",
+ "@types/react-dom": "^16.8 || ^17.0 || ^18.0",
+ "react": "^16.8 || ^17.0 || ^18.0",
+ "react-dom": "^16.8 || ^17.0 || ^18.0",
+ "react-native": ">=0.59",
+ "redux": "^4"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ },
+ "react-native": {
+ "optional": true
+ },
+ "redux": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-redux/node_modules/react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
+ },
"node_modules/react-refresh": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
@@ -14531,6 +14645,22 @@
"node": "*"
}
},
+ "node_modules/redux": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
+ "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
+ "dependencies": {
+ "@babel/runtime": "^7.9.2"
+ }
+ },
+ "node_modules/redux-thunk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz",
+ "integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==",
+ "peerDependencies": {
+ "redux": "^4"
+ }
+ },
"node_modules/regenerate": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
@@ -14686,6 +14816,11 @@
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
"dev": true
},
+ "node_modules/reselect": {
+ "version": "4.1.8",
+ "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz",
+ "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ=="
+ },
"node_modules/resolve": {
"version": "1.22.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
@@ -16340,6 +16475,14 @@
"punycode": "^2.1.0"
}
},
+ "node_modules/use-sync-external-store": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
+ "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@@ -19509,6 +19652,17 @@
"source-map": "^0.7.3"
}
},
+ "@reduxjs/toolkit": {
+ "version": "1.9.5",
+ "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.5.tgz",
+ "integrity": "sha512-Rt97jHmfTeaxL4swLRNPD/zV4OxTes4la07Xc4hetpUW/vc75t5m1ANyxG6ymnEQ2FsLQsoMlYB2vV1sO3m8tQ==",
+ "requires": {
+ "immer": "^9.0.21",
+ "redux": "^4.2.1",
+ "redux-thunk": "^2.4.2",
+ "reselect": "^4.1.8"
+ }
+ },
"@rollup/plugin-babel": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
@@ -19876,6 +20030,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",
@@ -19950,6 +20113,11 @@
"integrity": "sha512-fOwvpvQYStpb/zHMx0Cauwywu9yLDmzWiiQBC7gJyq5tYLUXFZvDG7VK1B7WBxxjBJNKFOZ0zLoOQn8vmATbhw==",
"dev": true
},
+ "@types/prop-types": {
+ "version": "15.7.5",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
+ "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
+ },
"@types/q": {
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz",
@@ -19968,6 +20136,16 @@
"integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==",
"dev": true
},
+ "@types/react": {
+ "version": "18.0.37",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.37.tgz",
+ "integrity": "sha512-4yaZZtkRN3ZIQD3KSEwkfcik8s0SWV+82dlJot1AbGYHCzJkWP3ENBY6wYeDRmKZ6HkrgoGAmR2HqdwYGp6OEw==",
+ "requires": {
+ "@types/prop-types": "*",
+ "@types/scheduler": "*",
+ "csstype": "^3.0.2"
+ }
+ },
"@types/resolve": {
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
@@ -19983,6 +20161,11 @@
"integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==",
"dev": true
},
+ "@types/scheduler": {
+ "version": "0.16.3",
+ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
+ "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ=="
+ },
"@types/serve-index": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz",
@@ -20023,6 +20206,11 @@
"integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==",
"dev": true
},
+ "@types/use-sync-external-store": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
+ "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
+ },
"@types/ws": {
"version": "8.5.3",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz",
@@ -21748,6 +21936,11 @@
}
}
},
+ "csstype": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
+ "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
+ },
"damerau-levenshtein": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
@@ -23521,6 +23714,14 @@
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
"dev": true
},
+ "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"
+ }
+ },
"hoopy": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
@@ -23739,10 +23940,9 @@
"integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ=="
},
"immer": {
- "version": "9.0.15",
- "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.15.tgz",
- "integrity": "sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ==",
- "dev": true
+ "version": "9.0.21",
+ "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz",
+ "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA=="
},
"import-fresh": {
"version": "3.3.0",
@@ -27678,6 +27878,26 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
+ "react-redux": {
+ "version": "8.0.5",
+ "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.5.tgz",
+ "integrity": "sha512-Q2f6fCKxPFpkXt1qNRZdEDLlScsDWyrgSj0mliK59qU6W5gvBiKkdMEG2lJzhd1rCctf0hb6EtePPLZ2e0m1uw==",
+ "requires": {
+ "@babel/runtime": "^7.12.1",
+ "@types/hoist-non-react-statics": "^3.3.1",
+ "@types/use-sync-external-store": "^0.0.3",
+ "hoist-non-react-statics": "^3.3.2",
+ "react-is": "^18.0.0",
+ "use-sync-external-store": "^1.0.0"
+ },
+ "dependencies": {
+ "react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
+ }
+ }
+ },
"react-refresh": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
@@ -27800,6 +28020,20 @@
}
}
},
+ "redux": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
+ "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
+ "requires": {
+ "@babel/runtime": "^7.9.2"
+ }
+ },
+ "redux-thunk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz",
+ "integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==",
+ "requires": {}
+ },
"regenerate": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
@@ -27924,6 +28158,11 @@
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
"dev": true
},
+ "reselect": {
+ "version": "4.1.8",
+ "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz",
+ "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ=="
+ },
"resolve": {
"version": "1.22.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
@@ -29163,6 +29402,12 @@
"punycode": "^2.1.0"
}
},
+ "use-sync-external-store": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
+ "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
+ "requires": {}
+ },
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
diff --git a/code/package.json b/code/package.json
index 7aad26ebc..f971764b9 100644
--- a/code/package.json
+++ b/code/package.json
@@ -4,6 +4,7 @@
"private": true,
"dependencies": {
"@babel/eslint-parser": "^7.18.9",
+ "@reduxjs/toolkit": "^1.9.5",
"eslint": "^8.21.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-plugin-import": "^2.26.0",
@@ -11,7 +12,8 @@
"eslint-plugin-react": "^7.30.1",
"eslint-plugin-react-hooks": "^4.6.0",
"react": "^18.2.0",
- "react-dom": "^18.2.0"
+ "react-dom": "^18.2.0",
+ "react-redux": "^8.0.5"
},
"scripts": {
"start": "react-scripts start",
From 6e14c67ac047336cd4db3dd5295b80434b4f0e6d Mon Sep 17 00:00:00 2001
From: Ylva Karlsson <121539816+YlvaKarlsson@users.noreply.github.com>
Date: Tue, 18 Apr 2023 12:08:31 +0200
Subject: [PATCH 02/28] Some kind of a working to do list - yey
---
code/.gitignore | 23 ---------
code/package-lock.json | 84 ++++++++++++++++++++++++++++++--
code/package.json | 2 +
code/src/App.js | 20 ++++++--
code/src/components/AddToDo.js | 32 ++++++++++++
code/src/components/ToDoItem.js | 0
code/src/components/ToDoList.js | 17 +++++++
code/src/redux/reducers/todos.js | 36 ++++++++++++++
code/src/redux/store.js | 0
9 files changed, 183 insertions(+), 31 deletions(-)
delete mode 100644 code/.gitignore
create mode 100644 code/src/components/AddToDo.js
create mode 100644 code/src/components/ToDoItem.js
create mode 100644 code/src/components/ToDoList.js
create mode 100644 code/src/redux/reducers/todos.js
create mode 100644 code/src/redux/store.js
diff --git a/code/.gitignore b/code/.gitignore
deleted file mode 100644
index 4d29575de..000000000
--- a/code/.gitignore
+++ /dev/null
@@ -1,23 +0,0 @@
-# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
-
-# dependencies
-/node_modules
-/.pnp
-.pnp.js
-
-# testing
-/coverage
-
-# production
-/build
-
-# misc
-.DS_Store
-.env.local
-.env.development.local
-.env.test.local
-.env.production.local
-
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
diff --git a/code/package-lock.json b/code/package-lock.json
index 292180b53..6c941cd81 100644
--- a/code/package-lock.json
+++ b/code/package-lock.json
@@ -16,8 +16,10 @@
"eslint-plugin-jsx-a11y": "^6.6.1",
"eslint-plugin-react": "^7.30.1",
"eslint-plugin-react-hooks": "^4.6.0",
+ "framer-motion": "^10.12.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
+ "react-icons": "^4.8.0",
"react-redux": "^8.0.5"
},
"devDependencies": {
@@ -2155,6 +2157,21 @@
"postcss-selector-parser": "^6.0.10"
}
},
+ "node_modules/@emotion/is-prop-valid": {
+ "version": "0.8.8",
+ "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz",
+ "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==",
+ "optional": true,
+ "dependencies": {
+ "@emotion/memoize": "0.7.4"
+ }
+ },
+ "node_modules/@emotion/memoize": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz",
+ "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==",
+ "optional": true
+ },
"node_modules/@eslint/eslintrc": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz",
@@ -8213,6 +8230,29 @@
"url": "https://www.patreon.com/infusion"
}
},
+ "node_modules/framer-motion": {
+ "version": "10.12.3",
+ "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-10.12.3.tgz",
+ "integrity": "sha512-OQrfIMJrWrcnyQ+K3VkDboQHigCk8pqFjXLedbpl/V7P7X8d1DX/dK1/lefLx5hIcdnsmT1DQDpZBQGnYZGh1Q==",
+ "dependencies": {
+ "tslib": "^2.4.0"
+ },
+ "optionalDependencies": {
+ "@emotion/is-prop-valid": "^0.8.2"
+ },
+ "peerDependencies": {
+ "react": "^18.0.0",
+ "react-dom": "^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/fresh": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
@@ -14441,6 +14481,14 @@
"integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==",
"dev": true
},
+ "node_modules/react-icons": {
+ "version": "4.8.0",
+ "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.8.0.tgz",
+ "integrity": "sha512-N6+kOLcihDiAnj5Czu637waJqSnwlMNROzVZMhfX68V/9bu9qHaMIJC4UdozWoOk57gahFCNHwVvWzm0MTzRjg==",
+ "peerDependencies": {
+ "react": "*"
+ }
+ },
"node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
@@ -16250,8 +16298,7 @@
"node_modules/tslib": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
- "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
- "dev": true
+ "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
},
"node_modules/tsutils": {
"version": "3.21.0",
@@ -18935,6 +18982,21 @@
"dev": true,
"requires": {}
},
+ "@emotion/is-prop-valid": {
+ "version": "0.8.8",
+ "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz",
+ "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==",
+ "optional": true,
+ "requires": {
+ "@emotion/memoize": "0.7.4"
+ }
+ },
+ "@emotion/memoize": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz",
+ "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==",
+ "optional": true
+ },
"@eslint/eslintrc": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz",
@@ -23452,6 +23514,15 @@
"integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==",
"dev": true
},
+ "framer-motion": {
+ "version": "10.12.3",
+ "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-10.12.3.tgz",
+ "integrity": "sha512-OQrfIMJrWrcnyQ+K3VkDboQHigCk8pqFjXLedbpl/V7P7X8d1DX/dK1/lefLx5hIcdnsmT1DQDpZBQGnYZGh1Q==",
+ "requires": {
+ "@emotion/is-prop-valid": "^0.8.2",
+ "tslib": "^2.4.0"
+ }
+ },
"fresh": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
@@ -27873,6 +27944,12 @@
"integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==",
"dev": true
},
+ "react-icons": {
+ "version": "4.8.0",
+ "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.8.0.tgz",
+ "integrity": "sha512-N6+kOLcihDiAnj5Czu637waJqSnwlMNROzVZMhfX68V/9bu9qHaMIJC4UdozWoOk57gahFCNHwVvWzm0MTzRjg==",
+ "requires": {}
+ },
"react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
@@ -29247,8 +29324,7 @@
"tslib": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
- "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
- "dev": true
+ "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
},
"tsutils": {
"version": "3.21.0",
diff --git a/code/package.json b/code/package.json
index f971764b9..78fb8e423 100644
--- a/code/package.json
+++ b/code/package.json
@@ -11,8 +11,10 @@
"eslint-plugin-jsx-a11y": "^6.6.1",
"eslint-plugin-react": "^7.30.1",
"eslint-plugin-react-hooks": "^4.6.0",
+ "framer-motion": "^10.12.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
+ "react-icons": "^4.8.0",
"react-redux": "^8.0.5"
},
"scripts": {
diff --git a/code/src/App.js b/code/src/App.js
index f2007d229..f032cb804 100644
--- a/code/src/App.js
+++ b/code/src/App.js
@@ -1,9 +1,21 @@
import React from 'react';
+import { Provider } from 'react-redux';
+import { configureStore, combineReducers } from '@reduxjs/toolkit';
+import AddToDo from 'components/AddToDo';
+import ToDoList from 'components/ToDoList';
+import todos from 'redux/reducers/todos'
export const App = () => {
+ const reducer = combineReducers({
+ todos: todos.reducer
+ });
+ const store = configureStore({ reducer });
return (
-
- Find me in src/app.js!
-
- );
+
+
+
+
+ )
}
+
+// ctrl + c inside the terminal to stop the liveServer
\ No newline at end of file
diff --git a/code/src/components/AddToDo.js b/code/src/components/AddToDo.js
new file mode 100644
index 000000000..e98299848
--- /dev/null
+++ b/code/src/components/AddToDo.js
@@ -0,0 +1,32 @@
+import React, { useState } from 'react';
+import { useDispatch } from 'react-redux';
+import todos from 'redux/reducers/todos';
+
+const AddToDo = () => {
+ const [inputValue, setInputValue] = useState('');
+ const dispatch = useDispatch();
+ const onFormSubmit = (event) => {
+ event.preventDefault();
+ const newToDo = {
+ id: Date.now().toString(),
+ name: inputValue.charAt(0).toUpperCase() + inputValue.slice(1),
+ isNew: false
+ };
+ dispatch(todos.actions.addToDo(newToDo));
+ setInputValue('');
+ // https://www.random.org
+ }
+ return (
+
+ )
+}
+
+export default AddToDo;
\ No newline at end of file
diff --git a/code/src/components/ToDoItem.js b/code/src/components/ToDoItem.js
new file mode 100644
index 000000000..e69de29bb
diff --git a/code/src/components/ToDoList.js b/code/src/components/ToDoList.js
new file mode 100644
index 000000000..b588cc593
--- /dev/null
+++ b/code/src/components/ToDoList.js
@@ -0,0 +1,17 @@
+import React from 'react';
+import { useSelector } from 'react-redux';
+
+const ToDoList = () => {
+ const todoList = useSelector((store) => store.todos.items)
+ return (
+
+
+ {todoList.map((singleToDo) => {
+ return - {singleToDo.name}
+ })}
+
+
+ )
+}
+
+export default ToDoList;
\ No newline at end of file
diff --git a/code/src/redux/reducers/todos.js b/code/src/redux/reducers/todos.js
new file mode 100644
index 000000000..bcc64a0d7
--- /dev/null
+++ b/code/src/redux/reducers/todos.js
@@ -0,0 +1,36 @@
+import { createSlice } from '@reduxjs/toolkit';
+
+const initialState = {
+ items: [
+ {
+ id: '189438fdjhrjejioe9845',
+ name: 'ToDo1',
+ isNew: false
+ },
+ {
+ id: '189438fdjhrjejioe9846',
+ name: 'ToDo2',
+ isNew: false
+ },
+ {
+ id: '189438fdjhrjejioe9847',
+ name: 'ToDo3',
+ isNew: false
+ }
+ ]
+}
+
+const todos = createSlice({
+ name: 'todos',
+ initialState,
+ reducers: {
+ addToDo: (store, action) => {
+ // Mutable
+ // store.items.push(action.payload);
+ // Immutable
+ store.items = [...store.items, action.payload];
+ }
+ }
+});
+
+export default todos;
\ No newline at end of file
diff --git a/code/src/redux/store.js b/code/src/redux/store.js
new file mode 100644
index 000000000..e69de29bb
From e4d1c0a0d0553f1048aeb299f200e1e761460083 Mon Sep 17 00:00:00 2001
From: Ylva Karlsson <121539816+YlvaKarlsson@users.noreply.github.com>
Date: Thu, 20 Apr 2023 12:29:10 +0200
Subject: [PATCH 03/28] Some more things are working and some are still in
progress
---
code/package-lock.json | 461 ++++++++++++++++++++++++++---
code/package.json | 5 +-
code/public/favicon.ico | Bin 0 -> 1383 bytes
code/public/index.html | 4 +-
code/src/App.js | 22 +-
code/src/components/AddToDo.js | 68 ++++-
code/src/components/GlobalStyle.js | 50 ++++
code/src/components/ToDoItem.js | 42 +++
code/src/components/ToDoList.js | 77 ++++-
code/src/index.css | 2 +
code/src/redux/reducers/todos.js | 81 +++--
11 files changed, 712 insertions(+), 100 deletions(-)
create mode 100644 code/public/favicon.ico
create mode 100644 code/src/components/GlobalStyle.js
diff --git a/code/package-lock.json b/code/package-lock.json
index 6c941cd81..88ee3d540 100644
--- a/code/package-lock.json
+++ b/code/package-lock.json
@@ -17,10 +17,13 @@
"eslint-plugin-react": "^7.30.1",
"eslint-plugin-react-hooks": "^4.6.0",
"framer-motion": "^10.12.3",
+ "moment": "^2.29.4",
"react": "^18.2.0",
+ "react-datepicker": "^4.11.0",
"react-dom": "^18.2.0",
"react-icons": "^4.8.0",
- "react-redux": "^8.0.5"
+ "react-redux": "^8.0.5",
+ "styled-components.macro": "^1.0.0"
},
"devDependencies": {
"react-scripts": "5.0.1"
@@ -133,7 +136,6 @@
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz",
"integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==",
- "dev": true,
"dependencies": {
"@babel/types": "^7.18.6"
},
@@ -2172,6 +2174,18 @@
"integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==",
"optional": true
},
+ "node_modules/@emotion/stylis": {
+ "version": "0.8.5",
+ "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz",
+ "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==",
+ "peer": true
+ },
+ "node_modules/@emotion/unitless": {
+ "version": "0.7.5",
+ "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz",
+ "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==",
+ "peer": true
+ },
"node_modules/@eslint/eslintrc": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz",
@@ -3143,6 +3157,15 @@
}
}
},
+ "node_modules/@popperjs/core": {
+ "version": "2.11.7",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.7.tgz",
+ "integrity": "sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw==",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/popperjs"
+ }
+ },
"node_modules/@reduxjs/toolkit": {
"version": "1.9.5",
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.5.tgz",
@@ -3737,8 +3760,7 @@
"node_modules/@types/parse-json": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
- "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
- "dev": true
+ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA=="
},
"node_modules/@types/prettier": {
"version": "2.6.4",
@@ -4884,7 +4906,6 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz",
"integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==",
- "dev": true,
"dependencies": {
"@babel/runtime": "^7.12.5",
"cosmiconfig": "^7.0.0",
@@ -4943,6 +4964,27 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/babel-plugin-styled-components": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.1.tgz",
+ "integrity": "sha512-c8lJlszObVQPguHkI+akXv8+Jgb9Ccujx0EetL7oIvwU100LxO6XAGe45qry37wUL40a5U9f23SYrivro2XKhA==",
+ "peer": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.16.0",
+ "@babel/helper-module-imports": "^7.16.0",
+ "babel-plugin-syntax-jsx": "^6.18.0",
+ "lodash": "^4.17.21",
+ "picomatch": "^2.3.0"
+ },
+ "peerDependencies": {
+ "styled-components": ">= 2"
+ }
+ },
+ "node_modules/babel-plugin-syntax-jsx": {
+ "version": "6.18.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
+ "integrity": "sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw=="
+ },
"node_modules/babel-plugin-transform-react-remove-prop-types": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz",
@@ -5280,6 +5322,15 @@
"node": ">= 6"
}
},
+ "node_modules/camelize": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz",
+ "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==",
+ "peer": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/caniuse-api": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
@@ -5404,6 +5455,11 @@
"integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==",
"dev": true
},
+ "node_modules/classnames": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz",
+ "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
+ },
"node_modules/clean-css": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz",
@@ -5715,7 +5771,6 @@
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz",
"integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==",
- "dev": true,
"dependencies": {
"@types/parse-json": "^4.0.0",
"import-fresh": "^3.2.1",
@@ -5767,6 +5822,15 @@
"postcss": "^8.4"
}
},
+ "node_modules/css-color-keywords": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
+ "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==",
+ "peer": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/css-declaration-sorter": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.0.tgz",
@@ -5975,6 +6039,17 @@
"integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==",
"dev": true
},
+ "node_modules/css-to-react-native": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz",
+ "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==",
+ "peer": true,
+ "dependencies": {
+ "camelize": "^1.0.0",
+ "css-color-keywords": "^1.0.0",
+ "postcss-value-parser": "^4.0.2"
+ }
+ },
"node_modules/css-tree": {
"version": "1.0.0-alpha.37",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz",
@@ -6195,6 +6270,18 @@
"node": ">=10"
}
},
+ "node_modules/date-fns": {
+ "version": "2.29.3",
+ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz",
+ "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==",
+ "engines": {
+ "node": ">=0.11"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/date-fns"
+ }
+ },
"node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -6635,7 +6722,6 @@
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
- "dev": true,
"dependencies": {
"is-arrayish": "^0.2.1"
}
@@ -9007,8 +9093,7 @@
"node_modules/is-arrayish": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
- "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
- "dev": true
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="
},
"node_modules/is-bigint": {
"version": "1.0.4",
@@ -11627,8 +11712,7 @@
"node_modules/json-parse-even-better-errors": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
- "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
- "dev": true
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
},
"node_modules/json-schema": {
"version": "0.4.0",
@@ -11763,8 +11847,7 @@
"node_modules/lines-and-columns": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
- "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
- "dev": true
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
},
"node_modules/loader-runner": {
"version": "4.3.0",
@@ -11806,8 +11889,7 @@
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
- "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
- "dev": true
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"node_modules/lodash.debounce": {
"version": "4.0.8",
@@ -12119,6 +12201,14 @@
"mkdirp": "bin/cmd.js"
}
},
+ "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",
@@ -12542,7 +12632,6 @@
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
"integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
- "dev": true,
"dependencies": {
"@babel/code-frame": "^7.0.0",
"error-ex": "^1.3.1",
@@ -14051,8 +14140,7 @@
"node_modules/postcss-value-parser": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
- "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
- "dev": true
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
},
"node_modules/prelude-ls": {
"version": "1.2.1",
@@ -14337,6 +14425,23 @@
"node": ">=14"
}
},
+ "node_modules/react-datepicker": {
+ "version": "4.11.0",
+ "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-4.11.0.tgz",
+ "integrity": "sha512-50n93o7mQwBEhg05tbopjFKgs8qgi8VBCAOMC4VqrKut72eAjESc/wXS/k5hRtnP0oe2FCGw7MJuIwh37wuXOw==",
+ "dependencies": {
+ "@popperjs/core": "^2.9.2",
+ "classnames": "^2.2.6",
+ "date-fns": "^2.24.0",
+ "prop-types": "^15.7.2",
+ "react-onclickoutside": "^6.12.2",
+ "react-popper": "^2.3.0"
+ },
+ "peerDependencies": {
+ "react": "^16.9.0 || ^17 || ^18",
+ "react-dom": "^16.9.0 || ^17 || ^18"
+ }
+ },
"node_modules/react-dev-utils": {
"version": "12.0.1",
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz",
@@ -14481,6 +14586,11 @@
"integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==",
"dev": true
},
+ "node_modules/react-fast-compare": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.1.tgz",
+ "integrity": "sha512-xTYf9zFim2pEif/Fw16dBiXpe0hoy5PxcD8+OwBnTtNLfIm3g6WxhKNurY+6OmdH1u6Ta/W/Vl6vjbYP1MFnDg=="
+ },
"node_modules/react-icons": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.8.0.tgz",
@@ -14494,6 +14604,33 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
+ "node_modules/react-onclickoutside": {
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.13.0.tgz",
+ "integrity": "sha512-ty8So6tcUpIb+ZE+1HAhbLROvAIJYyJe/1vRrrcmW+jLsaM+/powDRqxzo6hSh9CuRZGSL1Q8mvcF5WRD93a0A==",
+ "funding": {
+ "type": "individual",
+ "url": "https://github.com/Pomax/react-onclickoutside/blob/master/FUNDING.md"
+ },
+ "peerDependencies": {
+ "react": "^15.5.x || ^16.x || ^17.x || ^18.x",
+ "react-dom": "^15.5.x || ^16.x || ^17.x || ^18.x"
+ }
+ },
+ "node_modules/react-popper": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz",
+ "integrity": "sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==",
+ "dependencies": {
+ "react-fast-compare": "^3.0.1",
+ "warning": "^4.0.2"
+ },
+ "peerDependencies": {
+ "@popperjs/core": "^2.0.0",
+ "react": "^16.8.0 || ^17 || ^18",
+ "react-dom": "^16.8.0 || ^17 || ^18"
+ }
+ },
"node_modules/react-redux": {
"version": "8.0.5",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.5.tgz",
@@ -15389,6 +15526,12 @@
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
"dev": true
},
+ "node_modules/shallowequal": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
+ "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==",
+ "peer": true
+ },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -15798,6 +15941,77 @@
"webpack": "^5.0.0"
}
},
+ "node_modules/styled-components": {
+ "version": "5.3.9",
+ "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.9.tgz",
+ "integrity": "sha512-Aj3kb13B75DQBo2oRwRa/APdB5rSmwUfN5exyarpX+x/tlM/rwZA2vVk2vQgVSP6WKaZJHWwiFrzgHt+CLtB4A==",
+ "peer": true,
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.0.0",
+ "@babel/traverse": "^7.4.5",
+ "@emotion/is-prop-valid": "^1.1.0",
+ "@emotion/stylis": "^0.8.4",
+ "@emotion/unitless": "^0.7.4",
+ "babel-plugin-styled-components": ">= 1.12.0",
+ "css-to-react-native": "^3.0.0",
+ "hoist-non-react-statics": "^3.0.0",
+ "shallowequal": "^1.1.0",
+ "supports-color": "^5.5.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/styled-components"
+ },
+ "peerDependencies": {
+ "react": ">= 16.8.0",
+ "react-dom": ">= 16.8.0",
+ "react-is": ">= 16.8.0"
+ }
+ },
+ "node_modules/styled-components.macro": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/styled-components.macro/-/styled-components.macro-1.0.0.tgz",
+ "integrity": "sha512-MrGQOP3VhXk3iwJIEM/Qx55u5TZ9x3H5fOyVMH+oLqf3b8nbozsMY1eYghPChwOALh99qrDGpaEXzhhOU583jg==",
+ "dependencies": {
+ "babel-plugin-styled-components": "^1.8.0"
+ },
+ "peerDependencies": {
+ "babel-plugin-macros": ">=2",
+ "styled-components": ">=2"
+ }
+ },
+ "node_modules/styled-components.macro/node_modules/babel-plugin-styled-components": {
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.13.3.tgz",
+ "integrity": "sha512-meGStRGv+VuKA/q0/jXxrPNWEm4LPfYIqxooDTdmh8kFsP/Ph7jJG5rUPwUPX3QHUvggwdbgdGpo88P/rRYsVw==",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.15.4",
+ "@babel/helper-module-imports": "^7.15.4",
+ "babel-plugin-syntax-jsx": "^6.18.0",
+ "lodash": "^4.17.11"
+ },
+ "peerDependencies": {
+ "styled-components": ">= 2"
+ }
+ },
+ "node_modules/styled-components/node_modules/@emotion/is-prop-valid": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz",
+ "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==",
+ "peer": true,
+ "dependencies": {
+ "@emotion/memoize": "^0.8.0"
+ }
+ },
+ "node_modules/styled-components/node_modules/@emotion/memoize": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz",
+ "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==",
+ "peer": true
+ },
"node_modules/stylehacks": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.0.tgz",
@@ -16633,6 +16847,14 @@
"makeerror": "1.0.12"
}
},
+ "node_modules/warning": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
+ "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
+ "dependencies": {
+ "loose-envify": "^1.0.0"
+ }
+ },
"node_modules/watchpack": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
@@ -17525,7 +17747,6 @@
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
"integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
- "dev": true,
"engines": {
"node": ">= 6"
}
@@ -17650,7 +17871,6 @@
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz",
"integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==",
- "dev": true,
"requires": {
"@babel/types": "^7.18.6"
}
@@ -18997,6 +19217,18 @@
"integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==",
"optional": true
},
+ "@emotion/stylis": {
+ "version": "0.8.5",
+ "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz",
+ "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==",
+ "peer": true
+ },
+ "@emotion/unitless": {
+ "version": "0.7.5",
+ "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz",
+ "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==",
+ "peer": true
+ },
"@eslint/eslintrc": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz",
@@ -19714,6 +19946,11 @@
"source-map": "^0.7.3"
}
},
+ "@popperjs/core": {
+ "version": "2.11.7",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.7.tgz",
+ "integrity": "sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw=="
+ },
"@reduxjs/toolkit": {
"version": "1.9.5",
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.5.tgz",
@@ -20166,8 +20403,7 @@
"@types/parse-json": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
- "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
- "dev": true
+ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA=="
},
"@types/prettier": {
"version": "2.6.4",
@@ -21037,7 +21273,6 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz",
"integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==",
- "dev": true,
"requires": {
"@babel/runtime": "^7.12.5",
"cosmiconfig": "^7.0.0",
@@ -21081,6 +21316,24 @@
"@babel/helper-define-polyfill-provider": "^0.3.2"
}
},
+ "babel-plugin-styled-components": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.1.tgz",
+ "integrity": "sha512-c8lJlszObVQPguHkI+akXv8+Jgb9Ccujx0EetL7oIvwU100LxO6XAGe45qry37wUL40a5U9f23SYrivro2XKhA==",
+ "peer": true,
+ "requires": {
+ "@babel/helper-annotate-as-pure": "^7.16.0",
+ "@babel/helper-module-imports": "^7.16.0",
+ "babel-plugin-syntax-jsx": "^6.18.0",
+ "lodash": "^4.17.21",
+ "picomatch": "^2.3.0"
+ }
+ },
+ "babel-plugin-syntax-jsx": {
+ "version": "6.18.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
+ "integrity": "sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw=="
+ },
"babel-plugin-transform-react-remove-prop-types": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz",
@@ -21349,6 +21602,12 @@
"integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
"dev": true
},
+ "camelize": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz",
+ "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==",
+ "peer": true
+ },
"caniuse-api": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
@@ -21439,6 +21698,11 @@
"integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==",
"dev": true
},
+ "classnames": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz",
+ "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
+ },
"clean-css": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz",
@@ -21687,7 +21951,6 @@
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz",
"integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==",
- "dev": true,
"requires": {
"@types/parse-json": "^4.0.0",
"import-fresh": "^3.2.1",
@@ -21721,6 +21984,12 @@
"postcss-selector-parser": "^6.0.9"
}
},
+ "css-color-keywords": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
+ "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==",
+ "peer": true
+ },
"css-declaration-sorter": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.0.tgz",
@@ -21851,6 +22120,17 @@
"integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==",
"dev": true
},
+ "css-to-react-native": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz",
+ "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==",
+ "peer": true,
+ "requires": {
+ "camelize": "^1.0.0",
+ "css-color-keywords": "^1.0.0",
+ "postcss-value-parser": "^4.0.2"
+ }
+ },
"css-tree": {
"version": "1.0.0-alpha.37",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz",
@@ -22019,6 +22299,11 @@
"whatwg-url": "^8.0.0"
}
},
+ "date-fns": {
+ "version": "2.29.3",
+ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz",
+ "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA=="
+ },
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -22351,7 +22636,6 @@
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
- "dev": true,
"requires": {
"is-arrayish": "^0.2.1"
}
@@ -24078,8 +24362,7 @@
"is-arrayish": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
- "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
- "dev": true
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="
},
"is-bigint": {
"version": "1.0.4",
@@ -26010,8 +26293,7 @@
"json-parse-even-better-errors": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
- "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
- "dev": true
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
},
"json-schema": {
"version": "0.4.0",
@@ -26114,8 +26396,7 @@
"lines-and-columns": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
- "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
- "dev": true
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
},
"loader-runner": {
"version": "4.3.0",
@@ -26145,8 +26426,7 @@
"lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
- "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
- "dev": true
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"lodash.debounce": {
"version": "4.0.8",
@@ -26388,6 +26668,11 @@
"minimist": "^1.2.6"
}
},
+ "moment": {
+ "version": "2.29.4",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
+ "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
+ },
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -26694,7 +26979,6 @@
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
"integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
- "dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"error-ex": "^1.3.1",
@@ -27620,8 +27904,7 @@
"postcss-value-parser": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
- "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
- "dev": true
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
},
"prelude-ls": {
"version": "1.2.1",
@@ -27834,6 +28117,19 @@
"whatwg-fetch": "^3.6.2"
}
},
+ "react-datepicker": {
+ "version": "4.11.0",
+ "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-4.11.0.tgz",
+ "integrity": "sha512-50n93o7mQwBEhg05tbopjFKgs8qgi8VBCAOMC4VqrKut72eAjESc/wXS/k5hRtnP0oe2FCGw7MJuIwh37wuXOw==",
+ "requires": {
+ "@popperjs/core": "^2.9.2",
+ "classnames": "^2.2.6",
+ "date-fns": "^2.24.0",
+ "prop-types": "^15.7.2",
+ "react-onclickoutside": "^6.12.2",
+ "react-popper": "^2.3.0"
+ }
+ },
"react-dev-utils": {
"version": "12.0.1",
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz",
@@ -27944,6 +28240,11 @@
"integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==",
"dev": true
},
+ "react-fast-compare": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.1.tgz",
+ "integrity": "sha512-xTYf9zFim2pEif/Fw16dBiXpe0hoy5PxcD8+OwBnTtNLfIm3g6WxhKNurY+6OmdH1u6Ta/W/Vl6vjbYP1MFnDg=="
+ },
"react-icons": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.8.0.tgz",
@@ -27955,6 +28256,21 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
+ "react-onclickoutside": {
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.13.0.tgz",
+ "integrity": "sha512-ty8So6tcUpIb+ZE+1HAhbLROvAIJYyJe/1vRrrcmW+jLsaM+/powDRqxzo6hSh9CuRZGSL1Q8mvcF5WRD93a0A==",
+ "requires": {}
+ },
+ "react-popper": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz",
+ "integrity": "sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==",
+ "requires": {
+ "react-fast-compare": "^3.0.1",
+ "warning": "^4.0.2"
+ }
+ },
"react-redux": {
"version": "8.0.5",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.5.tgz",
@@ -28622,6 +28938,12 @@
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
"dev": true
},
+ "shallowequal": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
+ "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==",
+ "peer": true
+ },
"shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -28936,6 +29258,62 @@
"dev": true,
"requires": {}
},
+ "styled-components": {
+ "version": "5.3.9",
+ "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.9.tgz",
+ "integrity": "sha512-Aj3kb13B75DQBo2oRwRa/APdB5rSmwUfN5exyarpX+x/tlM/rwZA2vVk2vQgVSP6WKaZJHWwiFrzgHt+CLtB4A==",
+ "peer": true,
+ "requires": {
+ "@babel/helper-module-imports": "^7.0.0",
+ "@babel/traverse": "^7.4.5",
+ "@emotion/is-prop-valid": "^1.1.0",
+ "@emotion/stylis": "^0.8.4",
+ "@emotion/unitless": "^0.7.4",
+ "babel-plugin-styled-components": ">= 1.12.0",
+ "css-to-react-native": "^3.0.0",
+ "hoist-non-react-statics": "^3.0.0",
+ "shallowequal": "^1.1.0",
+ "supports-color": "^5.5.0"
+ },
+ "dependencies": {
+ "@emotion/is-prop-valid": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz",
+ "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==",
+ "peer": true,
+ "requires": {
+ "@emotion/memoize": "^0.8.0"
+ }
+ },
+ "@emotion/memoize": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz",
+ "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==",
+ "peer": true
+ }
+ }
+ },
+ "styled-components.macro": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/styled-components.macro/-/styled-components.macro-1.0.0.tgz",
+ "integrity": "sha512-MrGQOP3VhXk3iwJIEM/Qx55u5TZ9x3H5fOyVMH+oLqf3b8nbozsMY1eYghPChwOALh99qrDGpaEXzhhOU583jg==",
+ "requires": {
+ "babel-plugin-styled-components": "^1.8.0"
+ },
+ "dependencies": {
+ "babel-plugin-styled-components": {
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.13.3.tgz",
+ "integrity": "sha512-meGStRGv+VuKA/q0/jXxrPNWEm4LPfYIqxooDTdmh8kFsP/Ph7jJG5rUPwUPX3QHUvggwdbgdGpo88P/rRYsVw==",
+ "requires": {
+ "@babel/helper-annotate-as-pure": "^7.15.4",
+ "@babel/helper-module-imports": "^7.15.4",
+ "babel-plugin-syntax-jsx": "^6.18.0",
+ "lodash": "^4.17.11"
+ }
+ }
+ }
+ },
"stylehacks": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.0.tgz",
@@ -29569,6 +29947,14 @@
"makeerror": "1.0.12"
}
},
+ "warning": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
+ "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
+ "requires": {
+ "loose-envify": "^1.0.0"
+ }
+ },
"watchpack": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
@@ -30283,8 +30669,7 @@
"yaml": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
- "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
- "dev": true
+ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="
},
"yargs": {
"version": "16.2.0",
diff --git a/code/package.json b/code/package.json
index 78fb8e423..143931ed9 100644
--- a/code/package.json
+++ b/code/package.json
@@ -12,10 +12,13 @@
"eslint-plugin-react": "^7.30.1",
"eslint-plugin-react-hooks": "^4.6.0",
"framer-motion": "^10.12.3",
+ "moment": "^2.29.4",
"react": "^18.2.0",
+ "react-datepicker": "^4.11.0",
"react-dom": "^18.2.0",
"react-icons": "^4.8.0",
- "react-redux": "^8.0.5"
+ "react-redux": "^8.0.5",
+ "styled-components.macro": "^1.0.0"
},
"scripts": {
"start": "react-scripts start",
diff --git a/code/public/favicon.ico b/code/public/favicon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..d2a41f06e475ddcfaf3a4cffcf616929503e8c9d
GIT binary patch
literal 1383
zcmV-t1(^DYP)yiPR53<8w2C$qnb2FCnI`-J#%uq8d75v-mSNnd
zwKrRC_M1Fe>s#x4$9G|dxK<2>0tE^bC{Un4fdVa8WRQ}wlZ=#|IiUO&U{p9Cws`rjgHUh?buU|k=dD4SQnzY<#8Ph2uc7G?7XUxQ%#
zhx8KOaDqO!e!t~9N973+ta_roge!ZZ
z?}kEEU6e+<$!dMw%temzj+I}pRnh%dra%R!=P*@uHwbzi>!wfs#$_(!rfzbwFQdM0
z<@c(wC!m7o99z0Tkoo50^lSBTay3V(lu@tik_(3~>^G{t>cJyW!E=tf;~;4BB;nd)
z
zc7jZH0vs}9mcy~OCqXD&Yf2JsOma&`yM818YRGktokz&;Is&^65x48zafEuU_b~Hr
z{C>$Omt*ZYNIG!{6iIpX`^D>Aj@8~yN%KL{%^l?T9RwTZ_jQmGk4wK_ypbzVActyi
zr=+8ekppeK=x75Yy!!p-KpXi3UohFe&T)1(2r`#Lp50AO>N8EeTHJem_~L%6+77cklYf8;W;q<|ToVX-
z{au36b4_Gr?b}_jVL|4yCVO`N!deyGe<8!{#SA#%!pzcp
zK=J1|)>t(NGM597Z6c?w$yhL#Jv)D4t%~md@o!MUEQe#=tO7x=$Ezs)y^5^9e)D7I
z#%q>eh^+ixb?q-u!E=t=Q4k7$0Jo!L_4V;6b9Z9AYt~;}d)3{?pn~TdcQ=9{^E*+(
zcRwPht;tw0m%ZYCtJ)5;Jkt+B1+yHE^`H_2nLpe}?0$ro_bV3;EXZ8eWUsj2sRkdU`$iXXRkYdgiCslM;_B
pzh4;S3KS?%pg@5F1qu{e(Er%=$?!Y0QrrLl002ovPDHLkV1g0Nw+8?K
literal 0
HcmV?d00001
diff --git a/code/public/index.html b/code/public/index.html
index e6730aa66..9f84e31ff 100644
--- a/code/public/index.html
+++ b/code/public/index.html
@@ -5,6 +5,8 @@
- Technigo React App
+ W11 - To-Do-App by Ylva
diff --git a/code/src/App.js b/code/src/App.js
index f032cb804..d2511b8c3 100644
--- a/code/src/App.js
+++ b/code/src/App.js
@@ -1,18 +1,24 @@
import React from 'react';
import { Provider } from 'react-redux';
import { configureStore, combineReducers } from '@reduxjs/toolkit';
-import AddToDo from 'components/AddToDo';
-import ToDoList from 'components/ToDoList';
-import todos from 'redux/reducers/todos'
+import { ToDoList } from 'components/ToDoList';
+import { todos } from 'redux/reducers/todos'
+import { GlobalStyle } from 'components/GlobalStyle';
+
+const reducer = combineReducers({
+ todos: todos.reducer
+});
+
+const store = configureStore({ reducer });
export const App = () => {
- const reducer = combineReducers({
- todos: todos.reducer
- });
- const store = configureStore({ reducer });
+ // const reducer = combineReducers({
+ // todos: todos.reducer
+ // });
+ // const store = configureStore({ reducer });
return (
-
+
)
diff --git a/code/src/components/AddToDo.js b/code/src/components/AddToDo.js
index e98299848..2f11c1dc5 100644
--- a/code/src/components/AddToDo.js
+++ b/code/src/components/AddToDo.js
@@ -1,32 +1,68 @@
+/* eslint-disable jsx-a11y/label-has-associated-control */
+/* eslint-disable no-undef */
import React, { useState } from 'react';
import { useDispatch } from 'react-redux';
-import todos from 'redux/reducers/todos';
+import { todos } from 'redux/reducers/todos';
+import styled from 'styled-components';
-const AddToDo = () => {
+const NewToDo = styled.form`
+ line-height: 0.5rem;
+ padding-bottom: 0.8rem;
+`;
+
+const Input = styled.input`
+ background: #a83256;
+ border: none;
+ padding: 8px;
+ font-size: 18px;
+ font-family: 'Baloo 2', cursive;
+ border-bottom: 2px dashed;
+ :focus {
+ outline: none;
+ }
+`;
+
+const AddButton = styled.button`
+ font-family: 'Baloo 2', cursive;
+ font-size: 18px;
+ border: none;
+ background: transparent;
+ cursor: pointer;
+`;
+
+export const AddToDo = () => {
const [inputValue, setInputValue] = useState('');
const dispatch = useDispatch();
const onFormSubmit = (event) => {
event.preventDefault();
+
const newToDo = {
id: Date.now().toString(),
- name: inputValue.charAt(0).toUpperCase() + inputValue.slice(1),
- isNew: false
+ createdAt: new Date(),
+ text: inputValue.charAt(0).toUpperCase() + inputValue.slice(1),
+ isDone: false
};
- dispatch(todos.actions.addToDo(newToDo));
+ dispatch(todos.actions.addItem(newToDo));
setInputValue('');
// https://www.random.org
- }
+ };
+
return (
-
+
+ Add new To Do now
+
+
- )
-}
-
-export default AddToDo;
\ No newline at end of file
+ );
+};
\ No newline at end of file
diff --git a/code/src/components/GlobalStyle.js b/code/src/components/GlobalStyle.js
new file mode 100644
index 000000000..4ee51c755
--- /dev/null
+++ b/code/src/components/GlobalStyle.js
@@ -0,0 +1,50 @@
+import { createGlobalStyle } from 'styled-components/macro';
+import styled from 'styled-components';
+
+export const GlobalStyle = createGlobalStyle`
+body {
+ background-color: linear-gradient(to bottom, #3366ff 0%, #ff00ff 100%);
+ /* opacity: 50%; */
+ font-family: 'DynaPuff', cursive;
+ font-size: 20px;
+ display: flex;
+ justify-content: center;
+ }
+`;
+
+export const Wrapper = styled.div`
+ background: #3483eb;
+ width: 80vw;
+ text-align: center;
+ padding: 10px;
+ margin: 20px auto;
+ margin-bottom: 40px;
+ border-radius: 25px;
+ box-shadow: 4px 4px 4px rgba(0, 0, 0, 0.2);
+
+ @media (min-width: 668px) {
+ width: 55vw;
+ }
+`;
+
+export const SingleTodo = styled.div`
+ margin: 10px;
+ border-bottom: 1px solid black;
+ padding-bottom: 15px;
+ line-height: 1em;
+`;
+
+export const Button = styled.button`
+ font-size: 18px;
+ padding: 4px 13px;
+ margin: 8px;
+ font-family: 'Baloo 2', cursive;
+ background: #edca7f;
+ color: #fff;
+ border: solid 2px red;
+ border-radius: 30px;
+ cursor: pointer;
+ /* :hover {
+ opacity: 70%;
+ } */
+`;
diff --git a/code/src/components/ToDoItem.js b/code/src/components/ToDoItem.js
index e69de29bb..5c7397119 100644
--- a/code/src/components/ToDoItem.js
+++ b/code/src/components/ToDoItem.js
@@ -0,0 +1,42 @@
+import React from 'react';
+import moment from 'moment';
+import styled from 'styled-components';
+import { SingleTodo } from './GlobalStyle';
+
+const ToDoText = styled.div`
+cursor: pointer;
+text-decoration: ${(props) => (props.isDone ? 'line-through' : 'none')};
+font-size: 24px;
+`;
+
+const DateText = styled.div`
+ font-style: italic;
+ font-size: 14px;
+ margin: 7px;
+ opacity: 50%;
+`;
+
+const DeleteButton = styled.button`
+ background: #a83256;
+ border: none;
+ font-family: 'DynaPuff', cursive;
+ font-size: 18px;
+ cursor: pointer;
+ border-radius: 50%;
+ padding: 0px 9px;
+`;
+
+export const ToDoItem = ({ todo, index, onDelete, onDone }) => {
+ return (
+
+ onDone(todo.id)} key={todo.id} isDone={todo.isDone}>
+ {todo.text}
+ Added {moment(todo.createdAt).format('HH:mm on MMM D, YYYY')}
+
+ onDelete(index)} type="button" title="Delete task">
+ {' '}
+ X
+
+
+ );
+};
\ No newline at end of file
diff --git a/code/src/components/ToDoList.js b/code/src/components/ToDoList.js
index b588cc593..aca5365b6 100644
--- a/code/src/components/ToDoList.js
+++ b/code/src/components/ToDoList.js
@@ -1,17 +1,76 @@
+/* eslint-disable no-undef */
+/* eslint-disable import/named */
+/* eslint-disable no-unused-vars */
import React from 'react';
-import { useSelector } from 'react-redux';
+import { useSelector, useDispatch } from 'react-redux';
+import { todos } from 'redux/reducers/todos';
+import { ToDoItem } from './ToDoItem';
+import { AddToDo } from './AddToDo';
+
+export const ToDoList = () => {
+ const dispatch = useDispatch();
+ const allTodos = useSelector((store) => store.todos.items);
+
+ const onDone = (id) => {
+ dispatch(todos.actions.deleteItem(todoIndex));
+ };
+
+ const onDelete = (todoIndex) => {
+ dispatch(todos.actions.deleteItem(todoIndex));
+ };
+
+ const onCompleteAll = () => {
+ allTodos.forEach((todo) => {
+ if (!todo.isDone) {
+ dispatch(todos.actions.toggleItem(todo.id));
+ }
+ });
+ };
+
+ const onClearAll = () => {
+ if (window.confirm('Do you really want to delete all to-dos?')) {
+ dispatch(todos.actions.clearAll());
+ }
+ };
+
+ const todosTodo = allTodos.filter((todo) => !todo.isDone);
+ const doneTodos = allTodos.filter((todo) => todo.isDone);
-const ToDoList = () => {
- const todoList = useSelector((store) => store.todos.items)
return (
- )
-}
-
-export default ToDoList;
\ No newline at end of file
+ );
+};
diff --git a/code/src/index.css b/code/src/index.css
index 4a1df4db7..6f7c99e66 100644
--- a/code/src/index.css
+++ b/code/src/index.css
@@ -1,3 +1,5 @@
+@import url('https://fonts.googleapis.com/css2?family=DynaPuff:wght@400;600&display=swap');
+
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
diff --git a/code/src/redux/reducers/todos.js b/code/src/redux/reducers/todos.js
index bcc64a0d7..86f8cacc7 100644
--- a/code/src/redux/reducers/todos.js
+++ b/code/src/redux/reducers/todos.js
@@ -1,36 +1,63 @@
+/* eslint-disable max-len */
import { createSlice } from '@reduxjs/toolkit';
-const initialState = {
- items: [
- {
- id: '189438fdjhrjejioe9845',
- name: 'ToDo1',
- isNew: false
- },
- {
- id: '189438fdjhrjejioe9846',
- name: 'ToDo2',
- isNew: false
- },
- {
- id: '189438fdjhrjejioe9847',
- name: 'ToDo3',
- isNew: false
- }
- ]
-}
+// The slice for todo has the initial state with an array for each of the single todo-items
+// Every todo item has an id, text and isDone property.
-const todos = createSlice({
+export const todos = createSlice({
name: 'todos',
- initialState,
+ initialState: {
+ items: [
+ { id: '1', text: 'Click this to-do to mark it as done ✅✔', isDone: false },
+ { id: '2', text: 'Your first to-do is: Sing like no one is hearing ‼', isDone: false }
+ ]
+ },
+ // The reducers field contains functions to modify the state of the slice (todo made with createSlice)
reducers: {
- addToDo: (store, action) => {
- // Mutable
- // store.items.push(action.payload);
- // Immutable
- store.items = [...store.items, action.payload];
+ toggleItem: (store, action) => {
+ store.items.forEach((item) => {
+ if (item.id === action.payload) {
+ item.isDone = !item.isDone;
+ }
+ });
+ },
+ deleteItem: (store, action) => {
+ store.items.splice(action.payload, 1);
+ },
+ addItem: (store, action) => {
+ store.items.push(action.payload);
+ },
+ completeAll: (store) => {
+ store.items.forEach((item) => {
+ item.isDone = true;
+ });
+ },
+ clearAll: (store) => {
+ store.items = [];
}
}
});
+// Mutable
+// store.items.push(action.payload);
+// Immutable
+// store.items = [...store.items, action.payload];
-export default todos;
\ No newline at end of file
+// const initialState = {
+// items: [
+// {
+// id: '189438fdjhrjejioe9845',
+// name: 'ToDo1',
+// isNew: false
+// },
+// {
+// id: '189438fdjhrjejioe9846',
+// name: 'ToDo2',
+// isNew: false
+// },
+// {
+// id: '189438fdjhrjejioe9847',
+// name: 'ToDo3',
+// isNew: false
+// }
+// ]
+// }
\ No newline at end of file
From 34edb37c3dee73aa0cf185499fdf8024f040ae6d Mon Sep 17 00:00:00 2001
From: Ylva Karlsson <121539816+YlvaKarlsson@users.noreply.github.com>
Date: Thu, 20 Apr 2023 14:37:10 +0200
Subject: [PATCH 04/28] Changes and some styling
---
code/package-lock.json | 16 +++++++++++
code/package.json | 2 ++
code/src/App.js | 20 ++++---------
code/src/components/AddToDo.js | 2 +-
code/src/components/GlobalStyle.js | 9 ++++--
code/src/components/ToDoItem.js | 2 +-
code/src/components/ToDoList.js | 45 ++++++++++++++++--------------
code/src/redux/reducers/todos.js | 4 +--
code/src/redux/store.js | 23 +++++++++++++++
9 files changed, 81 insertions(+), 42 deletions(-)
diff --git a/code/package-lock.json b/code/package-lock.json
index 88ee3d540..2cfb60a18 100644
--- a/code/package-lock.json
+++ b/code/package-lock.json
@@ -23,6 +23,8 @@
"react-dom": "^18.2.0",
"react-icons": "^4.8.0",
"react-redux": "^8.0.5",
+ "redux-persist": "^6.0.0",
+ "redux-thunk": "^2.4.2",
"styled-components.macro": "^1.0.0"
},
"devDependencies": {
@@ -14838,6 +14840,14 @@
"@babel/runtime": "^7.9.2"
}
},
+ "node_modules/redux-persist": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-6.0.0.tgz",
+ "integrity": "sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ==",
+ "peerDependencies": {
+ "redux": ">4.0.0"
+ }
+ },
"node_modules/redux-thunk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz",
@@ -28421,6 +28431,12 @@
"@babel/runtime": "^7.9.2"
}
},
+ "redux-persist": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-6.0.0.tgz",
+ "integrity": "sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ==",
+ "requires": {}
+ },
"redux-thunk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz",
diff --git a/code/package.json b/code/package.json
index 143931ed9..2fa4ff73a 100644
--- a/code/package.json
+++ b/code/package.json
@@ -18,6 +18,8 @@
"react-dom": "^18.2.0",
"react-icons": "^4.8.0",
"react-redux": "^8.0.5",
+ "redux-persist": "^6.0.0",
+ "redux-thunk": "^2.4.2",
"styled-components.macro": "^1.0.0"
},
"scripts": {
diff --git a/code/src/App.js b/code/src/App.js
index d2511b8c3..a96eec704 100644
--- a/code/src/App.js
+++ b/code/src/App.js
@@ -1,25 +1,17 @@
import React from 'react';
import { Provider } from 'react-redux';
-import { configureStore, combineReducers } from '@reduxjs/toolkit';
+import { persistor, store } from 'redux/store'
+import { PersistGate } from 'redux-persist/integration/react';
import { ToDoList } from 'components/ToDoList';
-import { todos } from 'redux/reducers/todos'
import { GlobalStyle } from 'components/GlobalStyle';
-const reducer = combineReducers({
- todos: todos.reducer
-});
-
-const store = configureStore({ reducer });
-
export const App = () => {
- // const reducer = combineReducers({
- // todos: todos.reducer
- // });
- // const store = configureStore({ reducer });
return (
-
-
+
+
+
+
)
}
diff --git a/code/src/components/AddToDo.js b/code/src/components/AddToDo.js
index 2f11c1dc5..532c70024 100644
--- a/code/src/components/AddToDo.js
+++ b/code/src/components/AddToDo.js
@@ -11,7 +11,7 @@ const NewToDo = styled.form`
`;
const Input = styled.input`
- background: #a83256;
+ background: pink;
border: none;
padding: 8px;
font-size: 18px;
diff --git a/code/src/components/GlobalStyle.js b/code/src/components/GlobalStyle.js
index 4ee51c755..7a8f4840f 100644
--- a/code/src/components/GlobalStyle.js
+++ b/code/src/components/GlobalStyle.js
@@ -3,8 +3,9 @@ import styled from 'styled-components';
export const GlobalStyle = createGlobalStyle`
body {
- background-color: linear-gradient(to bottom, #3366ff 0%, #ff00ff 100%);
- /* opacity: 50%; */
+ background: rgb(51,102,255);
+ background: linear-gradient(180deg, rgba(51,102,255,1) 0%, rgba(255,0,255,1) 100%);
+// background-color: linear-gradient(to bottom, #3366ff 0%, #ff00ff 100%);
font-family: 'DynaPuff', cursive;
font-size: 20px;
display: flex;
@@ -13,7 +14,7 @@ body {
`;
export const Wrapper = styled.div`
- background: #3483eb;
+ background: white;
width: 80vw;
text-align: center;
padding: 10px;
@@ -28,8 +29,10 @@ export const Wrapper = styled.div`
`;
export const SingleTodo = styled.div`
+ background: lightpink;
margin: 10px;
border-bottom: 1px solid black;
+ padding-top: 10px;
padding-bottom: 15px;
line-height: 1em;
`;
diff --git a/code/src/components/ToDoItem.js b/code/src/components/ToDoItem.js
index 5c7397119..93a49ca48 100644
--- a/code/src/components/ToDoItem.js
+++ b/code/src/components/ToDoItem.js
@@ -17,7 +17,7 @@ const DateText = styled.div`
`;
const DeleteButton = styled.button`
- background: #a83256;
+ background: pink;
border: none;
font-family: 'DynaPuff', cursive;
font-size: 18px;
diff --git a/code/src/components/ToDoList.js b/code/src/components/ToDoList.js
index aca5365b6..59bc4c657 100644
--- a/code/src/components/ToDoList.js
+++ b/code/src/components/ToDoList.js
@@ -6,13 +6,14 @@ import { useSelector, useDispatch } from 'react-redux';
import { todos } from 'redux/reducers/todos';
import { ToDoItem } from './ToDoItem';
import { AddToDo } from './AddToDo';
+import { Wrapper } from './GlobalStyle';
export const ToDoList = () => {
const dispatch = useDispatch();
const allTodos = useSelector((store) => store.todos.items);
-
- const onDone = (id) => {
- dispatch(todos.actions.deleteItem(todoIndex));
+ // onDone calls the redux-reducer called toggleItem which toggles the items status
+ const onDone = (todoIndex) => {
+ dispatch(todos.actions.toggleItem(todoIndex));
};
const onDelete = (todoIndex) => {
@@ -37,40 +38,42 @@ export const ToDoList = () => {
const doneTodos = allTodos.filter((todo) => todo.isDone);
return (
-
- {/*
+
+
+ {/*
{allTodos.map((singleToDo) => {
return - {singleToDo.name}
})}
*/}
- To-do ({todosTodo.length})
+ To-do ({todosTodo.length})
- {todosTodo.lenghth === 0 && All done - great job! ✨
}
+ {todosTodo.length === 0 && All done - great job! ✨
}
- {todosTodo.map((todo, index) => (
-
- ))}
+ {todosTodo.map((todo, index) => (
+
+ ))}
-
+
- Done ({doneTodos.lenght})
+ Done ({doneTodos.length})
-
-
+
Clear all to-dos
-
+
- {doneTodos.map((todo, index) => (
-
- ))}
- {/*
+ {doneTodos.map((todo, index) => (
+
+ ))}
+ {/*
{todoList.map((singleToDo) => {
return - {singleToDo.name}
})}
*/}
-
+
+
);
};
diff --git a/code/src/redux/reducers/todos.js b/code/src/redux/reducers/todos.js
index 86f8cacc7..9808cde29 100644
--- a/code/src/redux/reducers/todos.js
+++ b/code/src/redux/reducers/todos.js
@@ -8,8 +8,8 @@ export const todos = createSlice({
name: 'todos',
initialState: {
items: [
- { id: '1', text: 'Click this to-do to mark it as done ✅✔', isDone: false },
- { id: '2', text: 'Your first to-do is: Sing like no one is hearing ‼', isDone: false }
+ { id: '1', text: 'Click this to-do to mark it as done ✅', isDone: false },
+ { id: '2', text: 'Your first to-do is: Sing like no one is hearing!', isDone: false }
]
},
// The reducers field contains functions to modify the state of the slice (todo made with createSlice)
diff --git a/code/src/redux/store.js b/code/src/redux/store.js
index e69de29bb..fe54791bc 100644
--- a/code/src/redux/store.js
+++ b/code/src/redux/store.js
@@ -0,0 +1,23 @@
+import { configureStore, combineReducers } from '@reduxjs/toolkit'
+import { todos } from 'redux/reducers/todos';
+import storage from 'redux-persist/lib/storage';
+import { persistReducer, persistStore } from 'redux-persist';
+import thunk from 'redux-thunk';
+
+const persistConfig = {
+ key: 'todo-list',
+ storage
+}
+
+const reducer = combineReducers({
+ todos: todos.reducer
+});
+
+const persistedReducer = persistReducer(persistConfig, reducer)
+
+export const store = configureStore({
+ reducer: persistedReducer,
+ middleware: [thunk]
+})
+
+export const persistor = persistStore(store)
\ No newline at end of file
From 120290c06112635b4b23a700e5126a6cbc0f7b78 Mon Sep 17 00:00:00 2001
From: Ylva Karlsson <121539816+YlvaKarlsson@users.noreply.github.com>
Date: Thu, 20 Apr 2023 14:42:51 +0200
Subject: [PATCH 05/28] Changes in styling, updating font etc
---
code/src/components/AddToDo.js | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/code/src/components/AddToDo.js b/code/src/components/AddToDo.js
index 532c70024..3c80e8ad8 100644
--- a/code/src/components/AddToDo.js
+++ b/code/src/components/AddToDo.js
@@ -6,7 +6,7 @@ import { todos } from 'redux/reducers/todos';
import styled from 'styled-components';
const NewToDo = styled.form`
- line-height: 0.5rem;
+ line-height: 0.8rem;
padding-bottom: 0.8rem;
`;
@@ -15,7 +15,7 @@ const Input = styled.input`
border: none;
padding: 8px;
font-size: 18px;
- font-family: 'Baloo 2', cursive;
+ font-family: 'DynaPuff', cursive;
border-bottom: 2px dashed;
:focus {
outline: none;
@@ -23,10 +23,10 @@ const Input = styled.input`
`;
const AddButton = styled.button`
- font-family: 'Baloo 2', cursive;
- font-size: 18px;
+ background: pink;
border: none;
- background: transparent;
+ font-family: 'DynaPuff', cursive;
+ font-size: 18px;
cursor: pointer;
`;
@@ -52,15 +52,18 @@ export const AddToDo = () => {
-
- Add new To Do now
+
+ Add
From 85f805cd52adc8c6ced6e268c0792a51384a31e6 Mon Sep 17 00:00:00 2001
From: Ylva Karlsson <121539816+YlvaKarlsson@users.noreply.github.com>
Date: Thu, 20 Apr 2023 16:20:02 +0200
Subject: [PATCH 06/28] Trying some more
---
code/src/components/AddToDo.js | 9 ++++
code/src/components/Button.js | 11 ++++
code/src/components/GlobalStyle.js | 6 ++-
code/src/components/TagsInput.js | 83 ++++++++++++++++++++++++++++++
code/src/index.css | 5 ++
code/src/redux/reducers/todos.js | 1 +
6 files changed, 113 insertions(+), 2 deletions(-)
create mode 100644 code/src/components/Button.js
create mode 100644 code/src/components/TagsInput.js
diff --git a/code/src/components/AddToDo.js b/code/src/components/AddToDo.js
index 3c80e8ad8..b656d233a 100644
--- a/code/src/components/AddToDo.js
+++ b/code/src/components/AddToDo.js
@@ -4,6 +4,8 @@ import React, { useState } from 'react';
import { useDispatch } from 'react-redux';
import { todos } from 'redux/reducers/todos';
import styled from 'styled-components';
+import { DefaultButton } from 'components/Button';
+import { TagsInput } from 'components/TagsInput';
const NewToDo = styled.form`
line-height: 0.8rem;
@@ -59,12 +61,19 @@ export const AddToDo = () => {
onChange={(event) => setInputValue(event.target.value)} />
{/* id={`new-todo-input${newToDo.id}`} /> */}
+
Add
+
+ Add
+
);
diff --git a/code/src/components/Button.js b/code/src/components/Button.js
new file mode 100644
index 000000000..988c6819a
--- /dev/null
+++ b/code/src/components/Button.js
@@ -0,0 +1,11 @@
+import styled from 'styled-components';
+
+export const DefaultButton = styled.button`
+background-color: red;
+border-radius: 8px 8px;
+font-size: 25px;
+&:hover {
+ box-shadow: 0 12px 16px 0 rgba(0, 0, 0, 0.24), 0 17px 50px 0 rgba(0, 0, 0, 0.19);
+ transform: scale(1.1);
+ }
+`;
\ No newline at end of file
diff --git a/code/src/components/GlobalStyle.js b/code/src/components/GlobalStyle.js
index 7a8f4840f..f493c6228 100644
--- a/code/src/components/GlobalStyle.js
+++ b/code/src/components/GlobalStyle.js
@@ -3,9 +3,11 @@ import styled from 'styled-components';
export const GlobalStyle = createGlobalStyle`
body {
- background: rgb(51,102,255);
+ /* background: rgb(51,102,255);
background: linear-gradient(180deg, rgba(51,102,255,1) 0%, rgba(255,0,255,1) 100%);
// background-color: linear-gradient(to bottom, #3366ff 0%, #ff00ff 100%);
+ // background-repeat: no-repeat;
+ background-size: 100%; */
font-family: 'DynaPuff', cursive;
font-size: 20px;
display: flex;
@@ -41,7 +43,7 @@ export const Button = styled.button`
font-size: 18px;
padding: 4px 13px;
margin: 8px;
- font-family: 'Baloo 2', cursive;
+ font-family: 'Dynapuff', cursive;
background: #edca7f;
color: #fff;
border: solid 2px red;
diff --git a/code/src/components/TagsInput.js b/code/src/components/TagsInput.js
new file mode 100644
index 000000000..0a134a17b
--- /dev/null
+++ b/code/src/components/TagsInput.js
@@ -0,0 +1,83 @@
+import React, { useState } from 'react';
+import { useSelector, useDispatch } from 'react-redux';
+import styled from 'styled-components';
+
+export const TagsInputContainer = styled.div`
+ border: 2px solid #000;
+ padding: .5em;
+ border-radius: 3px;
+ width: min(80vw, 600px);
+ margin-top: 1em;
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: .5em;
+`;
+
+export const TagItem = styled.div`
+ background-color: rgb(218, 216, 216);
+ display: inline-block;
+ padding: .5em .75em;
+ border-radius: 20px;
+`
+// .tag-item .close
+// height: 20px;
+// width: 20px;
+// background-color: rgb(48, 48, 48);
+// color: #fff;
+// border-radius: 50%;
+// display: inline-flex;
+// justify-content: center;
+// align-items: center;
+// margin-left: .5em;
+// font-size: 18px;
+// cursor: pointer;
+
+export const TagsInputField = styled.input`
+flex-grow: 1;
+ padding: .5em 0;
+ border: none;
+ outline: none;
+`;
+
+export const TagsInput = () => {
+// const [tags, setTags] = useState('');
+ const tags = useSelector(state => state.tags);
+ const dispatch = useDispatch();
+ const handleInputKeyDown = event => {
+ if (event.key === 'Enter') {
+ event.preventDefault();
+ const tag = event.target.value.trim();
+ if (tag) {
+ dispatch({ type: 'ADD_TAG', payload: tag });
+ setTagInput('');
+ }
+ } else if (event.key === 'Backspace' && !TagsInput) {
+ dispatch({ type: 'REMOVE_TAG', payload: tags[tags.length - 1]});
+ }
+ };
+
+ return (
+
+
+ {tags.map(tag) => (
+
+ {tag}
+ dispatch({ type: 'REMOVE_TAG', payload: tag })}
+ >
+ ×
+
+ setTagInput(event.target.value)}
+ placeholder="Type something"
+ />
+
+
+
+ );
+};
\ No newline at end of file
diff --git a/code/src/index.css b/code/src/index.css
index 6f7c99e66..daec5549d 100644
--- a/code/src/index.css
+++ b/code/src/index.css
@@ -1,7 +1,12 @@
@import url('https://fonts.googleapis.com/css2?family=DynaPuff:wght@400;600&display=swap');
body {
+ background: rgb(51,102,255);
+ background: linear-gradient(180deg, rgba(51,102,255,1) 0%, rgba(255,0,255,1) 100%);
+/* background-repeat: no-repeat; */
+ background-size: cover;
margin: 0;
+ height: 100%;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
diff --git a/code/src/redux/reducers/todos.js b/code/src/redux/reducers/todos.js
index 9808cde29..f9854a86b 100644
--- a/code/src/redux/reducers/todos.js
+++ b/code/src/redux/reducers/todos.js
@@ -11,6 +11,7 @@ export const todos = createSlice({
{ id: '1', text: 'Click this to-do to mark it as done ✅', isDone: false },
{ id: '2', text: 'Your first to-do is: Sing like no one is hearing!', isDone: false }
]
+ //
},
// The reducers field contains functions to modify the state of the slice (todo made with createSlice)
reducers: {
From d6cad3540698b3b218bc74930663021879fdf501 Mon Sep 17 00:00:00 2001
From: Ylva Karlsson <121539816+YlvaKarlsson@users.noreply.github.com>
Date: Thu, 20 Apr 2023 22:16:37 +0200
Subject: [PATCH 07/28] Not working anymore
---
code/src/components/TagsInput.js | 119 +++++++++++++++----------------
code/src/redux/reducers/tags.js | 19 +++++
code/src/redux/reducers/todos.js | 22 +-----
3 files changed, 77 insertions(+), 83 deletions(-)
create mode 100644 code/src/redux/reducers/tags.js
diff --git a/code/src/components/TagsInput.js b/code/src/components/TagsInput.js
index 0a134a17b..dfc135bf5 100644
--- a/code/src/components/TagsInput.js
+++ b/code/src/components/TagsInput.js
@@ -1,83 +1,78 @@
+/* eslint-disable jsx-a11y/click-events-have-key-events */
+/* eslint-disable no-shadow */
+/* eslint-no-unused-vars */
+/* eslint-disable jsx-a11y/no-static-element-interactions */
import React, { useState } from 'react';
-import { useSelector, useDispatch } from 'react-redux';
+import { useDispatch, useSelector } from 'react-redux';
+import { tags } from 'redux/reducers/tags';
import styled from 'styled-components';
export const TagsInputContainer = styled.div`
- border: 2px solid #000;
- padding: .5em;
- border-radius: 3px;
- width: min(80vw, 600px);
- margin-top: 1em;
- display: flex;
- align-items: center;
- flex-wrap: wrap;
- gap: .5em;
+ border: 2px solid #000;
+ padding: .5em;
+ border-radius: 3px;
+ width: min(80vw, 600px);
+ margin-top: 1em;
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: .5em;
`;
export const TagItem = styled.div`
- background-color: rgb(218, 216, 216);
- display: inline-block;
- padding: .5em .75em;
- border-radius: 20px;
-`
-// .tag-item .close
-// height: 20px;
-// width: 20px;
-// background-color: rgb(48, 48, 48);
-// color: #fff;
-// border-radius: 50%;
-// display: inline-flex;
-// justify-content: center;
-// align-items: center;
-// margin-left: .5em;
-// font-size: 18px;
-// cursor: pointer;
+ background-color: rgb(218, 216, 216);
+ display: inline-block;
+ padding: .5em .75em;
+ border-radius: 20px;
+`;
export const TagsInputField = styled.input`
-flex-grow: 1;
- padding: .5em 0;
- border: none;
- outline: none;
+ flex-grow: 1;
+ padding: .5em 0;
+ border: none;
+ outline: none;
`;
export const TagsInput = () => {
-// const [tags, setTags] = useState('');
- const tags = useSelector(state => state.tags);
+ const [tagInput, setTagInput] = useState('');
+ // const allTags = useSelector((state) => state.tags);
+ const allTags = useSelector((state) => state.tags.items);
const dispatch = useDispatch();
- const handleInputKeyDown = event => {
- if (event.key === 'Enter') {
- event.preventDefault();
- const tag = event.target.value.trim();
- if (tag) {
- dispatch({ type: 'ADD_TAG', payload: tag });
- setTagInput('');
- }
- } else if (event.key === 'Backspace' && !TagsInput) {
- dispatch({ type: 'REMOVE_TAG', payload: tags[tags.length - 1]});
+
+ const handleFormSubmit = (event) => {
+ event.preventDefault();
+ const newTag = tagInput.trim();
+ if (newTag) {
+ dispatch(tags.actions.addTag(newTag));
+ setTagInput('');
}
};
+ const handleTagCloseClick = (tag) => {
+ dispatch(tags.actions.removeTag(tag));
+ };
+
return (
-
- {tags.map(tag) => (
-
- {tag}
- dispatch({ type: 'REMOVE_TAG', payload: tag })}
- >
- ×
+
+ {allTags.map((tag) => (
+
+ {tag}
+ handleTagCloseClick(tag)}>
+ ×
- setTagInput(event.target.value)}
- placeholder="Type something"
- />
-
-
+
+ ))}
+
+
- );
+ );
};
\ No newline at end of file
diff --git a/code/src/redux/reducers/tags.js b/code/src/redux/reducers/tags.js
new file mode 100644
index 000000000..f365e51fc
--- /dev/null
+++ b/code/src/redux/reducers/tags.js
@@ -0,0 +1,19 @@
+import { createSlice } from '@reduxjs/toolkit';
+
+export const tags = createSlice({
+ name: 'tags',
+ initialState: {
+ items: [
+ { id: '1', text: 'Click' },
+ { id: '2', text: 'Your' }
+ ]
+ },
+ reducers: {
+ addTag: (state, action) => {
+ state.push(action.payload);
+ },
+ removeTag: (state, action) => {
+ return state.filter((tag) => tag.id !== action.payload.id);
+ }
+ }
+});
diff --git a/code/src/redux/reducers/todos.js b/code/src/redux/reducers/todos.js
index f9854a86b..58a67409d 100644
--- a/code/src/redux/reducers/todos.js
+++ b/code/src/redux/reducers/todos.js
@@ -41,24 +41,4 @@ export const todos = createSlice({
// Mutable
// store.items.push(action.payload);
// Immutable
-// store.items = [...store.items, action.payload];
-
-// const initialState = {
-// items: [
-// {
-// id: '189438fdjhrjejioe9845',
-// name: 'ToDo1',
-// isNew: false
-// },
-// {
-// id: '189438fdjhrjejioe9846',
-// name: 'ToDo2',
-// isNew: false
-// },
-// {
-// id: '189438fdjhrjejioe9847',
-// name: 'ToDo3',
-// isNew: false
-// }
-// ]
-// }
\ No newline at end of file
+// store.items = [...store.items, action.payload];
\ No newline at end of file
From aa1d9ea405122858d7bd4c32281f7ad154ea5313 Mon Sep 17 00:00:00 2001
From: Ylva Karlsson <121539816+YlvaKarlsson@users.noreply.github.com>
Date: Thu, 20 Apr 2023 22:39:34 +0200
Subject: [PATCH 08/28] Not working!
---
code/src/components/TagsInput.js | 5 +++--
code/src/redux/reducers/tags.js | 6 +++---
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/code/src/components/TagsInput.js b/code/src/components/TagsInput.js
index dfc135bf5..e4aa92c66 100644
--- a/code/src/components/TagsInput.js
+++ b/code/src/components/TagsInput.js
@@ -34,10 +34,11 @@ export const TagsInputField = styled.input`
`;
export const TagsInput = () => {
+ const dispatch = useDispatch();
const [tagInput, setTagInput] = useState('');
// const allTags = useSelector((state) => state.tags);
const allTags = useSelector((state) => state.tags.items);
- const dispatch = useDispatch();
+ // const dispatch = useDispatch();
const handleFormSubmit = (event) => {
event.preventDefault();
@@ -55,7 +56,7 @@ export const TagsInput = () => {
return (
- {allTags.map((tag) => (
+ {allTags.items.map((tag) => (
{tag}
{
- state.push(action.payload);
+ state.items.push({ id: Math.random().toString(), text: action.payload });
},
removeTag: (state, action) => {
- return state.filter((tag) => tag.id !== action.payload.id);
+ state.items = state.items.filter((tag) => tag.id !== action.payload);
}
}
-});
+});
\ No newline at end of file
From cab2f177d3fd1534a89ad2fbee69b3621a4b281d Mon Sep 17 00:00:00 2001
From: Ylva Karlsson <121539816+YlvaKarlsson@users.noreply.github.com>
Date: Thu, 20 Apr 2023 22:51:22 +0200
Subject: [PATCH 09/28] Fixed a border
---
code/src/components/ToDoItem.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/src/components/ToDoItem.js b/code/src/components/ToDoItem.js
index 93a49ca48..fbaf1b9f1 100644
--- a/code/src/components/ToDoItem.js
+++ b/code/src/components/ToDoItem.js
@@ -18,7 +18,7 @@ const DateText = styled.div`
const DeleteButton = styled.button`
background: pink;
- border: none;
+ border: solid 1px black;
font-family: 'DynaPuff', cursive;
font-size: 18px;
cursor: pointer;
From eda39f5cc567fb6705c9771e6aeaafbd4aab88d4 Mon Sep 17 00:00:00 2001
From: Ylva Karlsson <121539816+YlvaKarlsson@users.noreply.github.com>
Date: Fri, 21 Apr 2023 15:12:03 +0200
Subject: [PATCH 10/28] All working - some styling left
---
code/src/App.js | 4 +-
code/src/components/ToDoItem.js | 42 ---------------
code/src/components/{ => addtodo}/AddToDo.js | 35 +++---------
code/src/components/addtodo/AddToDo.style.js | 26 +++++++++
.../components/{ => tagsinput}/TagsInput.js | 53 ++++++-------------
.../components/tagsinput/TagsInput.style.js | 27 ++++++++++
code/src/components/todoitem/ToDoItem.js | 25 +++++++++
.../src/components/todoitem/ToDoItem.style.js | 43 +++++++++++++++
.../src/components/{ => todolist}/ToDoList.js | 20 +++----
.../src/components/todolist/ToDoList.style.js | 1 +
code/src/index.css | 5 --
code/src/redux/reducers/tags.js | 5 +-
code/src/redux/store.js | 4 +-
code/src/{components => styles}/Button.js | 5 +-
.../src/{components => styles}/GlobalStyle.js | 45 +++++++---------
15 files changed, 186 insertions(+), 154 deletions(-)
delete mode 100644 code/src/components/ToDoItem.js
rename code/src/components/{ => addtodo}/AddToDo.js (71%)
create mode 100644 code/src/components/addtodo/AddToDo.style.js
rename code/src/components/{ => tagsinput}/TagsInput.js (59%)
create mode 100644 code/src/components/tagsinput/TagsInput.style.js
create mode 100644 code/src/components/todoitem/ToDoItem.js
create mode 100644 code/src/components/todoitem/ToDoItem.style.js
rename code/src/components/{ => todolist}/ToDoList.js (82%)
create mode 100644 code/src/components/todolist/ToDoList.style.js
rename code/src/{components => styles}/Button.js (72%)
rename code/src/{components => styles}/GlobalStyle.js (50%)
diff --git a/code/src/App.js b/code/src/App.js
index a96eec704..043156f71 100644
--- a/code/src/App.js
+++ b/code/src/App.js
@@ -2,8 +2,8 @@ import React from 'react';
import { Provider } from 'react-redux';
import { persistor, store } from 'redux/store'
import { PersistGate } from 'redux-persist/integration/react';
-import { ToDoList } from 'components/ToDoList';
-import { GlobalStyle } from 'components/GlobalStyle';
+import { ToDoList } from 'components/todolist/ToDoList';
+import { GlobalStyle } from 'styles/GlobalStyle';
export const App = () => {
return (
diff --git a/code/src/components/ToDoItem.js b/code/src/components/ToDoItem.js
deleted file mode 100644
index fbaf1b9f1..000000000
--- a/code/src/components/ToDoItem.js
+++ /dev/null
@@ -1,42 +0,0 @@
-import React from 'react';
-import moment from 'moment';
-import styled from 'styled-components';
-import { SingleTodo } from './GlobalStyle';
-
-const ToDoText = styled.div`
-cursor: pointer;
-text-decoration: ${(props) => (props.isDone ? 'line-through' : 'none')};
-font-size: 24px;
-`;
-
-const DateText = styled.div`
- font-style: italic;
- font-size: 14px;
- margin: 7px;
- opacity: 50%;
-`;
-
-const DeleteButton = styled.button`
- background: pink;
- border: solid 1px black;
- font-family: 'DynaPuff', cursive;
- font-size: 18px;
- cursor: pointer;
- border-radius: 50%;
- padding: 0px 9px;
-`;
-
-export const ToDoItem = ({ todo, index, onDelete, onDone }) => {
- return (
-
- onDone(todo.id)} key={todo.id} isDone={todo.isDone}>
- {todo.text}
- Added {moment(todo.createdAt).format('HH:mm on MMM D, YYYY')}
-
- onDelete(index)} type="button" title="Delete task">
- {' '}
- X
-
-
- );
-};
\ No newline at end of file
diff --git a/code/src/components/AddToDo.js b/code/src/components/addtodo/AddToDo.js
similarity index 71%
rename from code/src/components/AddToDo.js
rename to code/src/components/addtodo/AddToDo.js
index b656d233a..44ed309e1 100644
--- a/code/src/components/AddToDo.js
+++ b/code/src/components/addtodo/AddToDo.js
@@ -3,34 +3,13 @@
import React, { useState } from 'react';
import { useDispatch } from 'react-redux';
import { todos } from 'redux/reducers/todos';
-import styled from 'styled-components';
-import { DefaultButton } from 'components/Button';
-import { TagsInput } from 'components/TagsInput';
-
-const NewToDo = styled.form`
- line-height: 0.8rem;
- padding-bottom: 0.8rem;
-`;
-
-const Input = styled.input`
- background: pink;
- border: none;
- padding: 8px;
- font-size: 18px;
- font-family: 'DynaPuff', cursive;
- border-bottom: 2px dashed;
- :focus {
- outline: none;
- }
-`;
-
-const AddButton = styled.button`
- background: pink;
- border: none;
- font-family: 'DynaPuff', cursive;
- font-size: 18px;
- cursor: pointer;
-`;
+import { DefaultButton } from 'styles/Button';
+import { TagsInput } from 'components/tagsinput/TagsInput';
+import {
+ NewToDo,
+ Input,
+ AddButton
+} from 'components/addtodo/AddToDo.style'
export const AddToDo = () => {
const [inputValue, setInputValue] = useState('');
diff --git a/code/src/components/addtodo/AddToDo.style.js b/code/src/components/addtodo/AddToDo.style.js
new file mode 100644
index 000000000..801cd7652
--- /dev/null
+++ b/code/src/components/addtodo/AddToDo.style.js
@@ -0,0 +1,26 @@
+import styled from 'styled-components';
+
+export const NewToDo = styled.form`
+ line-height: 0.8rem;
+ padding-bottom: 0.8rem;
+`;
+
+export const Input = styled.input`
+ background: pink;
+ border: none;
+ padding: 8px;
+ font-size: 18px;
+ font-family: 'DynaPuff', cursive;
+ border-bottom: 2px dashed;
+ :focus {
+ outline: none;
+ }
+`;
+
+export const AddButton = styled.button`
+ background: pink;
+ border: none;
+ font-family: 'DynaPuff', cursive;
+ font-size: 18px;
+ cursor: pointer;
+`;
diff --git a/code/src/components/TagsInput.js b/code/src/components/tagsinput/TagsInput.js
similarity index 59%
rename from code/src/components/TagsInput.js
rename to code/src/components/tagsinput/TagsInput.js
index e4aa92c66..aa6a3f85d 100644
--- a/code/src/components/TagsInput.js
+++ b/code/src/components/tagsinput/TagsInput.js
@@ -5,39 +5,18 @@
import React, { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { tags } from 'redux/reducers/tags';
-import styled from 'styled-components';
-
-export const TagsInputContainer = styled.div`
- border: 2px solid #000;
- padding: .5em;
- border-radius: 3px;
- width: min(80vw, 600px);
- margin-top: 1em;
- display: flex;
- align-items: center;
- flex-wrap: wrap;
- gap: .5em;
-`;
-
-export const TagItem = styled.div`
- background-color: rgb(218, 216, 216);
- display: inline-block;
- padding: .5em .75em;
- border-radius: 20px;
-`;
-
-export const TagsInputField = styled.input`
- flex-grow: 1;
- padding: .5em 0;
- border: none;
- outline: none;
-`;
+import {
+ TagsInputContainer,
+ TagsInputField,
+ TagItem
+} from 'components/tagsinput/TagsInput.style.js';
export const TagsInput = () => {
const dispatch = useDispatch();
const [tagInput, setTagInput] = useState('');
// const allTags = useSelector((state) => state.tags);
const allTags = useSelector((state) => state.tags.items);
+ console.log('allTaaaaaags', allTags);
// const dispatch = useDispatch();
const handleFormSubmit = (event) => {
@@ -49,29 +28,29 @@ export const TagsInput = () => {
}
};
- const handleTagCloseClick = (tag) => {
- dispatch(tags.actions.removeTag(tag));
- };
+ // const handleTagCloseClick = (tag) => {
+ // dispatch(tags.actions.removeTag(tag));
+ // };
return (
- {allTags.items.map((tag) => (
-
- {tag}
- (
+
+ {tag.text}
+ {/* handleTagCloseClick(tag)}>
×
-
+ */}
))}
diff --git a/code/src/components/tagsinput/TagsInput.style.js b/code/src/components/tagsinput/TagsInput.style.js
new file mode 100644
index 000000000..3d6f27848
--- /dev/null
+++ b/code/src/components/tagsinput/TagsInput.style.js
@@ -0,0 +1,27 @@
+import styled from 'styled-components';
+
+export const TagsInputContainer = styled.div`
+ border: 2px dotted #000;
+ padding: 0.3rem 1.5rem;
+ border-radius: 2rem;
+ max-width: 70%;
+ margin-top: 1.5rem;
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: 0.8rem;
+`;
+
+export const TagItem = styled.div`
+ background-color: rgb(218, 216, 216);
+ display: inline-block;
+ padding: .5em .75em;
+ border-radius: 20px;
+`;
+
+export const TagsInputField = styled.input`
+ flex-grow: 1;
+ padding: .5em 0;
+ border: none;
+ outline: none;
+`;
\ No newline at end of file
diff --git a/code/src/components/todoitem/ToDoItem.js b/code/src/components/todoitem/ToDoItem.js
new file mode 100644
index 000000000..d1ab817ae
--- /dev/null
+++ b/code/src/components/todoitem/ToDoItem.js
@@ -0,0 +1,25 @@
+import React from 'react';
+import moment from 'moment';
+import {
+ SingleTodo,
+ DateAndDelete,
+ DeleteButton,
+ ToDoText,
+ DateText
+} from 'components/todoitem/ToDoItem.style';
+
+export const ToDoItem = ({ todo, index, onDelete, onDone }) => {
+ return (
+
+ onDone(todo.id)} key={todo.id} isDone={todo.isDone}>
+ {todo.text}
+
+
+ onDelete(index)} type="button" title="Delete task">
+ X
+
+ Added {moment(todo.createdAt).format('HH:mm on MMM D, YYYY')}
+
+
+ );
+};
\ No newline at end of file
diff --git a/code/src/components/todoitem/ToDoItem.style.js b/code/src/components/todoitem/ToDoItem.style.js
new file mode 100644
index 000000000..ce3016c7b
--- /dev/null
+++ b/code/src/components/todoitem/ToDoItem.style.js
@@ -0,0 +1,43 @@
+import styled from 'styled-components';
+
+export const SingleTodo = styled.div`
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-between;
+ background: lightpink;
+ margin: 10px;
+ border-bottom: 1px solid black;
+ padding: 1rem 2rem;
+`;
+
+export const ToDoText = styled.div`
+cursor: pointer;
+text-decoration: ${(props) => (props.isDone ? 'line-through' : 'none')};
+font-size: 24px;
+`;
+
+export const DateAndDelete = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 0.5rem;
+`;
+
+export const DateText = styled.div`
+ font-style: italic;
+ font-size: 14px;
+ margin: 7px;
+ opacity: 50%;
+`;
+
+export const DeleteButton = styled.button`
+ background: #e47588;
+ border: solid 1px black;
+ font-family: 'DynaPuff', cursive;
+ font-size: 18px;
+ cursor: pointer;
+ border-radius: 50%;
+ padding: 0px 9px;
+ max-width: 2.5rem;
+`;
\ No newline at end of file
diff --git a/code/src/components/ToDoList.js b/code/src/components/todolist/ToDoList.js
similarity index 82%
rename from code/src/components/ToDoList.js
rename to code/src/components/todolist/ToDoList.js
index 59bc4c657..5bbc26721 100644
--- a/code/src/components/ToDoList.js
+++ b/code/src/components/todolist/ToDoList.js
@@ -4,9 +4,11 @@
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { todos } from 'redux/reducers/todos';
-import { ToDoItem } from './ToDoItem';
-import { AddToDo } from './AddToDo';
-import { Wrapper } from './GlobalStyle';
+import { AddToDo } from 'components/addtodo/AddToDo';
+// import { ToDoItem } from './ToDoItem';
+import { ToDoItem } from 'components/todoitem/ToDoItem';
+import { Wrapper } from 'styles/GlobalStyle';
+import { DefaultButton } from 'styles/Button';
export const ToDoList = () => {
const dispatch = useDispatch();
@@ -47,23 +49,23 @@ export const ToDoList = () => {
*/}
To-do ({todosTodo.length})
+
+
{todosTodo.length === 0 && All done - great job! ✨
}
{todosTodo.map((todo, index) => (
))}
-
-
Done ({doneTodos.length})
-
+
Complete all to-dos
-
+
-
+
Clear all to-dos
-
+
{doneTodos.map((todo, index) => (
diff --git a/code/src/components/todolist/ToDoList.style.js b/code/src/components/todolist/ToDoList.style.js
new file mode 100644
index 000000000..4daa90b41
--- /dev/null
+++ b/code/src/components/todolist/ToDoList.style.js
@@ -0,0 +1 @@
+// import styled from 'styled-components';
diff --git a/code/src/index.css b/code/src/index.css
index daec5549d..6f7c99e66 100644
--- a/code/src/index.css
+++ b/code/src/index.css
@@ -1,12 +1,7 @@
@import url('https://fonts.googleapis.com/css2?family=DynaPuff:wght@400;600&display=swap');
body {
- background: rgb(51,102,255);
- background: linear-gradient(180deg, rgba(51,102,255,1) 0%, rgba(255,0,255,1) 100%);
-/* background-repeat: no-repeat; */
- background-size: cover;
margin: 0;
- height: 100%;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
diff --git a/code/src/redux/reducers/tags.js b/code/src/redux/reducers/tags.js
index c107d3ff1..f1d8159c1 100644
--- a/code/src/redux/reducers/tags.js
+++ b/code/src/redux/reducers/tags.js
@@ -4,8 +4,9 @@ export const tags = createSlice({
name: 'tags',
initialState: {
items: [
- { id: '1', text: 'Click' },
- { id: '2', text: 'Your' }
+ { id: '1', text: 'Work' },
+ { id: '2', text: 'Home' },
+ { id: '3', text: 'Other' }
]
},
reducers: {
diff --git a/code/src/redux/store.js b/code/src/redux/store.js
index fe54791bc..07d6f1e05 100644
--- a/code/src/redux/store.js
+++ b/code/src/redux/store.js
@@ -1,5 +1,6 @@
import { configureStore, combineReducers } from '@reduxjs/toolkit'
import { todos } from 'redux/reducers/todos';
+import { tags } from 'redux/reducers/tags';
import storage from 'redux-persist/lib/storage';
import { persistReducer, persistStore } from 'redux-persist';
import thunk from 'redux-thunk';
@@ -10,7 +11,8 @@ const persistConfig = {
}
const reducer = combineReducers({
- todos: todos.reducer
+ todos: todos.reducer,
+ tags: tags.reducer
});
const persistedReducer = persistReducer(persistConfig, reducer)
diff --git a/code/src/components/Button.js b/code/src/styles/Button.js
similarity index 72%
rename from code/src/components/Button.js
rename to code/src/styles/Button.js
index 988c6819a..5f4885ab6 100644
--- a/code/src/components/Button.js
+++ b/code/src/styles/Button.js
@@ -1,9 +1,12 @@
import styled from 'styled-components';
export const DefaultButton = styled.button`
-background-color: red;
+background-color: pink;
+border: solid black 2px;
border-radius: 8px 8px;
font-size: 25px;
+font-family: 'Dynapuff', cursive;
+color: #6c6969;
&:hover {
box-shadow: 0 12px 16px 0 rgba(0, 0, 0, 0.24), 0 17px 50px 0 rgba(0, 0, 0, 0.19);
transform: scale(1.1);
diff --git a/code/src/components/GlobalStyle.js b/code/src/styles/GlobalStyle.js
similarity index 50%
rename from code/src/components/GlobalStyle.js
rename to code/src/styles/GlobalStyle.js
index f493c6228..36a50ad9a 100644
--- a/code/src/components/GlobalStyle.js
+++ b/code/src/styles/GlobalStyle.js
@@ -3,11 +3,11 @@ import styled from 'styled-components';
export const GlobalStyle = createGlobalStyle`
body {
- /* background: rgb(51,102,255);
+ background: rgb(51,102,255);
background: linear-gradient(180deg, rgba(51,102,255,1) 0%, rgba(255,0,255,1) 100%);
-// background-color: linear-gradient(to bottom, #3366ff 0%, #ff00ff 100%);
- // background-repeat: no-repeat;
- background-size: 100%; */
+ background-repeat: no-repeat;
+ min-height: 100vh;
+ background-size: cover;
font-family: 'DynaPuff', cursive;
font-size: 20px;
display: flex;
@@ -30,26 +30,17 @@ export const Wrapper = styled.div`
}
`;
-export const SingleTodo = styled.div`
- background: lightpink;
- margin: 10px;
- border-bottom: 1px solid black;
- padding-top: 10px;
- padding-bottom: 15px;
- line-height: 1em;
-`;
-
-export const Button = styled.button`
- font-size: 18px;
- padding: 4px 13px;
- margin: 8px;
- font-family: 'Dynapuff', cursive;
- background: #edca7f;
- color: #fff;
- border: solid 2px red;
- border-radius: 30px;
- cursor: pointer;
- /* :hover {
- opacity: 70%;
- } */
-`;
+// export const Button = styled.button`
+// font-size: 18px;
+// padding: 4px 13px;
+// margin: 8px;
+// font-family: 'Dynapuff', cursive;
+// background: tomato;
+// color: #fff;
+// border: solid 2px red;
+// border-radius: 30px;
+// cursor: pointer;
+// /* :hover {
+// opacity: 70%;
+// } */
+// `;
From ae0753a3d0ad2c2bb9c20459d8fff8c5ee049ac1 Mon Sep 17 00:00:00 2001
From: Ylva Karlsson <121539816+YlvaKarlsson@users.noreply.github.com>
Date: Fri, 21 Apr 2023 15:25:35 +0200
Subject: [PATCH 11/28] Fixed some bugs
---
code/src/components/addtodo/AddToDo.js | 22 ++++++++-----------
code/src/components/addtodo/AddToDo.style.js | 7 ++++++
code/src/components/todolist/ToDoList.js | 13 ++++++-----
.../src/components/todolist/ToDoList.style.js | 9 +++++++-
4 files changed, 31 insertions(+), 20 deletions(-)
diff --git a/code/src/components/addtodo/AddToDo.js b/code/src/components/addtodo/AddToDo.js
index 44ed309e1..7d1b21d33 100644
--- a/code/src/components/addtodo/AddToDo.js
+++ b/code/src/components/addtodo/AddToDo.js
@@ -8,7 +8,7 @@ import { TagsInput } from 'components/tagsinput/TagsInput';
import {
NewToDo,
Input,
- AddButton
+ AddContainer
} from 'components/addtodo/AddToDo.style'
export const AddToDo = () => {
@@ -40,19 +40,15 @@ export const AddToDo = () => {
onChange={(event) => setInputValue(event.target.value)} />
{/* id={`new-todo-input${newToDo.id}`} /> */}
-
-
+
+
+
Add
-
-
- Add
-
+
+
);
diff --git a/code/src/components/addtodo/AddToDo.style.js b/code/src/components/addtodo/AddToDo.style.js
index 801cd7652..e3cd523f5 100644
--- a/code/src/components/addtodo/AddToDo.style.js
+++ b/code/src/components/addtodo/AddToDo.style.js
@@ -6,6 +6,7 @@ export const NewToDo = styled.form`
`;
export const Input = styled.input`
+ min-height: 3rem;
background: pink;
border: none;
padding: 8px;
@@ -24,3 +25,9 @@ export const AddButton = styled.button`
font-size: 18px;
cursor: pointer;
`;
+
+export const AddContainer = styled.div`
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+`;
diff --git a/code/src/components/todolist/ToDoList.js b/code/src/components/todolist/ToDoList.js
index 5bbc26721..3275150da 100644
--- a/code/src/components/todolist/ToDoList.js
+++ b/code/src/components/todolist/ToDoList.js
@@ -9,6 +9,7 @@ import { AddToDo } from 'components/addtodo/AddToDo';
import { ToDoItem } from 'components/todoitem/ToDoItem';
import { Wrapper } from 'styles/GlobalStyle';
import { DefaultButton } from 'styles/Button';
+import { ButtonContainer } from './ToDoList.style';
export const ToDoList = () => {
const dispatch = useDispatch();
@@ -58,15 +59,15 @@ export const ToDoList = () => {
))}
Done ({doneTodos.length})
-
-
+
+
Complete all to-dos
-
+
-
+
Clear all to-dos
-
-
+
+
{doneTodos.map((todo, index) => (
))}
diff --git a/code/src/components/todolist/ToDoList.style.js b/code/src/components/todolist/ToDoList.style.js
index 4daa90b41..84369193d 100644
--- a/code/src/components/todolist/ToDoList.style.js
+++ b/code/src/components/todolist/ToDoList.style.js
@@ -1 +1,8 @@
-// import styled from 'styled-components';
+import styled from 'styled-components';
+
+export const ButtonContainer = styled.div`
+display: flex;
+flex-direction: row;
+justify-content: center;
+gap: 1rem;
+`;
From cc5bf0b0967f617d77fbca370a139c82ebedbefe Mon Sep 17 00:00:00 2001
From: Ylva Karlsson <121539816+YlvaKarlsson@users.noreply.github.com>
Date: Sun, 23 Apr 2023 19:40:11 +0200
Subject: [PATCH 12/28] Added OG-tags and updated readme
---
code/public/index.html | 2 ++
code/src/App.js | 2 +-
code/src/components/addtodo/AddToDo.js | 4 ++--
code/src/components/addtodo/AddToDo.style.js | 1 +
code/src/components/tagsinput/TagsInput.js | 2 +-
code/src/components/todoitem/ToDoItem.js | 2 +-
code/src/components/todolist/ToDoList.js | 4 ++--
7 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/code/public/index.html b/code/public/index.html
index 9f84e31ff..1ab5c89bd 100644
--- a/code/public/index.html
+++ b/code/public/index.html
@@ -4,6 +4,8 @@
+
+
+
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