diff --git a/.eslintrc.js b/.eslintrc.js index 17514e75..4e8e6fef 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -49,7 +49,12 @@ module.exports = { }, ], rules: { - "prettier/prettier": "error", + "prettier/prettier": [ + "error", + { + endOfLine: "auto", + }, + ], "react/jsx-filename-extension": "off", "import/prefer-default-export": "off", "prefer-destructuring": "off", @@ -59,5 +64,21 @@ module.exports = { "no-underscore-dangle": "off", "react/forbid-prop-types": "off", "react/prop-types": "off", + "jsx-a11y/label-has-associated-control": [ + "error", + { + required: { + some: ["nesting", "id"], + }, + }, + ], + "jsx-a11y/label-has-for": [ + "error", + { + required: { + some: ["nesting", "id"], + }, + }, + ], }, }; diff --git a/package-lock.json b/package-lock.json index a58d3d17..567efa2e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1279,6 +1279,29 @@ "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-10.1.0.tgz", "integrity": "sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg==" }, + "@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==", + "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==" + }, + "@emotion/stylis": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", + "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==" + }, + "@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + }, "@eslint/eslintrc": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.1.tgz", @@ -2140,6 +2163,11 @@ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=" }, + "@types/lodash": { + "version": "4.14.170", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.170.tgz", + "integrity": "sha512-bpcvu/MKHHeYX+qeEN8GE7DIravODWdACVA1ctevD8CN24RhPZIKMn9ntfAsrvLfSX3cR5RrBKAbYm9bGs0A+Q==" + }, "@types/minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz", @@ -3088,6 +3116,22 @@ "@babel/helper-define-polyfill-provider": "^0.2.0" } }, + "babel-plugin-styled-components": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.12.0.tgz", + "integrity": "sha512-FEiD7l5ZABdJPpLssKXjBUJMYqzbcNzBowfXDCdJhOpbhWiewapUaY+LZGT8R4Jg2TwOjGjG4RKeyrO5p9sBkA==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-module-imports": "^7.0.0", + "babel-plugin-syntax-jsx": "^6.18.0", + "lodash": "^4.17.11" + } + }, + "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": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=" + }, "babel-plugin-syntax-object-rest-spread": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", @@ -3815,6 +3859,11 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==" }, + "camelize": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", + "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" + }, "caniuse-api": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", @@ -4518,6 +4567,11 @@ "postcss": "^7.0.5" } }, + "css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=" + }, "css-color-names": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", @@ -4601,6 +4655,16 @@ "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" }, + "css-to-react-native": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz", + "integrity": "sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==", + "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", @@ -6937,6 +7001,27 @@ "mime-types": "^2.1.12" } }, + "formik": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/formik/-/formik-2.2.8.tgz", + "integrity": "sha512-hDjQyTGO0ivptzCRHEyeTvfvgFVSzLeW2ptAgSk5U2jkf8pvSNtXe6oExo1RmrbKF1Bs7dmPv4P5g2JAgYnvlw==", + "requires": { + "deepmerge": "^2.1.1", + "hoist-non-react-statics": "^3.3.0", + "lodash": "^4.17.14", + "lodash-es": "^4.17.14", + "react-fast-compare": "^2.0.1", + "tiny-warning": "^1.0.2", + "tslib": "^1.10.0" + }, + "dependencies": { + "deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==" + } + } + }, "forwarded": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", @@ -9433,6 +9518,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, "lodash._reinterpolate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", @@ -9572,6 +9662,11 @@ "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==", "dev": true }, + "material-design-icons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/material-design-icons/-/material-design-icons-3.0.1.tgz", + "integrity": "sha1-mnHEh0chjrylHlGmbaaCA4zct78=" + }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -9914,6 +10009,11 @@ "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", "optional": true }, + "nanoclone": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz", + "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==" + }, "nanoid": { "version": "3.1.23", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", @@ -11938,6 +12038,11 @@ } } }, + "property-expr": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.4.tgz", + "integrity": "sha512-sFPkHQjVKheDNnPvotjQmm3KD3uk1fWKUN7CrpdbwmUx3CrG3QiM8QpTSimvig5vTXmTvjz7+TDvXOI9+4rkcg==" + }, "proxy-addr": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", @@ -12333,6 +12438,19 @@ "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz", "integrity": "sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew==" }, + "react-fast-compare": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz", + "integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==" + }, + "react-head": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/react-head/-/react-head-3.4.0.tgz", + "integrity": "sha512-T+a+WTN2lQECle3KdUBTnXMpjzOTDRFS1f2jCLP9H64XBXgayxadoLkzWSiJD793zE8IMWzQ8xKe3V573es9NQ==", + "requires": { + "@babel/runtime": "^7.8.3" + } + }, "react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -13665,6 +13783,11 @@ "safe-buffer": "^5.0.1" } }, + "shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -14342,6 +14465,38 @@ "schema-utils": "^2.7.0" } }, + "styled-components": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.0.tgz", + "integrity": "sha512-bPJKwZCHjJPf/hwTJl6TbkSZg/3evha+XPEizrZUGb535jLImwDUdjTNxXqjjaASt2M4qO4AVfoHJNe3XB/tpQ==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/traverse": "^7.4.5", + "@emotion/is-prop-valid": "^0.8.8", + "@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": { + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "stylehacks": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", @@ -14793,6 +14948,11 @@ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" }, + "toposort": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", + "integrity": "sha1-riF2gXXRVZ1IvvNUILL0li8JwzA=" + }, "tough-cookie": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", @@ -16880,6 +17040,20 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" + }, + "yup": { + "version": "0.32.9", + "resolved": "https://registry.npmjs.org/yup/-/yup-0.32.9.tgz", + "integrity": "sha512-Ci1qN+i2H0XpY7syDQ0k5zKQ/DoxO0LzPg8PAR/X4Mpj6DqaeCoIYEEjDJwhArh3Fa7GWbQQVDZKeXYlSH4JMg==", + "requires": { + "@babel/runtime": "^7.10.5", + "@types/lodash": "^4.14.165", + "lodash": "^4.17.20", + "lodash-es": "^4.17.15", + "nanoclone": "^0.2.1", + "property-expr": "^2.0.4", + "toposort": "^2.0.2" + } } } } diff --git a/package.json b/package.json index 326aeb06..85082b87 100644 --- a/package.json +++ b/package.json @@ -16,16 +16,21 @@ "@testing-library/react": "^11.2.6", "@testing-library/user-event": "^13.1.5", "bootstrap": "^4.6.0", + "formik": "^2.2.8", + "material-design-icons": "^3.0.1", "prop-types": "^15.7.2", "react": "^17.0.2", "react-dom": "^17.0.2", + "react-head": "^3.4.0", "react-redux": "^7.2.3", "react-router-dom": "^5.2.0", "react-scripts": "4.0.3", "redux": "^4.0.5", "redux-thunk": "^2.3.0", "sass": "^1.32.11", - "web-vitals": "^1.1.1" + "styled-components": "^5.3.0", + "web-vitals": "^1.1.1", + "yup": "^0.32.9" }, "devDependencies": { "@babel/core": "^7.13.16", diff --git a/src/App.js b/src/App.js index de524524..8d882a7f 100644 --- a/src/App.js +++ b/src/App.js @@ -1,14 +1,18 @@ import React from "react"; +import { BrowserRouter } from "react-router-dom"; +import { HeadProvider, Title, Meta } from "react-head"; + +import Home from "./pages/Home"; function App() { return ( -
-
-
-

Hola mundo

-
-
-
+ + + Title of page + + + + ); } diff --git a/src/components/AppHeader/AppHeader.js b/src/components/AppHeader/AppHeader.js new file mode 100644 index 00000000..7c783f61 --- /dev/null +++ b/src/components/AppHeader/AppHeader.js @@ -0,0 +1,33 @@ +import React, { Component } from "react"; + +import "./AppHeader.scss"; + +class AppHeader extends Component { + constructor(props) { + super(props); + this.state = {}; + } + + render() { + const { themeToggler } = this.props; + return ( +
+

TODO

+ +
+ ); + } +} + +export default AppHeader; diff --git a/src/components/AppHeader/AppHeader.scss b/src/components/AppHeader/AppHeader.scss new file mode 100644 index 00000000..53ac05c0 --- /dev/null +++ b/src/components/AppHeader/AppHeader.scss @@ -0,0 +1,13 @@ +.gridMode { + display: grid; + grid-template-columns: auto 40px; + width: 100%; + height: fit-content; + align-items: center; +} + +.big-title { + font-size: 50px; + font-weight: bold; + letter-spacing: 12px; +} diff --git a/src/components/AppHeader/index.js b/src/components/AppHeader/index.js new file mode 100644 index 00000000..8ad0d174 --- /dev/null +++ b/src/components/AppHeader/index.js @@ -0,0 +1 @@ +export { default } from "./AppHeader"; diff --git a/src/components/BgPicture/BgPicture.js b/src/components/BgPicture/BgPicture.js new file mode 100644 index 00000000..5c38e731 --- /dev/null +++ b/src/components/BgPicture/BgPicture.js @@ -0,0 +1,25 @@ +import React, { Component } from "react"; + +import "./BgPicture.scss"; + +class BgPicture extends Component { + constructor(props) { + super(props); + this.state = {}; + } + + render() { + return ( +
+
+
+ ); + } +} + +export default BgPicture; diff --git a/src/components/BgPicture/BgPicture.scss b/src/components/BgPicture/BgPicture.scss new file mode 100644 index 00000000..c4b6e0d5 --- /dev/null +++ b/src/components/BgPicture/BgPicture.scss @@ -0,0 +1,16 @@ +.bgPicture { + position: absolute; + transform: translateY(-10vh); + z-index: 50; + height: 45vh; + width: 100%; + overflow: hidden; + object-fit: cover; +} + +.bgImg { + width: 100%; + z-index: 60; + object-fit: cover; + transform: translateY(-100px); +} diff --git a/src/components/BgPicture/index.js b/src/components/BgPicture/index.js new file mode 100644 index 00000000..8c8b91b6 --- /dev/null +++ b/src/components/BgPicture/index.js @@ -0,0 +1 @@ +export { default } from "./BgPicture"; diff --git a/src/components/CardFooter/CardFooter.js b/src/components/CardFooter/CardFooter.js new file mode 100644 index 00000000..4dbe143c --- /dev/null +++ b/src/components/CardFooter/CardFooter.js @@ -0,0 +1,31 @@ +import React, { Component } from "react"; + +import "./CardFooter.scss"; + +class CardFooter extends Component { + constructor(props) { + super(props); + this.state = { + toDosToDo: 0, + }; + this.leftToDos = this.leftToDos.bind(this); + } + + leftToDos() { + // eslint-disable-next-line no-unused-vars + const { toDosToDo } = this.state; + } + + render() { + const { allToDos } = this.props; + return ( +
+

{allToDos} items left

+
All Active Completed
+
Clear completed
+
+ ); + } +} + +export default CardFooter; diff --git a/src/components/CardFooter/CardFooter.scss b/src/components/CardFooter/CardFooter.scss new file mode 100644 index 00000000..08760865 --- /dev/null +++ b/src/components/CardFooter/CardFooter.scss @@ -0,0 +1,21 @@ +.gridFooter { + display: grid; + grid-template-columns: 1fr 5fr 1.5fr; + grid-template-rows: fit-content; + width: 100%; + height: fit-content; + padding: 1%; + align-items: center; + justify-content: center; + justify-items: center; + margin: 0; +} + +.text-center { + text-align: center; + margin-bottom: 0px; + p { + text-align: center; + margin-bottom: 0px; + } +} diff --git a/src/components/CardFooter/index.js b/src/components/CardFooter/index.js new file mode 100644 index 00000000..0c2197fe --- /dev/null +++ b/src/components/CardFooter/index.js @@ -0,0 +1 @@ +export { default } from "./CardFooter"; diff --git a/src/components/DarkMode/Theme.js b/src/components/DarkMode/Theme.js new file mode 100644 index 00000000..7db77060 --- /dev/null +++ b/src/components/DarkMode/Theme.js @@ -0,0 +1,26 @@ +export const lightTheme = { + body: "white", + text: "grey", + toggleBorder: "black", + background: "rgb(216, 204, 196)", + p: "black", + border_wide: "black", + mainBackground: "white", + h1: "black", + validation: "orange", + bigImage: + "https://images.pexels.com/photos/1232594/pexels-photo-1232594.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260", +}; +export const darkTheme = { + body: "grey", + text: "white", + toggleBorder: "#white", + background: "rgb(20, 41, 49)", + p: "White", + border_wide: "grey", + mainBackground: "rgb(11, 28, 49)", + h1: "white", + validation: "rgb(0, 109, 218)", + bigImage: + "https://images.pexels.com/photos/540518/pexels-photo-540518.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260", +}; diff --git a/src/components/DarkMode/globalStyles.js b/src/components/DarkMode/globalStyles.js new file mode 100644 index 00000000..d55b42f7 --- /dev/null +++ b/src/components/DarkMode/globalStyles.js @@ -0,0 +1,55 @@ +import { createGlobalStyle } from "styled-components"; + +export const GlobalStyles = createGlobalStyle` + body { + background: ${({ theme }) => theme.background}; + color: ${({ theme }) => theme.text}; + font-family: Tahoma, Helvetica, Arial, Roboto, sans-serif; + transition: all 0.50s linear; + } + .card-wide{ + background-color:${({ theme }) => theme.mainBackground}; + border-bottom:1px solid ${({ theme }) => theme.border_wide}; + transition: all 0.50s linear; + } + p{ + color:${({ theme }) => theme.p}; + transition: all 0.50s linear; + } + button.btnDarkMode{ + color:${({ theme }) => theme.h1}; + transition: all 0.50s linear; + } + .whiteBg { + background-color: ${({ theme }) => theme.mainBackground}; + transition: all 0.50s linear; + } + span{ + color:${({ theme }) => theme.p}; + transition: all 0.50s linear; + } + input{ + background-color:${({ theme }) => theme.mainBackground}; + transition: all 0.50s linear; + } + .gray-color { + color: ${({ theme }) => theme.border_wide}; + transition: all 0.50s linear; + } + .mainBackground { + background-color: ${({ theme }) => theme.background}; + transition: all 0.50s linear; + } + .bgPicture { + background-image: url(${({ theme }) => theme.bigImage}); + transition: all 0.50s linear; + } + h1{ + color:${({ theme }) => theme.h1}; + transition: all 0.50s linear; + } + .validation{ + color:${({ theme }) => theme.validation}; + transform:translateY(-7px); + } + `; diff --git a/src/components/Footer/Footer.js b/src/components/Footer/Footer.js new file mode 100644 index 00000000..1f19ff4e --- /dev/null +++ b/src/components/Footer/Footer.js @@ -0,0 +1,20 @@ +import React, { Component } from "react"; + +import "./Footer.scss"; + +class Footer extends Component { + constructor(props) { + super(props); + this.state = {}; + } + + render() { + return ( + + ); + } +} + +export default Footer; diff --git a/src/components/Footer/Footer.scss b/src/components/Footer/Footer.scss new file mode 100644 index 00000000..938a5efd --- /dev/null +++ b/src/components/Footer/Footer.scss @@ -0,0 +1,8 @@ +.centerText { + text-align: center; +} + +.font-size-10 { + font-size: 10; +} + diff --git a/src/components/Footer/index.js b/src/components/Footer/index.js new file mode 100644 index 00000000..3738288b --- /dev/null +++ b/src/components/Footer/index.js @@ -0,0 +1 @@ +export { default } from "./Footer"; diff --git a/src/components/Input-schema/input-Schema.js b/src/components/Input-schema/input-Schema.js new file mode 100644 index 00000000..0638e852 --- /dev/null +++ b/src/components/Input-schema/input-Schema.js @@ -0,0 +1,10 @@ +import * as Yup from "yup"; + +const productSchema = Yup.object().shape({ + title: Yup.string() + .min(2, "The title is too short!") + .max(10, "The title is too long!") + .required("The title is required"), +}); + +export default productSchema; diff --git a/src/components/NewTodoCard/NewTodoCard.js b/src/components/NewTodoCard/NewTodoCard.js new file mode 100644 index 00000000..90e99d78 --- /dev/null +++ b/src/components/NewTodoCard/NewTodoCard.js @@ -0,0 +1,83 @@ +import React, { Component } from "react"; + +class NewTodoCard extends Component { + constructor(props) { + super(props); + this.state = { + inputText: "", + validation: false, + }; + this.formManagement = this.formManagement.bind(this); + this.submit = this.submit.bind(this); + } + + formManagement(event) { + // const { inputText } = this.state; + + this.setState({ + inputText: event.target.value, + }); + + // console.log(inputText); + } + + submit(event) { + const { inputText } = this.state; + // eslint-disable-next-line no-unused-vars + const { validation } = this.state; + const { newToDo } = this.props; + + event.preventDefault(); + + if (inputText.trim() !== "") { + newToDo(inputText); + this.setState({ + validation: true, + inputText: "", + }); + } else { + this.setState({ + validation: false, + }); + } + + // console.log(inputText); + // console.log(newTodo); + // console.log(this.props); + // console.log(this); + } + + render() { + const { inputText, validation } = this.state; + + return ( +
+
+ +
+ +
+
+ {!validation && ( +
AƱada una tarea, por favor
+ )} +
+ ); + } +} + +export default NewTodoCard; diff --git a/src/components/NewTodoCard/index.js b/src/components/NewTodoCard/index.js new file mode 100644 index 00000000..2f38a9ab --- /dev/null +++ b/src/components/NewTodoCard/index.js @@ -0,0 +1 @@ +export { default } from "./NewTodoCard"; diff --git a/src/components/TodoCard/TodoCard.js b/src/components/TodoCard/TodoCard.js new file mode 100644 index 00000000..e84156dc --- /dev/null +++ b/src/components/TodoCard/TodoCard.js @@ -0,0 +1,156 @@ +import React, { Component } from "react"; + +import "./TodoCard.scss"; + +class TodoCard extends Component { + constructor(props) { + super(props); + this.state = { + editMode: false, + newEditedText: "", + isDone: false, + showHideSidenav: "show", + divHidden: "hidden", + }; + this.deleteTodo = this.deleteTodo.bind(this); + this.editToDo = this.editToDo.bind(this); + this.manageNewtoDoText = this.manageNewtoDoText.bind(this); + this.submitEdit = this.submitEdit.bind(this); + this.toggleChange = this.toggleChange.bind(this); + this.hoverDivIn = this.hoverDivIn.bind(this); + this.hoverDivOut = this.hoverDivOut.bind(this); + } + + toggleChange() { + const { isDone } = this.state; + + if (isDone) { + this.setState({ + showHideSidenav: "show", + }); + } else { + this.setState({ + showHideSidenav: "taskDone", + }); + setTimeout(() => { + this.setState({ + showHideSidenav: "hidden", + }); + }, 1000); + } + + this.setState({ + isDone: !isDone, + }); + } + + hoverDivIn() { + this.setState({ + divHidden: "divHover", + }); + } + + hoverDivOut() { + this.setState({ + divHidden: "hidden", + }); + } + + editToDo() { + // const { editMode } = this.state; + + this.setState({ + editMode: true, + }); + } + + manageNewtoDoText(event) { + this.setState({ + newEditedText: event.target.value, + }); + } + + submitEdit(event) { + const { updateToDo, id } = this.props; + const { newEditedText } = this.state; + + event.preventDefault(); + + updateToDo(id, newEditedText); + this.setState({ + newEditedText: "", + editMode: false, + }); + } + + deleteTodo() { + const { selectedToDoToDelete, id } = this.props; + selectedToDoToDelete(id); + // console.log(this); + } + + render() { + const { toDo } = this.props; + const { editMode, newEditedText, isDone, showHideSidenav, divHidden } = + this.state; + + return ( +
+ {!editMode ? ( +
+ + {toDo} +
+ + +
+
+ ) : ( + <> +
+ + +
+ + )} +
+ ); + } +} + +export default TodoCard; diff --git a/src/components/TodoCard/TodoCard.scss b/src/components/TodoCard/TodoCard.scss new file mode 100644 index 00000000..de93c7a9 --- /dev/null +++ b/src/components/TodoCard/TodoCard.scss @@ -0,0 +1,89 @@ + +.flex-row { + display: flex; + flex-direction: row; + justify-items: center; +} + +.card-wide { + width: 100%; + height: 50px; + padding: 10px; + gap: 10px; + align-items: center; +} + +.card-widetWo { + width: 100%; + height: 50px; + padding: 10px; + gap: 10px; + align-items: center; +} + +.font-bold { + font-weight: bold; +} + +.font-big { + font-size: 18px; +} + +.font-light { + font-weight: 100; +} + +label { + display: inline-block; + margin-bottom: 0px; +} + +input.blue-checkbox { + width: 20px; + height: 20px; + border: 1px red solid; +} + +.full-width { + width: 100%; +} + +.input-no-border { + border: none; + outline: none; + :focus { + background-color: red; + } +} + +.clickable { + cursor: pointer; +} +.no-border { + border: none; +} + +.taskDone { + color:red; + visibility: hidden; + opacity: 0; + transition: visibility 0s 1s, opacity 1s linear; +} + +.show{ + color: black; +} + +.hidden{ + display: none; + opacity: 0; +} + +.divHover{ + display: block; +} + +.validation{ + text-align: center; + color: red; +} \ No newline at end of file diff --git a/src/components/TodoCard/index.js b/src/components/TodoCard/index.js new file mode 100644 index 00000000..0e041b8e --- /dev/null +++ b/src/components/TodoCard/index.js @@ -0,0 +1 @@ +export { default } from "./TodoCard"; diff --git a/src/pages/Home/Home.js b/src/pages/Home/Home.js new file mode 100644 index 00000000..6cbf989c --- /dev/null +++ b/src/pages/Home/Home.js @@ -0,0 +1,157 @@ +import React, { Component } from "react"; + +import "./Home.scss"; +import { ThemeProvider } from "styled-components"; +import AppHeader from "../../components/AppHeader/index"; +import Footer from "../../components/Footer/index"; +import TodoCard from "../../components/TodoCard/index"; +import NewTodoCard from "../../components/NewTodoCard/index"; +import BgPicture from "../../components/BgPicture/index"; +import { GlobalStyles } from "../../components/DarkMode/globalStyles"; +import { lightTheme, darkTheme } from "../../components/DarkMode/Theme"; +import CardFooter from "../../components/CardFooter/index"; + +const LOCAL_STORAGE_KEY = "toDoListSaved"; + +function loadLocalStorageData() { + const prevToDos = localStorage.getItem(LOCAL_STORAGE_KEY); + + if (!prevToDos) { + return null; + } + + try { + return JSON.parse(prevToDos); + } catch (error) { + return null; + } +} + +class Home extends Component { + constructor(props) { + super(props); + this.state = { + toDoList: [], + theme: "light", + }; + this.newToDo = this.newToDo.bind(this); + this.selectedToDoToDelete = this.selectedToDoToDelete.bind(this); + this.updateToDo = this.updateToDo.bind(this); + this.themeToggler = this.themeToggler.bind(this); + } + + componentDidMount() { + const prevToDos = loadLocalStorageData(); + + if (prevToDos) { + this.setState({ + toDoList: prevToDos, + }); + } else { + this.setState({ + toDoList: [], + }); + } + } + + componentDidUpdate() { + const { toDoList } = this.state; + + localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(toDoList)); + } + + newToDo(toDo) { + const { toDoList } = this.state; + + this.setState({ + toDoList: [toDo, ...toDoList], + }); + } + + selectedToDoToDelete(id) { + const { toDoList } = this.state; + + const filteredToDoList = toDoList.filter((e, index) => index !== id); + this.setState({ + toDoList: filteredToDoList, + }); + } + + updateToDo(id, toDo) { + const { toDoList } = this.state; + + const updatedList = toDoList.map((e, index) => { + if (index === id) { + // eslint-disable-next-line no-param-reassign + e = toDo; + } + return e; + }); + this.setState({ + toDoList: updatedList, + }); + } + + themeToggler() { + const { theme } = this.state; + if (theme === "light") { + this.setState({ + theme: "dark", + }); + } else { + this.setState({ + theme: "light", + }); + } + } + + // noActiveToDos() { + // // eslint-disable-next-line no-unused-vars + // const { toDoList } = this.state; + // toDoList.toDoList.filter( + // (e, index) => {isDone !== false} + // ); + // this.setState({ + // toDoList: filteredToDoList, + // }); + // } + + render() { + const { toDoList, theme } = this.state; + + return ( + + <> + +
+ +
+ +
+ +
+
+
+ {toDoList.map((e, index) => ( + + ))} +
+ +
+
+
+ +
+ ); + } +} + +export default Home; diff --git a/src/pages/Home/Home.scss b/src/pages/Home/Home.scss new file mode 100644 index 00000000..e941519a --- /dev/null +++ b/src/pages/Home/Home.scss @@ -0,0 +1,115 @@ +@import url("https://fonts.googleapis.com/css2?family=Dosis&display=swap"); +@import url("https://fonts.googleapis.com/icon?family=Material+Icons"); +@import url("https://use.fontawesome.com/releases/v5.15.3/css/all.css"); + +.material-icons { + font-family: 'Material Icons'; + font-weight: normal; + font-style: normal; + font-size: 24px; /* Preferred icon size */ + display: inline-block; + line-height: 1; + text-transform: none; + letter-spacing: normal; + word-wrap: normal; + white-space: nowrap; + direction: ltr; + + /* Support for all WebKit browsers. */ + -webkit-font-smoothing: antialiased; + /* Support for Safari and Chrome. */ + text-rendering: optimizeLegibility; + + /* Support for Firefox. */ + -moz-osx-font-smoothing: grayscale; + + /* Support for IE. */ + font-feature-settings: 'liga'; +} + +.material-icons.md-dark { color: rgb(0, 0, 0); } +.material-icons.md-dark.md-inactive { color: rgba(0, 0, 0, 0.26); } + +.material-icons.md-light { color: rgba(255, 255, 255, 1); } +.material-icons.md-light.md-inactive { color: rgba(255, 255, 255, 0.3); } + +.material-icons.orange600 { color: #FB8C00; } + +* { + /* outline: solid red 1px; */ + font-family: "Dosis", sans-serif; + font-weight: 300; + margin: 0; + padding: 0; + box-sizing: border-box; +} + +@mixin gridSquare { + display: grid; + grid-template-columns: 1fr; + grid-template-rows: 1fr; +} + +.allWidth { + width: 100vw; +} +.minHeight { + min-height: 100vh; +} + +.gridBody { + @include gridSquare(); + padding-top: 5vh; + z-index: -100; + overflow-x: hidden; +} + +.gridMain { + display: grid; + grid-template-columns: 1fr; + grid-template-rows: 100px 80px; + justify-content: center; + width: 80%; + height: fit-content; + max-width: 600px; + margin: 0 auto; + z-index: 100; + padding: 1%; + overflow-x: hidden; + margin-bottom: 5vh; + section { + height: fit-content; + } +} + +.roundedCorner { + border-radius: 5px; + overflow: hidden; +} + +.shadow { + box-shadow: 5px 10px #888888; +} + +.flowScroll { + overflow-y: scroll; +} + +.flowScroll::-webkit-scrollbar { + background-color: rgb(206, 206, 206); + width: 5px; +} + +.flowScroll::-webkit-scrollbar-thumb { + background-color: rgb(78, 78, 78); + width: 5px; +} + +.margBot { + margin-bottom: 20px; +} + +.btnDarkMode{ + background-color: rgba(222, 184, 135, 0); + border: 0; +} diff --git a/src/pages/Home/index.js b/src/pages/Home/index.js new file mode 100644 index 00000000..ffa79319 --- /dev/null +++ b/src/pages/Home/index.js @@ -0,0 +1 @@ +export { default } from "./Home";