diff --git a/README.md b/README.md index 9d9614c4fd32e65dcbefff34b758d7824b397181..763ec537cf8f086611fc5d3a5a238ee45684a314 100755 --- a/README.md +++ b/README.md @@ -27,6 +27,20 @@ Your app is ready to be deployed! See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. +#### Building for Relative Paths + +By default, the build is produced assuming your app is hosted at the server root.<br> +To override this, specify the homepage in your package.json, for example: + +```js +"homepage": "https://api.portalmec.c3sl.ufpr.br/relativepath" +``` +You will also need to set the relative path in the basename property from BrowserReact in src/App.js: + +```js +<BrowserRouter basename="/relativepath"> +``` + ### `npm run eject` **Note: this is a one-way operation. Once you `eject`, you can’t go back!** diff --git a/package-lock.json b/package-lock.json index 8966c047e184beb875625ece3e4010da442722d9..cb6f20995cd7290456862eed47a271e5bc0d3b0b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1031,16 +1031,6 @@ "regenerator-runtime": "^0.13.4" } }, - "@babel/runtime-corejs3": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.10.2.tgz", - "integrity": "sha512-+a2M/u7r15o3dV1NEizr9bRi+KUVnrs/qYxF0Z06DAPx/4VCWaz1WA7EcbE+uqGgt39lp5akWGmHsTseIkHkHg==", - "dev": true, - "requires": { - "core-js-pure": "^3.0.0", - "regenerator-runtime": "^0.13.4" - } - }, "@babel/template": { "version": "7.10.1", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", @@ -1207,53 +1197,53 @@ "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==" }, "@material-ui/core": { - "version": "4.10.2", - "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.10.2.tgz", - "integrity": "sha512-Uf4iDLi9sW6HKbVQDyDZDr1nMR4RUAE7w/RIIJZGNVZResC0xwmpLRZMtaUdSO43N0R0yJehfxTi4Z461Cd49A==", + "version": "4.11.2", + "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.11.2.tgz", + "integrity": "sha512-/D1+AQQeYX/WhT/FUk78UCRj8ch/RCglsQLYujYTIqPSJlwZHKcvHidNeVhODXeApojeXjkl0tWdk5C9ofwOkQ==", "requires": { "@babel/runtime": "^7.4.4", - "@material-ui/styles": "^4.10.0", - "@material-ui/system": "^4.9.14", + "@material-ui/styles": "^4.11.2", + "@material-ui/system": "^4.11.2", "@material-ui/types": "^5.1.0", - "@material-ui/utils": "^4.10.2", + "@material-ui/utils": "^4.11.2", "@types/react-transition-group": "^4.2.0", "clsx": "^1.0.4", "hoist-non-react-statics": "^3.3.2", "popper.js": "1.16.1-lts", "prop-types": "^15.7.2", - "react-is": "^16.8.0", + "react-is": "^16.8.0 || ^17.0.0", "react-transition-group": "^4.4.0" } }, "@material-ui/icons": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@material-ui/icons/-/icons-4.9.1.tgz", - "integrity": "sha512-GBitL3oBWO0hzBhvA9KxqcowRUsA0qzwKkURyC8nppnC3fw54KPKZ+d4V1Eeg/UnDRSzDaI9nGCdel/eh9AQMg==", + "version": "4.11.2", + "resolved": "https://registry.npmjs.org/@material-ui/icons/-/icons-4.11.2.tgz", + "integrity": "sha512-fQNsKX2TxBmqIGJCSi3tGTO/gZ+eJgWmMJkgDiOfyNaunNaxcklJQFaFogYcFl0qFuaEz1qaXYXboa/bUXVSOQ==", "requires": { "@babel/runtime": "^7.4.4" } }, "@material-ui/lab": { - "version": "4.0.0-alpha.56", - "resolved": "https://registry.npmjs.org/@material-ui/lab/-/lab-4.0.0-alpha.56.tgz", - "integrity": "sha512-xPlkK+z/6y/24ka4gVJgwPfoCF4RCh8dXb1BNE7MtF9bXEBLN/lBxNTK8VAa0qm3V2oinA6xtUIdcRh0aeRtVw==", + "version": "4.0.0-alpha.57", + "resolved": "https://registry.npmjs.org/@material-ui/lab/-/lab-4.0.0-alpha.57.tgz", + "integrity": "sha512-qo/IuIQOmEKtzmRD2E4Aa6DB4A87kmY6h0uYhjUmrrgmEAgbbw9etXpWPVXuRK6AGIQCjFzV6WO2i21m1R4FCw==", "requires": { "@babel/runtime": "^7.4.4", - "@material-ui/utils": "^4.10.2", + "@material-ui/utils": "^4.11.2", "clsx": "^1.0.4", "prop-types": "^15.7.2", - "react-is": "^16.8.0" + "react-is": "^16.8.0 || ^17.0.0" } }, "@material-ui/styles": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.10.0.tgz", - "integrity": "sha512-XPwiVTpd3rlnbfrgtEJ1eJJdFCXZkHxy8TrdieaTvwxNYj42VnnCyFzxYeNW9Lhj4V1oD8YtQ6S5Gie7bZDf7Q==", + "version": "4.11.2", + "resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.11.2.tgz", + "integrity": "sha512-xbItf8zkfD3FuGoD9f2vlcyPf9jTEtj9YTJoNNV+NMWaSAHXgrW6geqRoo/IwBuMjqpwqsZhct13e2nUyU9Ljw==", "requires": { "@babel/runtime": "^7.4.4", "@emotion/hash": "^0.8.0", "@material-ui/types": "^5.1.0", - "@material-ui/utils": "^4.9.6", + "@material-ui/utils": "^4.11.2", "clsx": "^1.0.4", "csstype": "^2.5.2", "hoist-non-react-statics": "^3.3.2", @@ -1269,12 +1259,12 @@ } }, "@material-ui/system": { - "version": "4.9.14", - "resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.9.14.tgz", - "integrity": "sha512-oQbaqfSnNlEkXEziDcJDDIy8pbvwUmZXWNqlmIwDqr/ZdCK8FuV3f4nxikUh7hvClKV2gnQ9djh5CZFTHkZj3w==", + "version": "4.11.2", + "resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.11.2.tgz", + "integrity": "sha512-BELFJEel5E+5DMiZb6XXT3peWRn6UixRvBtKwSxqntmD0+zwbbfCij6jtGwwdJhN1qX/aXrKu10zX31GBaeR7A==", "requires": { "@babel/runtime": "^7.4.4", - "@material-ui/utils": "^4.9.6", + "@material-ui/utils": "^4.11.2", "csstype": "^2.5.2", "prop-types": "^15.7.2" } @@ -1285,13 +1275,13 @@ "integrity": "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A==" }, "@material-ui/utils": { - "version": "4.10.2", - "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.10.2.tgz", - "integrity": "sha512-eg29v74P7W5r6a4tWWDAAfZldXIzfyO1am2fIsC39hdUUHm/33k6pGOKPbgDjg/U/4ifmgAePy/1OjkKN6rFRw==", + "version": "4.11.2", + "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.11.2.tgz", + "integrity": "sha512-Uul8w38u+PICe2Fg2pDKCaIG7kOyhowZ9vjiC1FsVwPABTW8vPPKfF6OvxRq3IiBaI1faOJmgdvMG7rMJARBhA==", "requires": { "@babel/runtime": "^7.4.4", "prop-types": "^15.7.2", - "react-is": "^16.8.0" + "react-is": "^16.8.0 || ^17.0.0" } }, "@mrmlnc/readdir-enhanced": { @@ -1546,71 +1536,85 @@ } }, "@syncfusion/ej2-base": { - "version": "18.2.44", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-base/-/ej2-base-18.2.44.tgz", - "integrity": "sha512-q1aHQr9DXpCQh1iqWsYcIg2eGzsQZXBCu6XvFzMIXp6aWFu6fmW/2WYceg+F5B3cVfo1xCivthdrhlHzxiicGg==", + "version": "18.3.52", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-base/-/ej2-base-18.3.52.tgz", + "integrity": "sha512-g32+xrxnktzz7PhAPlmVhM/Lu4Ad+VuEYDOIw6+/tTHc4FkfNglZxyNmom+9J4bfDkz9AyVv0JmbPyeBxDvETg==", "requires": { - "@syncfusion/ej2-icons": "~18.2.44" + "@syncfusion/ej2-icons": "~18.3.47" } }, "@syncfusion/ej2-buttons": { - "version": "18.2.44", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-buttons/-/ej2-buttons-18.2.44.tgz", - "integrity": "sha512-mKhZ8DJEiRHyGdfQgti72Ul0UmTxVgPYzBnpB80/iif67tWsxLnqVJ53CWgxkXJq0fm6fAneIFSXztMffN2fmw==", + "version": "18.3.47", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-buttons/-/ej2-buttons-18.3.47.tgz", + "integrity": "sha512-V/uzgfaE4f0bfbxKbztIs4Px6cVEVYKKoSMMTWxGFOAD1Ol2Hp055MJzDjQTzmoaq7TlLjyHXGZDsYoKGuguGw==", "requires": { - "@syncfusion/ej2-base": "~18.2.44" + "@syncfusion/ej2-base": "~18.3.47" } }, "@syncfusion/ej2-icons": { - "version": "18.2.44", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-icons/-/ej2-icons-18.2.44.tgz", - "integrity": "sha512-4jOb0RtpTU+s+IXbaQxxcWhFpXXn9aYyakGmrF7A6smbpndM7do28mDybJMFIns/IoRsQokOnrDhqqAIaoDRVQ==" + "version": "18.3.47", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-icons/-/ej2-icons-18.3.47.tgz", + "integrity": "sha512-SSasO60RF0wZuPvz7KUMhvqeZgHCBOrCy2IjPywg3YDOgH244E90NasE0jfGm/1HDdkkVhxWATh8bZh79Ivg/g==" }, "@syncfusion/ej2-inputs": { - "version": "18.2.45", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-inputs/-/ej2-inputs-18.2.45.tgz", - "integrity": "sha512-1lyunOQFT77PXB2gZuJjmgRfyQqFcsTBmj9fGA5PIm5dwipsq4fy6IKOhTMcGCO64q7NZieNXcWOWdSws0lqAQ==", + "version": "18.3.52", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-inputs/-/ej2-inputs-18.3.52.tgz", + "integrity": "sha512-+uN/eGlCsoPISsx/j/HA3MO1TQALDiRVVPe/Cr9kmtxirgIFfkFeY5kOZ3vbYho+5fomSU/4JQX1FMXNV3xQ9A==", "requires": { - "@syncfusion/ej2-base": "~18.2.44", - "@syncfusion/ej2-buttons": "~18.2.44", - "@syncfusion/ej2-popups": "~18.2.44", - "@syncfusion/ej2-splitbuttons": "~18.2.44" + "@syncfusion/ej2-base": "~18.3.52", + "@syncfusion/ej2-buttons": "~18.3.47", + "@syncfusion/ej2-popups": "~18.3.52", + "@syncfusion/ej2-splitbuttons": "~18.3.52" } }, "@syncfusion/ej2-popups": { - "version": "18.2.44", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-popups/-/ej2-popups-18.2.44.tgz", - "integrity": "sha512-+1riSvOH+nhoQtRbgX3Yl2W50Ql5YceiaucyQXNV/WKC9JqHuamRj3PINzd11HjAubvkAMOoYLQQ7B7wP4UmaA==", + "version": "18.3.52", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-popups/-/ej2-popups-18.3.52.tgz", + "integrity": "sha512-5+dAQaUkMYH59Ka82Rg7d4RvjP5dQm5GtZWGbAkN9TpIh4wfDhLTeBOhN87f7n8RsuDA9bBtCRk1YEdBfTpEGw==", "requires": { - "@syncfusion/ej2-base": "~18.2.44", - "@syncfusion/ej2-buttons": "~18.2.44" + "@syncfusion/ej2-base": "~18.3.52", + "@syncfusion/ej2-buttons": "~18.3.47" } }, "@syncfusion/ej2-react-base": { - "version": "18.2.44", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-react-base/-/ej2-react-base-18.2.44.tgz", - "integrity": "sha512-lvIdLzDd2f3V9CEpHBV0FLnJVbb0Nucu7qbdOKQ4dQDRCO0QfM3dqyuC6Wd20R0cyaNGyjucXIpqcueLPtqSvA==", + "version": "18.3.52", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-react-base/-/ej2-react-base-18.3.52.tgz", + "integrity": "sha512-dpNnTPjUUxfkdb0BxeUcBs9DPJ/ngf9ipbd5eLwJPE7XFlrOJ1owEoqDqXIeW9pI+eVu9L3hF25TI287T5b9Sw==", "requires": { - "@syncfusion/ej2-base": "~18.2.44" + "@syncfusion/ej2-base": "~18.3.52" } }, "@syncfusion/ej2-react-inputs": { - "version": "18.2.45", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-react-inputs/-/ej2-react-inputs-18.2.45.tgz", - "integrity": "sha512-lH5e/YNASvqBcXt4ix8YVDv/lWBwM9F7tKiwPXckKnfNX01s2iZg+u+Dw+W3Cj7KIulpg60CHQkFoPtCm2uVkQ==", + "version": "18.3.52", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-react-inputs/-/ej2-react-inputs-18.3.52.tgz", + "integrity": "sha512-qhMFm4uMUKTashS/mX+jbxwWP3dm49V2t6b7XyZ03wAxDk2wUxchqx2AwhSNBBzTWGYXh1ZvWIujjegXIS9kqQ==", "requires": { - "@syncfusion/ej2-base": "~18.2.44", - "@syncfusion/ej2-inputs": "18.2.45", - "@syncfusion/ej2-react-base": "~18.2.44" + "@syncfusion/ej2-base": "~18.3.52", + "@syncfusion/ej2-inputs": "18.3.52", + "@syncfusion/ej2-react-base": "~18.3.52" } }, "@syncfusion/ej2-splitbuttons": { - "version": "18.2.44", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-splitbuttons/-/ej2-splitbuttons-18.2.44.tgz", - "integrity": "sha512-zR/q7OTow5CtV3ZJ2mTHdOhkYr6TeWTg3I4I47lee+6H9EFrryURmi3iyhVHaLQEG/RHW7o53kr9d7qqQwyFyQ==", + "version": "18.3.52", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-splitbuttons/-/ej2-splitbuttons-18.3.52.tgz", + "integrity": "sha512-KgZ4MGpohJzhX5HoRE+unMkeiU0d9tJbNgEhmhLKK4IsXeVx579gc9ftlTtmofjtOU9UyyHvjmYI6y+gobprww==", "requires": { - "@syncfusion/ej2-base": "~18.2.44", - "@syncfusion/ej2-popups": "~18.2.44" + "@syncfusion/ej2-base": "~18.3.52", + "@syncfusion/ej2-popups": "~18.3.52" + } + }, + "@types/cookie": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.3.3.tgz", + "integrity": "sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow==" + }, + "@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/parse-json": { @@ -1629,12 +1633,19 @@ "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==" }, "@types/react": { - "version": "16.9.36", - "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.36.tgz", - "integrity": "sha512-mGgUb/Rk/vGx4NCvquRuSH0GHBQKb1OqpGS9cT9lFxlTLHZgkksgI60TuIxubmn7JuCb+sENHhQciqa0npm0AQ==", + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.0.tgz", + "integrity": "sha512-aj/L7RIMsRlWML3YB6KZiXB3fV2t41+5RBGYF8z+tAKU43Px8C3cYUZsDvf1/+Bm4FK21QWBrDutu8ZJ/70qOw==", "requires": { "@types/prop-types": "*", - "csstype": "^2.2.0" + "csstype": "^3.0.2" + }, + "dependencies": { + "csstype": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.5.tgz", + "integrity": "sha512-uVDi8LpBUKQj6sdxNaTetL6FpeCqTjOvAQuQUa/qAqq8oOd4ivkbhgnqayl0dnPal8Tb/yB1tF+gOvCBiicaiQ==" + } } }, "@types/react-transition-group": { @@ -2298,6 +2309,73 @@ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" }, + "array.prototype.flatmap": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz", + "integrity": "sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1", + "function-bind": "^1.1.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "object-inspect": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + } + } + }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", @@ -2460,11 +2538,18 @@ "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==" }, "axios": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", - "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", "requires": { - "follow-redirects": "1.5.10" + "follow-redirects": "^1.10.0" + }, + "dependencies": { + "follow-redirects": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.1.tgz", + "integrity": "sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg==" + } } }, "axobject-query": { @@ -3176,9 +3261,9 @@ "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" }, "binary-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", - "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==" }, "bluebird": { "version": "3.7.2", @@ -3478,6 +3563,16 @@ "unset-value": "^1.0.0" } }, + "call-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz", + "integrity": "sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.0" + } + }, "call-me-maybe": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", @@ -3542,9 +3637,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001083", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001083.tgz", - "integrity": "sha512-CnYJ27awX4h7yj5glfK7r1TOI13LBytpLzEgfj0s4mY75/F8pnQcYjL+oVpmS38FB59+vU0gscQ9D8tc+lIXvA==" + "version": "1.0.30001179", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001179.tgz", + "integrity": "sha512-blMmO0QQujuUWZKyVrD1msR4WNDAqb/UPO1Sw2WWsQ7deoM5bJiicKnWJ1Y0NS/aGINSnKPIWBMw5luX+NDUCA==" }, "capture-exit": { "version": "1.2.0", @@ -4078,9 +4173,9 @@ } }, "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" }, "cookie-signature": { "version": "1.0.6", @@ -4106,9 +4201,9 @@ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" }, "core-js": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", - "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==" + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.8.0.tgz", + "integrity": "sha512-W2VYNB0nwQQE7tKS7HzXd7r2y/y2SVJl4ga6oH/dnaLFzM0o2lB2P3zCkWj5Wc/zyMYjtgd5Hmhk0ObkQFZOIA==" }, "core-js-compat": { "version": "3.6.5", @@ -4126,12 +4221,6 @@ } } }, - "core-js-pure": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz", - "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==", - "dev": true - }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -5074,12 +5163,19 @@ } }, "dom-helpers": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.4.tgz", - "integrity": "sha512-TjMyeVUvNEnOnhzs6uAn9Ya47GmMo3qq7m+Lr/3ON0Rs5kHvb8I+SQYjLUSYn7qhEm0QjW0yrBkvz9yOrwwz1A==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.0.tgz", + "integrity": "sha512-Ru5o9+V8CpunKnz5LGgWXkmrH/20cGKwcHwS4m73zIvs54CN9epEmT/HLqFJW3kXpakAFkEdzgy1hzlJe3E4OQ==", "requires": { "@babel/runtime": "^7.8.7", - "csstype": "^2.6.7" + "csstype": "^3.0.2" + }, + "dependencies": { + "csstype": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.5.tgz", + "integrity": "sha512-uVDi8LpBUKQj6sdxNaTetL6FpeCqTjOvAQuQUa/qAqq8oOd4ivkbhgnqayl0dnPal8Tb/yB1tF+gOvCBiicaiQ==" + } } }, "dom-serializer": { @@ -5216,9 +5312,9 @@ "integrity": "sha512-smevlzzMNz3vMz6OLeeCq5HRWEj2AcgccNPYnAx4Usx0IOciq9DU36RJcICcS09hXoY7t7deRfVYKD14IrGb9A==" }, "elliptic": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", - "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", + "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", "requires": { "bn.js": "^4.4.0", "brorand": "^1.0.1", @@ -5259,14 +5355,6 @@ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, - "encoding": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", - "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", - "requires": { - "iconv-lite": "~0.4.13" - } - }, "end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -5505,9 +5593,9 @@ } }, "eslint-config-prettier": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz", - "integrity": "sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz", + "integrity": "sha512-a1+kOYLR8wMGustcgAjdydMsQ2A/2ipRPwRKUmfYaSxc9ZPcrku080Ctl6zrZzZNs/U82MjSv+qKREkoq3bJaw==", "dev": true, "requires": { "get-stdin": "^6.0.0" @@ -5706,31 +5794,32 @@ } }, "eslint-plugin-react": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.20.0.tgz", - "integrity": "sha512-rqe1abd0vxMjmbPngo4NaYxTcR3Y4Hrmc/jg4T+sYz63yqlmJRknpEQfmWY+eDWPuMmix6iUIK+mv0zExjeLgA==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.21.5.tgz", + "integrity": "sha512-8MaEggC2et0wSF6bUeywF7qQ46ER81irOdWS4QWxnnlAEsnzeBevk1sWh7fhpCghPpXb+8Ks7hvaft6L/xsR6g==", "dev": true, "requires": { "array-includes": "^3.1.1", + "array.prototype.flatmap": "^1.2.3", "doctrine": "^2.1.0", "has": "^1.0.3", - "jsx-ast-utils": "^2.2.3", - "object.entries": "^1.1.1", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "object.entries": "^1.1.2", "object.fromentries": "^2.0.2", "object.values": "^1.1.1", "prop-types": "^15.7.2", - "resolve": "^1.15.1", - "string.prototype.matchall": "^4.0.2", - "xregexp": "^4.3.0" + "resolve": "^1.18.1", + "string.prototype.matchall": "^4.0.2" }, "dependencies": { - "xregexp": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.3.0.tgz", - "integrity": "sha512-7jXDIFXh5yJ/orPn4SXjuVrWWoi4Cr8jfV1eHv9CixKSbU+jY4mxfrBwAuDvupPNKpMUY+FeIqsVw/JLT9+B8g==", + "resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", "dev": true, "requires": { - "@babel/runtime-corejs3": "^7.8.3" + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" } } } @@ -5941,6 +6030,11 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -7488,6 +7582,17 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" }, + "get-intrinsic": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.1.tgz", + "integrity": "sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, "get-own-enumerable-property-symbols": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", @@ -8333,9 +8438,9 @@ "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" }, "hyphenate-style-name": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.3.tgz", - "integrity": "sha512-EcuixamT82oplpoJ2XU4pDtKGWQ7b00CD9f1ug9IaQ3p1bkHMiKCZ9ut9QDI6qsa6cpUuB+A/I+zLtdNK4n2DQ==" + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz", + "integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==" }, "iconv-lite": { "version": "0.4.24", @@ -8382,11 +8487,11 @@ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" }, "image-to-base64": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/image-to-base64/-/image-to-base64-2.1.0.tgz", - "integrity": "sha512-Qlm5F5EJUkxMEY0uPVwbfEkirv4WowHGRj9LBPYU3bAuFucwhvIJiH9g3aJZ91A89jVq9GzmayiNvE2sEjQ9YQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/image-to-base64/-/image-to-base64-2.1.1.tgz", + "integrity": "sha512-G8EZaxl8dmYUXCmaC/1W4oqwj+yiY+qhF9A81TbdOtxdK9BAN3oV440Jofexp4J2oRsbHIUJtl3rlDqdjmiZOQ==", "requires": { - "node-fetch": "^1.7.3" + "node-fetch": "^2.6.0" } }, "immer": { @@ -8450,11 +8555,24 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" }, + "indefinite-observable": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/indefinite-observable/-/indefinite-observable-2.0.1.tgz", + "integrity": "sha512-G8vgmork+6H9S8lUAg1gtXEj2JxIQTo0g2PbFiYOdjkziSI0F7UYBiVwhZRuixhBCNGczAls34+5HJPyZysvxQ==", + "requires": { + "symbol-observable": "1.2.0" + } + }, "indexes-of": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=" }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -8470,9 +8588,9 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "inquirer": { "version": "6.5.2", @@ -8626,6 +8744,15 @@ "rgba-regex": "^1.0.0" } }, + "is-core-module": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", @@ -8712,6 +8839,12 @@ "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz", "integrity": "sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU=" }, + "is-negative-zero": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.0.tgz", + "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=", + "dev": true + }, "is-number": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", @@ -9634,81 +9767,89 @@ } }, "jss": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/jss/-/jss-10.3.0.tgz", - "integrity": "sha512-B5sTRW9B6uHaUVzSo9YiMEOEp3UX8lWevU0Fsv+xtRnsShmgCfIYX44bTH8bPJe6LQKqEXku3ulKuHLbxBS97Q==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/jss/-/jss-10.5.0.tgz", + "integrity": "sha512-B6151NvG+thUg3murLNHRPLxTLwQ13ep4SH5brj4d8qKtogOx/jupnpfkPGSHPqvcwKJaCLctpj2lEk+5yGwMw==", "requires": { "@babel/runtime": "^7.3.1", - "csstype": "^2.6.5", + "csstype": "^3.0.2", + "indefinite-observable": "^2.0.1", "is-in-browser": "^1.1.3", "tiny-warning": "^1.0.2" + }, + "dependencies": { + "csstype": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.5.tgz", + "integrity": "sha512-uVDi8LpBUKQj6sdxNaTetL6FpeCqTjOvAQuQUa/qAqq8oOd4ivkbhgnqayl0dnPal8Tb/yB1tF+gOvCBiicaiQ==" + } } }, "jss-plugin-camel-case": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.3.0.tgz", - "integrity": "sha512-tadWRi/SLWqLK3EUZEdDNJL71F3ST93Zrl9JYMjV0QDqKPAl0Liue81q7m/nFUpnSTXczbKDy4wq8rI8o7WFqA==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.5.0.tgz", + "integrity": "sha512-GSjPL0adGAkuoqeYiXTgO7PlIrmjv5v8lA6TTBdfxbNYpxADOdGKJgIEkffhlyuIZHlPuuiFYTwUreLUmSn7rg==", "requires": { "@babel/runtime": "^7.3.1", "hyphenate-style-name": "^1.0.3", - "jss": "^10.3.0" + "jss": "10.5.0" } }, "jss-plugin-default-unit": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.3.0.tgz", - "integrity": "sha512-tT5KkIXAsZOSS9WDSe8m8lEHIjoEOj4Pr0WrG0WZZsMXZ1mVLFCSsD2jdWarQWDaRNyMj/I4d7czRRObhOxSuw==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.5.0.tgz", + "integrity": "sha512-rsbTtZGCMrbcb9beiDd+TwL991NGmsAgVYH0hATrYJtue9e+LH/Gn4yFD1ENwE+3JzF3A+rPnM2JuD9L/SIIWw==", "requires": { "@babel/runtime": "^7.3.1", - "jss": "^10.3.0" + "jss": "10.5.0" } }, "jss-plugin-global": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.3.0.tgz", - "integrity": "sha512-etYTG/y3qIR/vxZnKY+J3wXwObyBDNhBiB3l/EW9/pE3WHE//BZdK8LFvQcrCO48sZW1Z6paHo6klxUPP7WbzA==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.5.0.tgz", + "integrity": "sha512-FZd9+JE/3D7HMefEG54fEC0XiQ9rhGtDHAT/ols24y8sKQ1D5KIw6OyXEmIdKFmACgxZV2ARQ5pAUypxkk2IFQ==", "requires": { "@babel/runtime": "^7.3.1", - "jss": "^10.3.0" + "jss": "10.5.0" } }, "jss-plugin-nested": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.3.0.tgz", - "integrity": "sha512-qWiEkoXNEkkZ+FZrWmUGpf+zBsnEOmKXhkjNX85/ZfWhH9dfGxUCKuJFuOWFM+rjQfxV4csfesq4hY0jk8Qt0w==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.5.0.tgz", + "integrity": "sha512-ejPlCLNlEGgx8jmMiDk/zarsCZk+DV0YqXfddpgzbO9Toamo0HweCFuwJ3ZO40UFOfqKwfpKMVH/3HUXgxkTMg==", "requires": { "@babel/runtime": "^7.3.1", - "jss": "^10.3.0", + "jss": "10.5.0", "tiny-warning": "^1.0.2" } }, "jss-plugin-props-sort": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.3.0.tgz", - "integrity": "sha512-boetORqL/lfd7BWeFD3K+IyPqyIC+l3CRrdZr+NPq7Noqp+xyg/0MR7QisgzpxCEulk+j2CRcEUoZsvgPC4nTg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.5.0.tgz", + "integrity": "sha512-kTLRvrOetFKz5vM88FAhLNeJIxfjhCepnvq65G7xsAQ/Wgy7HwO1BS/2wE5mx8iLaAWC6Rj5h16mhMk9sKdZxg==", "requires": { "@babel/runtime": "^7.3.1", - "jss": "^10.3.0" + "jss": "10.5.0" } }, "jss-plugin-rule-value-function": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.3.0.tgz", - "integrity": "sha512-7WiMrKIHH3rwxTuJki9+7nY11r1UXqaUZRhHvqTD4/ZE+SVhvtD5Tx21ivNxotwUSleucA/8boX+NF21oXzr5Q==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.5.0.tgz", + "integrity": "sha512-jXINGr8BSsB13JVuK274oEtk0LoooYSJqTBCGeBu2cG/VJ3+4FPs1gwLgsq24xTgKshtZ+WEQMVL34OprLidRA==", "requires": { "@babel/runtime": "^7.3.1", - "jss": "^10.3.0", + "jss": "10.5.0", "tiny-warning": "^1.0.2" } }, "jss-plugin-vendor-prefixer": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.3.0.tgz", - "integrity": "sha512-sZQbrcZyP5V0ADjCLwUA1spVWoaZvM7XZ+2fSeieZFBj31cRsnV7X70FFDerMHeiHAXKWzYek+67nMDjhrZAVQ==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.5.0.tgz", + "integrity": "sha512-rux3gmfwDdOKCLDx0IQjTwTm03IfBa+Rm/hs747cOw5Q7O3RaTUIMPKjtVfc31Xr/XI9Abz2XEupk1/oMQ7zRA==", "requires": { "@babel/runtime": "^7.3.1", "css-vendor": "^2.0.8", - "jss": "^10.3.0" + "jss": "10.5.0" } }, "jsx-ast-utils": { @@ -9914,9 +10055,9 @@ } }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" }, "lodash._reinterpolate": { "version": "3.0.0", @@ -10382,9 +10523,9 @@ } }, "moment": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.26.0.tgz", - "integrity": "sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw==" + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" }, "moo-server": { "version": "1.3.0", @@ -10498,18 +10639,9 @@ } }, "node-fetch": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", - "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", - "requires": { - "encoding": "^0.1.11", - "is-stream": "^1.0.1" - } - }, - "node-forge": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz", - "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==" + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" }, "node-int64": { "version": "0.4.0", @@ -10733,14 +10865,70 @@ } }, "object.entries": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.2.tgz", - "integrity": "sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.3.tgz", + "integrity": "sha512-ym7h7OZebNS96hn5IJeyUmaWhaSM4SVtAPPfNLQEI2MYWCO2egsITb9nab2+i/Pwibx+R0mtn+ltKJXRSeTMGg==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", + "es-abstract": "^1.18.0-next.1", "has": "^1.0.3" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "object-inspect": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + } } }, "object.fromentries": { @@ -13830,9 +14018,9 @@ } }, "react": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react/-/react-16.13.1.tgz", - "integrity": "sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==", + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", + "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -13858,6 +14046,16 @@ } } }, + "react-cookie": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/react-cookie/-/react-cookie-4.0.3.tgz", + "integrity": "sha512-cmi6IpdVgTSvjqssqIEvo779Gfqc4uPGHRrKMEdHcqkmGtPmxolGfsyKj95bhdLEKqMdbX8MLBCwezlnhkHK0g==", + "requires": { + "@types/hoist-non-react-statics": "^3.0.1", + "hoist-non-react-statics": "^3.0.0", + "universal-cookie": "^4.0.0" + } + }, "react-dev-utils": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-8.0.0.tgz", @@ -14005,9 +14203,9 @@ } }, "react-dom": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.1.tgz", - "integrity": "sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag==", + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", + "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -14016,13 +14214,22 @@ } }, "react-dropdown": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/react-dropdown/-/react-dropdown-1.7.0.tgz", - "integrity": "sha512-zFZ73pgLA32hArpE4j/7DtOEhOMg240XG5QvbAb0/VinGekkHDVIakMyAFUKC5jDz8jqXEltgriqFW9R5iCtPQ==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/react-dropdown/-/react-dropdown-1.9.0.tgz", + "integrity": "sha512-BDApCUhs0qHqnFW3b54SuqI200FOOsmiy0dejdmtdTn/MMY11jcou3CLX1oT2Qa1PdN7viTyAGT8YCpK5qb9xg==", "requires": { "classnames": "^2.2.3" } }, + "react-dropdown-select": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/react-dropdown-select/-/react-dropdown-select-4.7.1.tgz", + "integrity": "sha512-yoF39vFN+F2TaRK1EXnhiz+8jyv40E7+MRUD/X/UsMr2dnYFWoFMMrTIVXcjVnDCFlU+yAvZYRqb+8b60bUuyw==", + "requires": { + "@emotion/core": "^10.0.27", + "@emotion/styled": "^10.0.27" + } + }, "react-easy-crop": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/react-easy-crop/-/react-easy-crop-2.1.2.tgz", @@ -14034,9 +14241,9 @@ } }, "react-easy-swipe": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/react-easy-swipe/-/react-easy-swipe-0.0.18.tgz", - "integrity": "sha512-IddCZANbT0qVbGFEihfWOkZb/rFpeA3VV87SNOOqPzmSZ93G0nDSyHD28zuGhYJilwEP33MqYv/dwo+zaZha3Q==", + "version": "0.0.21", + "resolved": "https://registry.npmjs.org/react-easy-swipe/-/react-easy-swipe-0.0.21.tgz", + "integrity": "sha512-OeR2jAxdoqUMHIn/nS9fgreI5hSpgGoL5ezdal4+oO7YSSgJR8ga+PkYGJrSrJ9MKlPcQjMQXnketrD7WNmNsg==", "requires": { "prop-types": "^15.5.8" } @@ -14078,9 +14285,9 @@ } }, "react-google-login": { - "version": "5.1.20", - "resolved": "https://registry.npmjs.org/react-google-login/-/react-google-login-5.1.20.tgz", - "integrity": "sha512-/5vDx8Hy7Wo1fO1VC/0e5D6/ZGWgIgvcscI8mYZUQ653QOFf0c4GhTnKkebX5uE7m5rAB/2bzzZIUlIesGqWig==", + "version": "5.1.25", + "resolved": "https://registry.npmjs.org/react-google-login/-/react-google-login-5.1.25.tgz", + "integrity": "sha512-N7SZkjTEX9NsC3hywXs68SPJWAHo6M19Bs1OIFPirG0yomGF7KnbKjSqoiIfxz1V7fKAt8bkfBAzogwnGWYTeQ==", "requires": { "@types/react": "*", "prop-types": "^15.6.0" @@ -14095,20 +14302,20 @@ } }, "react-icons": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-3.10.0.tgz", - "integrity": "sha512-WsQ5n1JToG9VixWilSo1bHv842Cj5aZqTGiS3Ud47myF6aK7S/IUY2+dHcBdmkQcCFRuHsJ9OMUI0kTDfjyZXQ==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-3.11.0.tgz", + "integrity": "sha512-JRgiI/vdF6uyBgyZhVyYJUZAop95Sy4XDe/jmT3R/bKliFWpO/uZBwvSjWEdxwzec7SYbEPNPck0Kff2tUGM2Q==", "requires": { "camelcase": "^5.0.0" } }, "react-image-crop": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/react-image-crop/-/react-image-crop-8.6.4.tgz", - "integrity": "sha512-5buyhUg9slzW+QGvN2dbpGSI1VqPxxmfEwe19TZXUB7LjW5+ljZOnrTSsteIzeBqmz6ngVucc8l+OrwgcDOSNg==", + "version": "8.6.6", + "resolved": "https://registry.npmjs.org/react-image-crop/-/react-image-crop-8.6.6.tgz", + "integrity": "sha512-2iQHKp12dYb6Fu2iN/Mg19BeLMgrbdOuKkU9k0RH7CHX6ZZylOlhfCM3/RsECbKnjGJRtGpXniGF+/i9CGis1A==", "requires": { - "clsx": "^1.0.4", - "core-js": "^3.4.2", + "clsx": "^1.1.1", + "core-js": "^3.6.5", "prop-types": "^15.7.2" } }, @@ -14137,13 +14344,13 @@ "integrity": "sha512-IyanbozsYCuHvTYDuskZTIEcRAMG/sdvAu5b29iQWoC8Kd3Zk9WGCv2oNxh6RfGHvSvgHAyaLjmC6ei/yMsJ7g==" }, "react-responsive-carousel": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/react-responsive-carousel/-/react-responsive-carousel-3.2.7.tgz", - "integrity": "sha512-uqGCnoZukU+U1relhTNe8eVX/hMT5ELh1uxHCOxR6cH+A67eG2aX68e1pJnohWqXqPj/u+Pupt1q5j8LGhDabA==", + "version": "3.2.10", + "resolved": "https://registry.npmjs.org/react-responsive-carousel/-/react-responsive-carousel-3.2.10.tgz", + "integrity": "sha512-O8MV2LoR07BttvWaXesyWkE6s8xRW6p6HiMkelZ3TuPYQwKnlw+fYtZN+bQ3/1jg0D5JQGATY4Hnw/4WEXHnag==", "requires": { "classnames": "^2.2.5", "prop-types": "^15.5.8", - "react-easy-swipe": "^0.0.18" + "react-easy-swipe": "^0.0.21" } }, "react-router": { @@ -14177,6 +14384,14 @@ "tiny-warning": "^1.0.0" } }, + "react-router-hash-link": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/react-router-hash-link/-/react-router-hash-link-2.3.1.tgz", + "integrity": "sha512-QVYLaBLmRGovSbQv4Tbjqnl9JMEQ8c5rWebkZU16ovgZtpmNIf2znGj3uWaKkAL7lhuYBPcC3OAfhw7lk/QwNw==", + "requires": { + "prop-types": "^15.7.2" + } + }, "react-scripts": { "version": "2.1.8", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-2.1.8.tgz", @@ -14252,6 +14467,26 @@ "requires": { "path-parse": "^1.0.6" } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "terser-webpack-plugin": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.2.2.tgz", + "integrity": "sha512-1DMkTk286BzmfylAvLXwpJrI7dWa5BnFmscV/2dCr8+c56egFcbaeFAl7+sujAjdmpLam21XRdhA4oifLyiWWg==", + "requires": { + "cacache": "^11.0.2", + "find-cache-dir": "^2.0.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^1.4.0", + "source-map": "^0.6.1", + "terser": "^3.16.1", + "webpack-sources": "^1.1.0", + "worker-farm": "^1.5.2" + } } } }, @@ -15343,11 +15578,18 @@ "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=" }, "selfsigned": { - "version": "1.10.7", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.7.tgz", - "integrity": "sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA==", + "version": "1.10.8", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.8.tgz", + "integrity": "sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w==", "requires": { - "node-forge": "0.9.0" + "node-forge": "^0.10.0" + }, + "dependencies": { + "node-forge": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==" + } } }, "semver": { @@ -15564,13 +15806,68 @@ "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==" }, "side-channel": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.2.tgz", - "integrity": "sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.3.tgz", + "integrity": "sha512-A6+ByhlLkksFoUepsGxfj5x1gTSrs+OydsRptUxeNCabQpCFUvcwIczgOigI8vhY/OJCnPnyE9rGiwgvr9cS1g==", "dev": true, "requires": { - "es-abstract": "^1.17.0-next.1", - "object-inspect": "^1.7.0" + "es-abstract": "^1.18.0-next.0", + "object-inspect": "^1.8.0" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "object-inspect": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + } } }, "signal-exit": { @@ -16094,17 +16391,73 @@ } }, "string.prototype.matchall": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.2.tgz", - "integrity": "sha512-N/jp6O5fMf9os0JU3E72Qhf590RSRZU/ungsL/qJUYVTNv7hTG0P/dbPjxINVN9jpscu3nzYwKESU3P3RY5tOg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.3.tgz", + "integrity": "sha512-OBxYDA2ifZQ2e13cP82dWFMaCV9CGF8GzmN4fljBVw5O5wep0lu4gacm1OL6MjROoUnB8VbkWRThqkV2YFLNxw==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0", + "es-abstract": "^1.18.0-next.1", "has-symbols": "^1.0.1", "internal-slot": "^1.0.2", "regexp.prototype.flags": "^1.3.0", - "side-channel": "^1.0.2" + "side-channel": "^1.0.3" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "object-inspect": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + } } }, "string.prototype.trimend": { @@ -16313,6 +16666,11 @@ } } }, + "symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" + }, "symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -16386,24 +16744,79 @@ } }, "terser-webpack-plugin": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.2.2.tgz", - "integrity": "sha512-1DMkTk286BzmfylAvLXwpJrI7dWa5BnFmscV/2dCr8+c56egFcbaeFAl7+sujAjdmpLam21XRdhA4oifLyiWWg==", + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", + "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", "requires": { - "cacache": "^11.0.2", - "find-cache-dir": "^2.0.0", + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", "schema-utils": "^1.0.0", - "serialize-javascript": "^1.4.0", + "serialize-javascript": "^4.0.0", "source-map": "^0.6.1", - "terser": "^3.16.1", - "webpack-sources": "^1.1.0", - "worker-farm": "^1.5.2" + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" }, "dependencies": { + "cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "requires": { + "randombytes": "^2.1.0" + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "terser": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", + "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + } + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" } } }, @@ -16667,9 +17080,9 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "typescript": { - "version": "3.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.5.tgz", - "integrity": "sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ==" + "version": "3.9.7", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz", + "integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==" }, "uglify-js": { "version": "1.3.5", @@ -16737,6 +17150,15 @@ "imurmurhash": "^0.1.4" } }, + "universal-cookie": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/universal-cookie/-/universal-cookie-4.0.4.tgz", + "integrity": "sha512-lbRVHoOMtItjWbM7TwDLdl8wug7izB0tq3/YVKhT/ahB4VDvWMyvnADfnJI8y6fSvsjh51Ix7lTGC6Tn4rMPhw==", + "requires": { + "@types/cookie": "^0.3.3", + "cookie": "^0.4.0" + } + }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -16851,6 +17273,11 @@ "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" }, + "use-cookie-state": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/use-cookie-state/-/use-cookie-state-1.0.0.tgz", + "integrity": "sha512-I76Rg8olmAqUQL3mWnHxfSWaXNhc7UEfjX2frRrFnaCWjoyTxNggL5rE5a4LY1bnhEFOCc2BT3q0ctG6tizz4g==" + }, "util": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", diff --git a/package.json b/package.json index 717525b3312961c92fe54772ca13bb3d873f9a20..22c837b427c03bfe990bf426d6fcddca56b69ad9 100644 --- a/package.json +++ b/package.json @@ -3,41 +3,46 @@ "version": "0.1.0", "private": true, "dependencies": { - "@material-ui/core": "^4.9.0", - "@material-ui/icons": "^4.5.1", - "@material-ui/lab": "^4.0.0-alpha.40", - "@material-ui/styles": "^4.9.0", - "@syncfusion/ej2-react-inputs": "^18.2.45", - "axios": "^0.19.2", + "@material-ui/core": "^4.11.2", + "@material-ui/icons": "^4.11.2", + "@material-ui/lab": "^4.0.0-alpha.57", + "@material-ui/styles": "^4.11.2", + "@syncfusion/ej2-react-inputs": "^18.3.52", + "axios": "^0.21.1", "base64-img": "^1.0.4", - "binary-extensions": "^2.0.0", + "binary-extensions": "^2.1.0", "build": "^0.1.4", + "cookie": "^0.4.1", "fine-uploader": "^5.16.2", - "image-to-base64": "^2.0.1", + "image-to-base64": "^2.1.1", "material-design-icons": "^3.0.1", - "moment": "^2.24.0", - "react": "^16.12.0", - "react-dom": "^16.12.0", - "react-dropdown": "^1.7.0", + "moment": "^2.29.1", + "react": "^16.14.0", + "react-cookie": "^4.0.3", + "react-dom": "^16.14.0", + "react-dropdown": "^1.9.0", + "react-dropdown-select": "^4.7.1", "react-easy-crop": "^2.1.0", "react-fine-uploader": "^1.1.1", - "react-google-login": "^5.0.7", + "react-google-login": "^5.1.25", "react-grid-system": "^4.4.11", - "react-icons": "^3.8.0", - "react-image-crop": "^8.6.2", + "react-icons": "^3.11.0", + "react-image-crop": "^8.6.6", "react-input-mask": "^2.0.4", "react-recaptcha": "^2.3.10", - "react-responsive-carousel": "^3.1.51", + "react-responsive-carousel": "^3.2.10", "react-router-dom": "^5.1.2", + "react-router-hash-link": "^2.3.1", "react-scripts": "^2.1.8", "react-star-ratings": "^2.3.0", "styled-components": "^4.4.1", - "typescript": "^3.7.5" + "typescript": "^3.9.7", + "use-cookie-state": "^1.0.0" }, "devDependencies": { - "eslint-config-prettier": "^6.10.0", + "eslint-config-prettier": "^6.15.0", "eslint-plugin-prettier": "^3.1.2", - "eslint-plugin-react": "^7.18.0", + "eslint-plugin-react": "^7.21.5", "eslint-plugin-react-hooks": "^1.6.1", "prettier": "1.18.2" }, diff --git a/public/img/colecoes/boas1.jpg b/public/img/colecoes/boas1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..89c06d3598dd34f2d21ce19d8ac6c8a426c6556b Binary files /dev/null and b/public/img/colecoes/boas1.jpg differ diff --git a/public/img/colecoes/boas10.jpg b/public/img/colecoes/boas10.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7d5f49123f47e3370ed66a56652b1c33cf7d15c1 Binary files /dev/null and b/public/img/colecoes/boas10.jpg differ diff --git a/public/img/colecoes/boas11.jpg b/public/img/colecoes/boas11.jpg new file mode 100644 index 0000000000000000000000000000000000000000..add0e181dc7374c5b52cf0c7187585b3c301579f Binary files /dev/null and b/public/img/colecoes/boas11.jpg differ diff --git a/public/img/colecoes/boas12.jpg b/public/img/colecoes/boas12.jpg new file mode 100644 index 0000000000000000000000000000000000000000..379fee28bc3b47adac3ab3e8f84d9eaadd50aa92 Binary files /dev/null and b/public/img/colecoes/boas12.jpg differ diff --git a/public/img/colecoes/boas13.jpg b/public/img/colecoes/boas13.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ec60e3ac77eef53d1af47ccf6fcab272001fea9c Binary files /dev/null and b/public/img/colecoes/boas13.jpg differ diff --git a/public/img/colecoes/boas14.jpg b/public/img/colecoes/boas14.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f2feadea1575c5a22fbef1fcbf6c8450c06c132f Binary files /dev/null and b/public/img/colecoes/boas14.jpg differ diff --git a/public/img/colecoes/boas15.jpg b/public/img/colecoes/boas15.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5447d04e02a125be88e306759a84b79edbbd825e Binary files /dev/null and b/public/img/colecoes/boas15.jpg differ diff --git a/public/img/colecoes/boas16.jpg b/public/img/colecoes/boas16.jpg new file mode 100644 index 0000000000000000000000000000000000000000..18df94dcbd89a54a8eb6d96b6e4a13b37db10c12 Binary files /dev/null and b/public/img/colecoes/boas16.jpg differ diff --git a/public/img/colecoes/boas17.jpg b/public/img/colecoes/boas17.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0b0ae6cceee009eb64077264ca5b8e464575fc96 Binary files /dev/null and b/public/img/colecoes/boas17.jpg differ diff --git a/public/img/colecoes/boas18.jpg b/public/img/colecoes/boas18.jpg new file mode 100644 index 0000000000000000000000000000000000000000..35d6d721eafc0ad280753f0d2ac9f9373c4076e8 Binary files /dev/null and b/public/img/colecoes/boas18.jpg differ diff --git a/public/img/colecoes/boas19.jpg b/public/img/colecoes/boas19.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6e8783f1e1382e72aeeb5fdbc794acab61510870 Binary files /dev/null and b/public/img/colecoes/boas19.jpg differ diff --git a/public/img/colecoes/boas2.jpg b/public/img/colecoes/boas2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..364ce18f3fa7e3927d3ad6168fc084277ce87617 Binary files /dev/null and b/public/img/colecoes/boas2.jpg differ diff --git a/public/img/colecoes/boas20.jpg b/public/img/colecoes/boas20.jpg new file mode 100644 index 0000000000000000000000000000000000000000..69bf30ed53f4a86fe66730f1e727e10df5caf8dc Binary files /dev/null and b/public/img/colecoes/boas20.jpg differ diff --git a/public/img/colecoes/boas21.jpg b/public/img/colecoes/boas21.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ff7155d9fa66e4c225e4802242d5181726c8ffdd Binary files /dev/null and b/public/img/colecoes/boas21.jpg differ diff --git a/public/img/colecoes/boas22.jpg b/public/img/colecoes/boas22.jpg new file mode 100644 index 0000000000000000000000000000000000000000..97663c7967d3c811d28b73eb0e2d4115b1a64156 Binary files /dev/null and b/public/img/colecoes/boas22.jpg differ diff --git a/public/img/colecoes/boas23.jpg b/public/img/colecoes/boas23.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b20d36abfd6fe332eaa521de4a99a048eb317fba Binary files /dev/null and b/public/img/colecoes/boas23.jpg differ diff --git a/public/img/colecoes/boas24.jpg b/public/img/colecoes/boas24.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d97f51fd06d7a8236c5c55ce676d2da6aa8b441b Binary files /dev/null and b/public/img/colecoes/boas24.jpg differ diff --git a/public/img/colecoes/boas25.jpg b/public/img/colecoes/boas25.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e32b78d0589fb0c19dc3afea6d7a1c826d543c41 Binary files /dev/null and b/public/img/colecoes/boas25.jpg differ diff --git a/public/img/colecoes/boas26.jpg b/public/img/colecoes/boas26.jpg new file mode 100644 index 0000000000000000000000000000000000000000..364cb547db9b080c99be41c11ed08a1ed6503b19 Binary files /dev/null and b/public/img/colecoes/boas26.jpg differ diff --git a/public/img/colecoes/boas27.jpg b/public/img/colecoes/boas27.jpg new file mode 100644 index 0000000000000000000000000000000000000000..831eecf6deac39d3ef638080844cd4cf360cdb83 Binary files /dev/null and b/public/img/colecoes/boas27.jpg differ diff --git a/public/img/colecoes/boas28.jpg b/public/img/colecoes/boas28.jpg new file mode 100644 index 0000000000000000000000000000000000000000..71cd647c7542a675bd9b524ac9558e62e0621bec Binary files /dev/null and b/public/img/colecoes/boas28.jpg differ diff --git a/public/img/colecoes/boas29.jpg b/public/img/colecoes/boas29.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a02eb7819d559a84b7dd112a27b3426ba79e239b Binary files /dev/null and b/public/img/colecoes/boas29.jpg differ diff --git a/public/img/colecoes/boas3.jpg b/public/img/colecoes/boas3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3d474704ea5d17c5e564e6712fa9cab9773c8bfb Binary files /dev/null and b/public/img/colecoes/boas3.jpg differ diff --git a/public/img/colecoes/boas30.jpg b/public/img/colecoes/boas30.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e4a244a311018c315a7f51db2cd339117be1afb3 Binary files /dev/null and b/public/img/colecoes/boas30.jpg differ diff --git a/public/img/colecoes/boas4.jpg b/public/img/colecoes/boas4.jpg new file mode 100644 index 0000000000000000000000000000000000000000..94dee43db37bc68adb4054c6ff52b08da442ff77 Binary files /dev/null and b/public/img/colecoes/boas4.jpg differ diff --git a/public/img/colecoes/boas5.jpg b/public/img/colecoes/boas5.jpg new file mode 100644 index 0000000000000000000000000000000000000000..dd677614d95233713ecd33938d2453f0c7ce1c1a Binary files /dev/null and b/public/img/colecoes/boas5.jpg differ diff --git a/public/img/colecoes/boas6.jpg b/public/img/colecoes/boas6.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2a03d6d7560d0f0bab1e3eb88df16e3f53a12440 Binary files /dev/null and b/public/img/colecoes/boas6.jpg differ diff --git a/public/img/colecoes/boas7.jpg b/public/img/colecoes/boas7.jpg new file mode 100644 index 0000000000000000000000000000000000000000..93e7f88846b74df326ce0b41145f625df59d50b8 Binary files /dev/null and b/public/img/colecoes/boas7.jpg differ diff --git a/public/img/colecoes/boas8.jpg b/public/img/colecoes/boas8.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9aeeea55f52049b8be2851c13a4d2053a4e1fd35 Binary files /dev/null and b/public/img/colecoes/boas8.jpg differ diff --git a/public/img/colecoes/boas9.jpg b/public/img/colecoes/boas9.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a05f749f737eff3ce2bc748bd0b9fae54615ae95 Binary files /dev/null and b/public/img/colecoes/boas9.jpg differ diff --git a/public/img/colecoes/ecd.png b/public/img/colecoes/ecd.png new file mode 100644 index 0000000000000000000000000000000000000000..46b6ccc37527909668b77dbcb1cfcd2b9eedf7c1 Binary files /dev/null and b/public/img/colecoes/ecd.png differ diff --git a/public/img/colecoes/ecd1.jpg b/public/img/colecoes/ecd1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e103672c263637051bcb6930efef7b53e98668b9 Binary files /dev/null and b/public/img/colecoes/ecd1.jpg differ diff --git a/public/img/colecoes/ecd10.jpg b/public/img/colecoes/ecd10.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ed0196897190588d7bb0e97fefeaeb3cc81cceeb Binary files /dev/null and b/public/img/colecoes/ecd10.jpg differ diff --git a/public/img/colecoes/ecd11.jpg b/public/img/colecoes/ecd11.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e165deb12e3dad61f21cdface98b6b0096c0a8ab Binary files /dev/null and b/public/img/colecoes/ecd11.jpg differ diff --git a/public/img/colecoes/ecd12.jpg b/public/img/colecoes/ecd12.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a4d7568e7cd7201666425f8bc057d7bcc0684554 Binary files /dev/null and b/public/img/colecoes/ecd12.jpg differ diff --git a/public/img/colecoes/ecd13.jpg b/public/img/colecoes/ecd13.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1e005c1360e9dc23de27d184332bccdf03acaa35 Binary files /dev/null and b/public/img/colecoes/ecd13.jpg differ diff --git a/public/img/colecoes/ecd14.jpg b/public/img/colecoes/ecd14.jpg new file mode 100644 index 0000000000000000000000000000000000000000..61a6bd2259d39edcfd69e2df580a09c7dd865ef8 Binary files /dev/null and b/public/img/colecoes/ecd14.jpg differ diff --git a/public/img/colecoes/ecd15.jpg b/public/img/colecoes/ecd15.jpg new file mode 100644 index 0000000000000000000000000000000000000000..407e8b480d2cca92bab9598ab00f0687ee33ece2 Binary files /dev/null and b/public/img/colecoes/ecd15.jpg differ diff --git a/public/img/colecoes/ecd16.jpg b/public/img/colecoes/ecd16.jpg new file mode 100644 index 0000000000000000000000000000000000000000..02a2bb8d2198b72cb35b4317972b52896207d46e Binary files /dev/null and b/public/img/colecoes/ecd16.jpg differ diff --git a/public/img/colecoes/ecd17.jpg b/public/img/colecoes/ecd17.jpg new file mode 100644 index 0000000000000000000000000000000000000000..295b23fa7f2eebfa1bc1e9c8801fe04e9618db99 Binary files /dev/null and b/public/img/colecoes/ecd17.jpg differ diff --git a/public/img/colecoes/ecd18.jpg b/public/img/colecoes/ecd18.jpg new file mode 100644 index 0000000000000000000000000000000000000000..74f42fc6474d233eb86190c2dda5064b7b8a3325 Binary files /dev/null and b/public/img/colecoes/ecd18.jpg differ diff --git a/public/img/colecoes/ecd19.jpg b/public/img/colecoes/ecd19.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c937fea6045e070600bc856034eb6b54c9e8972a Binary files /dev/null and b/public/img/colecoes/ecd19.jpg differ diff --git a/public/img/colecoes/ecd2.jpg b/public/img/colecoes/ecd2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..359b5317651fcfbc2400fb9e3f4274d301072f52 Binary files /dev/null and b/public/img/colecoes/ecd2.jpg differ diff --git a/public/img/colecoes/ecd20.jpg b/public/img/colecoes/ecd20.jpg new file mode 100644 index 0000000000000000000000000000000000000000..90b325c3c532adeaa53d3cb39a0ef818eb9904ad Binary files /dev/null and b/public/img/colecoes/ecd20.jpg differ diff --git a/public/img/colecoes/ecd21.jpg b/public/img/colecoes/ecd21.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7d047527a9962713b3042bfbee79dab6cacf7a39 Binary files /dev/null and b/public/img/colecoes/ecd21.jpg differ diff --git a/public/img/colecoes/ecd22.jpg b/public/img/colecoes/ecd22.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6c5fc0e5352afb5dbf5503ffd86ec8905a0c2111 Binary files /dev/null and b/public/img/colecoes/ecd22.jpg differ diff --git a/public/img/colecoes/ecd23.jpg b/public/img/colecoes/ecd23.jpg new file mode 100644 index 0000000000000000000000000000000000000000..94c4267fb301752c0c3fa614795f7b12de129d9a Binary files /dev/null and b/public/img/colecoes/ecd23.jpg differ diff --git a/public/img/colecoes/ecd24.jpg b/public/img/colecoes/ecd24.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0f4897d4714d217a43eb120642031bc506d3d08e Binary files /dev/null and b/public/img/colecoes/ecd24.jpg differ diff --git a/public/img/colecoes/ecd25.jpg b/public/img/colecoes/ecd25.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f35f757120890d8086fc646f91f7acf74918ded5 Binary files /dev/null and b/public/img/colecoes/ecd25.jpg differ diff --git a/public/img/colecoes/ecd26.jpg b/public/img/colecoes/ecd26.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a46919c67718c451f45e64f28018e78cc0f8f020 Binary files /dev/null and b/public/img/colecoes/ecd26.jpg differ diff --git a/public/img/colecoes/ecd3.jpg b/public/img/colecoes/ecd3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..46efc2ce4b5f4390a03612edb99f15e80fc64246 Binary files /dev/null and b/public/img/colecoes/ecd3.jpg differ diff --git a/public/img/colecoes/ecd4.jpg b/public/img/colecoes/ecd4.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a7d7de6a52ba297cefa683699cd2480738698621 Binary files /dev/null and b/public/img/colecoes/ecd4.jpg differ diff --git a/public/img/colecoes/ecd5.jpg b/public/img/colecoes/ecd5.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a7c1623af658cce6fb3bd574228c08fa0746f8f8 Binary files /dev/null and b/public/img/colecoes/ecd5.jpg differ diff --git a/public/img/colecoes/ecd6.jpg b/public/img/colecoes/ecd6.jpg new file mode 100644 index 0000000000000000000000000000000000000000..66b1af33b7c95847d90359be516c31b4ac5b942d Binary files /dev/null and b/public/img/colecoes/ecd6.jpg differ diff --git a/public/img/colecoes/ecd7.jpg b/public/img/colecoes/ecd7.jpg new file mode 100644 index 0000000000000000000000000000000000000000..02dd2ee2b346192c3e3302e8e0f2c5e3b77d385b Binary files /dev/null and b/public/img/colecoes/ecd7.jpg differ diff --git a/public/img/colecoes/ecd8.jpg b/public/img/colecoes/ecd8.jpg new file mode 100644 index 0000000000000000000000000000000000000000..28060b24ba7566b7a8858b2f20b4cb43ade92a96 Binary files /dev/null and b/public/img/colecoes/ecd8.jpg differ diff --git a/public/img/colecoes/ecd9.jpg b/public/img/colecoes/ecd9.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3a80a711ae8bf0705e561c568f084cd4c7d8ced3 Binary files /dev/null and b/public/img/colecoes/ecd9.jpg differ diff --git a/public/img/colecoes/pnaic.png b/public/img/colecoes/pnaic.png new file mode 100644 index 0000000000000000000000000000000000000000..a3233c4a1a1392500f35b80efe8d76b432922c22 Binary files /dev/null and b/public/img/colecoes/pnaic.png differ diff --git a/public/img/colecoes/pnaic1.jpg b/public/img/colecoes/pnaic1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..534c2ebc287bdc49f3156ca86904517f27ed1028 Binary files /dev/null and b/public/img/colecoes/pnaic1.jpg differ diff --git a/public/img/colecoes/pnaic2.jpg b/public/img/colecoes/pnaic2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..99ac78f3ef192bfa09e2207f64a5739985c332a2 Binary files /dev/null and b/public/img/colecoes/pnaic2.jpg differ diff --git a/public/img/colecoes/pnaic3.jpg b/public/img/colecoes/pnaic3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ecedace1630b2720ef6599f9685dcadf80ae37ad Binary files /dev/null and b/public/img/colecoes/pnaic3.jpg differ diff --git a/public/img/colecoes/pnaic4.jpg b/public/img/colecoes/pnaic4.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8759d8717b0587f28f00d19a50f49f2a1b14e168 Binary files /dev/null and b/public/img/colecoes/pnaic4.jpg differ diff --git a/public/img/colecoes/pnaic8.jpg b/public/img/colecoes/pnaic8.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7646ff6c8cff5a0e47b4e04f8c9fe31a09f09b8e Binary files /dev/null and b/public/img/colecoes/pnaic8.jpg differ diff --git a/public/img/colecoes/pobreza.png b/public/img/colecoes/pobreza.png new file mode 100644 index 0000000000000000000000000000000000000000..cefc875c03f3257492826343916d3307ecd41025 Binary files /dev/null and b/public/img/colecoes/pobreza.png differ diff --git a/public/img/colecoes/pobreza0.jpg b/public/img/colecoes/pobreza0.jpg new file mode 100644 index 0000000000000000000000000000000000000000..27a739e1ff4a52930bf924a46d1764644281f4a2 Binary files /dev/null and b/public/img/colecoes/pobreza0.jpg differ diff --git a/public/img/colecoes/pobreza1.jpg b/public/img/colecoes/pobreza1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..99564b346b0b053fd72c9ba88ddb9eef7a18dcc8 Binary files /dev/null and b/public/img/colecoes/pobreza1.jpg differ diff --git a/public/img/colecoes/pobreza2.jpg b/public/img/colecoes/pobreza2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..098ee5db46a6039782a9f4beacf8a059b8b62e51 Binary files /dev/null and b/public/img/colecoes/pobreza2.jpg differ diff --git a/public/img/colecoes/pobreza3.jpg b/public/img/colecoes/pobreza3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..36ba07beb21d78789e0b8dd43ff90f79f3a8cd48 Binary files /dev/null and b/public/img/colecoes/pobreza3.jpg differ diff --git a/public/img/colecoes/pobreza4.jpg b/public/img/colecoes/pobreza4.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ca7805a149a5ac61ce947f101c9c6ed8d60e3f65 Binary files /dev/null and b/public/img/colecoes/pobreza4.jpg differ diff --git a/public/img/colecoes/senad.png b/public/img/colecoes/senad.png new file mode 100644 index 0000000000000000000000000000000000000000..a25098be457007baa3fc231b4b83fb0a597f4b9c Binary files /dev/null and b/public/img/colecoes/senad.png differ diff --git a/public/img/colecoes/senad1.jpg b/public/img/colecoes/senad1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..00a46f198de765ec3bb08b8cd5a7ed33359b4753 Binary files /dev/null and b/public/img/colecoes/senad1.jpg differ diff --git a/public/img/colecoes/senad2.jpg b/public/img/colecoes/senad2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b5684158c51339172a6c26990ecd5b38229602f8 Binary files /dev/null and b/public/img/colecoes/senad2.jpg differ diff --git a/public/img/colecoes/senad3.jpg b/public/img/colecoes/senad3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..739d0ea9d80e99b92d3ef8e099464cac7f3cdbc1 Binary files /dev/null and b/public/img/colecoes/senad3.jpg differ diff --git a/public/img/colecoes/senad4.jpg b/public/img/colecoes/senad4.jpg new file mode 100644 index 0000000000000000000000000000000000000000..04df2280d8809da38a511eb273b930553d070d8c Binary files /dev/null and b/public/img/colecoes/senad4.jpg differ diff --git a/public/img/ipen_capa.jpg b/public/img/ipen_capa.jpg new file mode 100644 index 0000000000000000000000000000000000000000..453af7bc501316dbc4527694f123bc7e4a8536d9 Binary files /dev/null and b/public/img/ipen_capa.jpg differ diff --git a/public/img/logo_parceiros/ENEF_AEF.png b/public/img/logo_parceiros/ENEF_AEF.png new file mode 100644 index 0000000000000000000000000000000000000000..fddea853a3a12fbca00a872ca14e09406e3d5cc0 Binary files /dev/null and b/public/img/logo_parceiros/ENEF_AEF.png differ diff --git a/public/img/logo_parceiros/ic_bioe.png b/public/img/logo_parceiros/ic_bioe.png new file mode 100644 index 0000000000000000000000000000000000000000..1bc47c707ab283e3965d1a38cc203455e441645d Binary files /dev/null and b/public/img/logo_parceiros/ic_bioe.png differ diff --git a/public/img/logo_parceiros/ic_default.png b/public/img/logo_parceiros/ic_default.png new file mode 100644 index 0000000000000000000000000000000000000000..3829583aa25b35d1c8eaf94ada77dd7013f8132b Binary files /dev/null and b/public/img/logo_parceiros/ic_default.png differ diff --git a/public/img/logo_parceiros/ic_diaadia.png b/public/img/logo_parceiros/ic_diaadia.png new file mode 100644 index 0000000000000000000000000000000000000000..9ee86dee5a83c880699d529310cc2011e6bf838f Binary files /dev/null and b/public/img/logo_parceiros/ic_diaadia.png differ diff --git a/public/img/logo_parceiros/ic_dominiopublico.png b/public/img/logo_parceiros/ic_dominiopublico.png new file mode 100644 index 0000000000000000000000000000000000000000..3fd2832af0396b94880172914e0a500ba20b6fc7 Binary files /dev/null and b/public/img/logo_parceiros/ic_dominiopublico.png differ diff --git a/public/img/logo_parceiros/ic_escoladigital.png b/public/img/logo_parceiros/ic_escoladigital.png new file mode 100644 index 0000000000000000000000000000000000000000..ce05b1f8d10ea8815b3931991db4d9197c9c5ed6 Binary files /dev/null and b/public/img/logo_parceiros/ic_escoladigital.png differ diff --git a/public/img/logo_parceiros/ic_nute.png b/public/img/logo_parceiros/ic_nute.png new file mode 100644 index 0000000000000000000000000000000000000000..40eb4474b28fbc62eb9756f704c63c5ad47bc597 Binary files /dev/null and b/public/img/logo_parceiros/ic_nute.png differ diff --git a/public/img/logo_parceiros/ic_peninsula.png b/public/img/logo_parceiros/ic_peninsula.png new file mode 100644 index 0000000000000000000000000000000000000000..b425b05142256d7857b2cbb82b324dbd146cbad2 Binary files /dev/null and b/public/img/logo_parceiros/ic_peninsula.png differ diff --git a/public/img/logo_parceiros/ic_phet.png b/public/img/logo_parceiros/ic_phet.png new file mode 100644 index 0000000000000000000000000000000000000000..5758157be9a5b4a451e8681e79654f775f55c703 Binary files /dev/null and b/public/img/logo_parceiros/ic_phet.png differ diff --git a/public/img/logo_parceiros/ic_portaldoprofessor.png b/public/img/logo_parceiros/ic_portaldoprofessor.png new file mode 100644 index 0000000000000000000000000000000000000000..df0eccf7c3bff1016f8033ddfa38430ba146005d Binary files /dev/null and b/public/img/logo_parceiros/ic_portaldoprofessor.png differ diff --git a/public/img/logo_parceiros/ic_tvescola.png b/public/img/logo_parceiros/ic_tvescola.png new file mode 100644 index 0000000000000000000000000000000000000000..e8488a8ff8f22c1ac419317e369176f12ef80fb2 Binary files /dev/null and b/public/img/logo_parceiros/ic_tvescola.png differ diff --git a/public/img/logo_parceiros/icones.ai b/public/img/logo_parceiros/icones.ai new file mode 100644 index 0000000000000000000000000000000000000000..d54d2505ea8b5adaf80471bffef6a0f6e3e205ad --- /dev/null +++ b/public/img/logo_parceiros/icones.ai @@ -0,0 +1,1042 @@ +%PDF-1.5 %���� +1 0 obj <</Metadata 2 0 R/OCProperties<</D<</ON[5 0 R 22 0 R 37 0 R 60 0 R 74 0 R 89 0 R 107 0 R 125 0 R 141 0 R 157 0 R 173 0 R 189 0 R]/Order 190 0 R/RBGroups[]>>/OCGs[5 0 R 22 0 R 37 0 R 60 0 R 74 0 R 89 0 R 107 0 R 125 0 R 141 0 R 157 0 R 173 0 R 189 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <</Length 27416/Subtype/XML/Type/Metadata>>stream +<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> +<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c111 79.158366, 2015/09/25-01:12:00 "> + <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> + <rdf:Description rdf:about="" + xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" + xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" + xmlns:stMfs="http://ns.adobe.com/xap/1.0/sType/ManifestItem#" + xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:xmp="http://ns.adobe.com/xap/1.0/" + xmlns:xmpGImg="http://ns.adobe.com/xap/1.0/g/img/" + xmlns:xmpTPg="http://ns.adobe.com/xap/1.0/t/pg/" + xmlns:stDim="http://ns.adobe.com/xap/1.0/sType/Dimensions#" + xmlns:xmpG="http://ns.adobe.com/xap/1.0/g/" + xmlns:illustrator="http://ns.adobe.com/illustrator/1.0/"> + <xmpMM:DocumentID>xmp.did:748fc865-cf1b-6d40-a0f1-1f75821450ff</xmpMM:DocumentID> + <xmpMM:InstanceID>uuid:4bb38d49-3b0c-4af7-9e9d-adca1199c051</xmpMM:InstanceID> + <xmpMM:OriginalDocumentID>xmp.did:748fc865-cf1b-6d40-a0f1-1f75821450ff</xmpMM:OriginalDocumentID> + <xmpMM:RenditionClass>proof:pdf</xmpMM:RenditionClass> + <xmpMM:DerivedFrom rdf:parseType="Resource"/> + <xmpMM:History> + <rdf:Seq> + <rdf:li rdf:parseType="Resource"> + <stEvt:action>saved</stEvt:action> + <stEvt:instanceID>xmp.iid:748fc865-cf1b-6d40-a0f1-1f75821450ff</stEvt:instanceID> + <stEvt:when>2016-10-06T17:18:17-03:00</stEvt:when> + <stEvt:softwareAgent>Adobe Illustrator CC 2015 (Windows)</stEvt:softwareAgent> + <stEvt:changed>/</stEvt:changed> + </rdf:li> + </rdf:Seq> + </xmpMM:History> + <xmpMM:Manifest> + <rdf:Seq> + <rdf:li rdf:parseType="Resource"> + <stMfs:linkForm>EmbedByReference</stMfs:linkForm> + <stMfs:reference rdf:parseType="Resource"> + <stRef:filePath>C:\Users\Quintas\Desktop\google2-01.png</stRef:filePath> + <stRef:documentID>0</stRef:documentID> + <stRef:instanceID>0</stRef:instanceID> + </stMfs:reference> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <stMfs:linkForm>EmbedByReference</stMfs:linkForm> + <stMfs:reference rdf:parseType="Resource"> + <stRef:filePath>C:\Users\Quintas\Desktop\banco_objetos.jpg</stRef:filePath> + <stRef:documentID>0</stRef:documentID> + <stRef:instanceID>0</stRef:instanceID> + </stMfs:reference> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <stMfs:linkForm>EmbedByReference</stMfs:linkForm> + <stMfs:reference rdf:parseType="Resource"> + <stRef:filePath>C:\Users\Quintas\Desktop\dominio.png</stRef:filePath> + <stRef:documentID>0</stRef:documentID> + <stRef:instanceID>0</stRef:instanceID> + </stMfs:reference> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <stMfs:linkForm>EmbedByReference</stMfs:linkForm> + <stMfs:reference rdf:parseType="Resource"> + <stRef:filePath>C:\Users\Quintas\Desktop\logo_1__2_.png</stRef:filePath> + <stRef:documentID>0</stRef:documentID> + <stRef:instanceID>0</stRef:instanceID> + </stMfs:reference> + </rdf:li> + </rdf:Seq> + </xmpMM:Manifest> + <xmpMM:Ingredients> + <rdf:Bag> + <rdf:li rdf:parseType="Resource"> + <stRef:filePath>C:\Users\Quintas\Desktop\google2-01.png</stRef:filePath> + <stRef:documentID>0</stRef:documentID> + <stRef:instanceID>0</stRef:instanceID> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <stRef:filePath>C:\Users\Quintas\Desktop\banco_objetos.jpg</stRef:filePath> + <stRef:documentID>0</stRef:documentID> + <stRef:instanceID>0</stRef:instanceID> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <stRef:filePath>C:\Users\Quintas\Desktop\dominio.png</stRef:filePath> + <stRef:documentID>0</stRef:documentID> + <stRef:instanceID>0</stRef:instanceID> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <stRef:filePath>C:\Users\Quintas\Desktop\logo_1__2_.png</stRef:filePath> + <stRef:documentID>0</stRef:documentID> + <stRef:instanceID>0</stRef:instanceID> + </rdf:li> + </rdf:Bag> + </xmpMM:Ingredients> + <dc:format>application/pdf</dc:format> + <xmp:CreatorTool>Adobe Illustrator CC 2015 (Windows)</xmp:CreatorTool> + <xmp:CreateDate>2016-10-06T17:18:17-03:00</xmp:CreateDate> + <xmp:MetadataDate>2016-10-13T19:27:22-03:00</xmp:MetadataDate> + <xmp:ModifyDate>2016-10-13T19:27:22-03:00</xmp:ModifyDate> + <xmp:Thumbnails> + <rdf:Alt> + <rdf:li rdf:parseType="Resource"> + <xmpGImg:width>256</xmpGImg:width> + <xmpGImg:height>256</xmpGImg:height> + <xmpGImg:format>JPEG</xmpGImg:format> + <xmpGImg:image>/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA
AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK
DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f
Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAEAAwER
AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA
AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB
UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE
1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ
qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy
obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp
0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo
+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7
FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7F
XYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FX
Yq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXY
q7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq
7FXYq7FXYq7FXYq7FXYq7FXYqtkkSNC7mijqcVJY9qH5g+V7H+9uXY+CROfDxA8cujgkXAzdp4cf
M/YUiufzi0NGpBDPIPH01H65Fy0aSTr5+0OEcrPw/akl1+cmrl6WVrb8T09ZHr2/llywaQdXEn7R
H+GPzH/Hm4fzR87zCsdjYsP9WQfrmxOmh3lgO29UeUYfj/OVm/MTz+BX9HWNOvRv+q+D8vj7z+Pg
2DtbWfzIfj/OWL+a3meFx9dsrVV/a9NXJp9M3zx/LRPItg7ayj6o/L/pJM7b849JbiLi3mQ7c2WN
eNe9P3hOQOkLbD2gxfxAj4ftZBY/mH5Wvf7q5df9aJx4+APhlUsEg7DF2ngycj9hZFHIkiB0NVPQ
9Om3fKXYArsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirTuqIzsaKoJY+w3xU
lhPmb8zNO071ILP9/crVT9pKEch+1GR1GZOPTk83T63tjHisDeX48nmV5rfmLzDcqksvryb8E4xJ
2BO4CfyZmiEYB5bLrc+pNX9yfaR+VerXVHuz6C+FEfx/lkHhlU9SByczT9hZJ7y2+X62Zab+Vfl6
3FbpPrTfOWPx/lkPjmPLUyPJ3WHsLDH6vV8x+lklnoOk2QpbQemB/lufH+Zj45SZk83Z49Jjh9I+
9GiCIdF/E5G2/hDfpp4YFpabeE9V/E4bXhCFvNE0y8jMdzD6iHqOTjsR+yR44RMjk1T08JcwxfUv
yp8v3A/0Nfqh+cknh/NJl8dVIc3VZuwsMvp9PzP6WOSeVfOXl1mm0qfmm1RxgFe3+7Gf+c5d4sJ8
3A/KarTbwNj/ADf033pxoX5oQSTC11aP6vL3epfsW6Rx06Uyuem6hzNL21GR4Z+k/P7gz6CeKeJZ
Ym5RtWhoR0NO+YpFO9BtfgS7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYql+ua3ZaRYyXV0
3EKDwWjHkwUsB8IaleOThAyNBp1GeOKJlJ415r8+ajrUjW8Z9Oz5HjH8LV+0AalFb7LZscWAR36v
G9odrzykxjtH+3yV/Kn5eX+rGO5uP3VoxBr8LVB4ns6t9lsGXOI7BGg7InmqUto/2eb1/SdC03S4
fSs4vTHf4mPcn9ot/NmvlMy5vY6fSwxCohH5ByHYq7FXYq7FXYq7FXYq7FUm13yppOsRFbmP95+z
JyfbcV2Vl/lyyGUx5OFqtBjzD1Df4/rYFLp/mPyVP9Ytm9fTR/eLSJOooN2Mj/bkzK4o5Pe6Mwz6
I2PVj+A/WeZeiaFrtlrNktzbNUbBxRtm4hiPiC/zZiTgYmi9Fp9RHLHiimWQb3Yq7FXYq7FXYq7F
XYq7FXYq7FXYq7FXYq7FUn81eYYND0p7uTd2qkQ33cozL0Vv5e+WYsfEacXWaqOGBkXhHmLzDdat
dy3d03wAsUWg2XkzAfCq1pyzaY4CIoPC6rVT1OT3nb5/DvYffa4/rAQGio1SfGhPiMtp6nsnsMQA
nk+r+w9C9+/Knz3Y6zo9vpzvxvbSJIuFGNVjSNK1CKv2m8c1eowmJt384U9BzGa0Pe6haWcRluZP
TQdTRj3A7A+OVZc0YC5Fsx4ZTNRDFNS/MrToSVtV9bwarL4dmjzS5+3ccdo7/P8AU7jB2JOX1bfj
3sav/wAydVkRuH7oAfa+Bv1x5q8nbeWe0dvl+p2mLsXHHnv8/wBbGb38ztRUlWveRFfh9JR49/Ty
UDrMm97f5rlR7PwD+H7T+tLW/NPVlaqS9O/FP4x5kx0uo6z+wMjosP8AN+0oi2/OLXImHOXko7cY
x+qLL449SP4/si1T7Nwnp9p/WyTSfzwBKrdrQbVNfl/LDlw1OohzHF8g4WXsSB+k/j5vRNH88aJq
YAjl4yN0TjIele5Rf5cy8PaWOZrkfj+p0ufs3Lj3rb4frT8Go2zYOvbxVpgGWhFQcUEPONa8tX3l
u/OtaN/c1rcRfD9jkZX+KRnPRANhmZDIJjhLzmo0c9LPxcX09R9p533Mw8ra/FremC5TZ0PpyjfZ
wisw3Vf5u2Y+XHwmnc6LVDPDiH4KcZW5bsVdirsVdirsVdirsVdirsVdirsVdiqG1LULbT7Ka7uH
VIoULksadO335KMSTQa82WOOJlLkHg/nbzbPrWoSu7BbKFmEQ+EgqrOVbkFU/ZbNphxCI83hdfrJ
6rLwx3F7fM197zvV9U9djFEaxg7kd+o8MvAeo7F7I8Eccx6v7PNKsk9Gi9MuL63vYZ7IH6xE6tHx
UNurAjYgjqBlWbJCESZkAMo4zPYC3tkf5v3iaUiXpWC835EvGx+3UfCsdPs0zi9b2jKRrADId/8A
aPe7XS9i73P8faxVvMtxrN3z3lUfamoFH2dtuK/y0zndZgmBxZT6u7b9Dv8AFijAVFMoNI1m7iL2
FjLdU/kU06/zUp2OY+l0OTMfSDTHNqseP6pAJRe/l5+Zd+xrpEix/wApktx4eLKe2dXpezRiGw3/
AB5uKe1dP/O+/wDUgZPyn/MJBVtGkP8AqyQt+pzmb4cu5A7U05/i+9A3P5f+dbYEy6LdgDqViZx9
618MHAe5tjrsB5Tj80oudN1G1JW5tZYSOokRlpT5j2yJDkRyRlyIKGxZK9teXFu3KJuP0A/rB8cp
y4IzFSCXoXlL82r3TmWK8asG/wDKP5j+zGT1OY0YZcP0eod2zrtV2djy+R/Hm9n0Hzt5e1mNTbXs
Xqmv7rlvsT/MFrstc2WHWwnsfTLuLzGo7Py4uYNd6fVGZjgtOiupRhVWBBHscUEWw3UdJvtB1T9L
aXG0trK3+mwKASFZzJI9WLt0UCij5ZkxmJCi6bLglp8niYxcT9Q+0nqyjTNTtdQtkmgcEkD1E3DK
1ASpBAO1fDKJRILtcOaOSNhF5FtdirsVdirsVdirsVdirsVdirsVdiryP8z/ADe9zMdKs5FNsNpi
jfaDCNx9liDvXqMz9NircvI9udocR8OJ26/Ye95/F5V8x68y22m27BGIDTukvpivwmrIrfzA5kyy
xjzbuwNAP72Xw+w9yf2X/OPGutGGu7y2DEA0jlk2qB/NBlJ1o6PYeKEPr35HXGlWMt3JqNsiRqzU
kmILcVLUFYVqTxynJ2lGAs/j7W3AJZJCIDDbSD0ZPqunwm6vCePNF9TeoX4SnxfapTOf1GTJqpWb
EO7f7RuORep0+lhgjcqtC6hp2uRTcLq2nRz3lSQdgf2hmyw6GGOPFKgHFy9qcR4cf4+RZLAING03
nLTn36VPxe/H+bONnGWu1HDDl+z49zsDk8HHcjv+1n35efm55a9AWF5H9Sn7zcYooju77s0tem3T
rnb4uyxgjUfx9jyGqnLLLiL1e0vbO7j9S2mSZP5o2Vh1I/ZJ8MiQQ4VK+BVrIjgq6hlPUEVGKQUo
1Tyh5d1JGW4sYOTVq4ii5b17lT45ExBb8eryQ5E/MvNfN35HI6y3WiSBXHJvQkNAR8TUVYoevQDK
pYe53Ol7araf4+ZeN3ljeWUxhuoXhkHVXVlPQHowHjmOQ9FCYkLBtQxZpjpOuX+mXCzW0rIVr0Zh
1BH7JX+bMfNpxPcbHvYyiJCju+gPy/8AzIsdbiW2uXEd2K05FRXd2/akZjRVyzS6og8GTn+O95Xt
Hsw4/VD6f7PJnubN0q10R0ZHHJWBDAitQdsUEWKLE54bjy/ra3Mbf7i7tgsiEn4JJJORIA4IAETM
gHjjXV1RidPlsf3cvvJ+XJlkMqSxJLGao6hlI3qCKjpmOQ7WJsWF2KXYq7FXYq7FXYq7FXYq7FXY
qkPnLzDHomkSXFf3xp6ailT8ag0HJT0bLcOPiLg9oasYMZl1/aHhOnwTalqttbuzSSXMscZYkk/E
QvU16DNpI0HgMUTlyAHnIh9A+X9GtdL0y3t4o1V1jQSOFAJYIoJJAWteOamczIvo2mxDHjjEdAPu
Rt3cw2ttLcTMEjhRndmIAooJO5p4ZWTQtyYRMiAHhnm7zDrPnTX/AND6QJDZrL6TOnqFKCRoyxMb
SLTjIN6ZgSickt+T1Olww02Pjl9X7Ph3PQPJH5Y6VoVvHNdRpcX5AZ3cI4DEITxLRqwoy7ZlwxgO
n1vaU8pobR/HmgPzJk0eiWkNpAbk15yLGnIU9NhuN+maTtvtAxj4cTuf2Hvc3sbSWeOXL+0JFqH5
QXut6PFNFcejdfF+7kdlj+2BuBEzfZXM3sDTjTx4pD1H9rX2nr+OfCPpH7PN5br3kPzPoch+s2kh
UdJY45SvQftMi/zUzrYZoydcJAo7yh+ZnmDy9eRF55Li0VgZYZWkf4firRfURa/F3yOTBGQRKAL3
nyl+Zvl3zBAnGdbe6IAaGZokblRa0X1HNKvTNdkwSi0SgQy9WVlDKQVO4I3BrlDBvFXYqwjzz+We
meYLZpLeNLe+FODqEQHdAeREbt9lNsrnjt2Wi7RliO+8fx5vnTVNJvtMumtbyJopVpUMrL1Ab9oK
ejZikU9fiyxmLCDwNqN0rVbvTbpLi2kZHWtOJYdQR2K/zZTlxCY82MoiQovqLyb5ntde0qKeN1Mw
RRKgIJrwUtsGc9XzM02fjjvzDxGu0hwzI6J/mS4SXeYdPS+0m5hI+MRuYiOofgwUjY775OEqLTnx
DJExKR+Qtb+sQz6VMWNzYSPCC5/YhCR9zXr7ZZmh173G0cyLxy5x+4bMtyhz3Yq7FXYq7FXYq7FX
Yq7FXYq8W/NLW3vdYFrHLytrf7KK1ftpGx5AEjqNs2WmhQt4rt7VGeTgB2j+kBLPy8s/rHmuwJFV
ik5H6FZh2P8ALk85qBcTsjHxaiPkXvgoBTwzVPoDzf8AM3zBeXMsPlrSiWubxljmKciVSUyQtX02
JABI6rmNklxHhDuuztOIg5Z8h+wp55E8jWPl/T43ZA9/KqvPKwUsGZU5ANwRvtJXfLYQoOJrdbLL
L+iyW9uktbWW4kICxIzmu32QT3p4Y5cghEyPQOHigZyER1eUaJb3HmTzCJJ6tH/uw7kD90QOvP8A
kzitJCWrz2eX7Pj3PY6qcdLgoc/2/DveuRoqKFUBVHQDbO4AA2DxhJPNQvtMsL6P07u3jnXwkRX7
g/tA+GSEiOSgvLfPH5IaddW8t5olYbpFLC3+FY2ICgAJFCSdlP05mYtURsW2OXveM32l+YvLd+RI
k9pLG20qiWMHix6MQh6pmcJRmG4EFn/kf87tRsDFZayPrFrVVE3xPIPsLu0koFKAnpmNl0oO4a5Y
u57boXmbR9btUnsbiOTkATGHQuKgHcKzfzDMCeMxO7QYkJrkEOxV5v8Amx5Ai1XT21GyiH12GlVR
RV+TRp+yjMaKp75VkhbuOy9cccuGX0/2vnogg0IofDMV61rFLO/yr84z6LrcdvK/+iXBWNlYmg5y
Riu7Kv2Vyn6J8Q+Lr+0dKMuM94/UX0fbXEdxBHNGQUkUOpFDswqOmbSMrFvFyiYmiqEAih6HrhYv
HrzUm8s/mosLMy22qUfiDRa3F4RyIqg6J75nRjx4/d+pwtTDhlHIPKJ+96/FIskSSKaq6hlI8CK5
glzAbFrsUuxV2KuxV2KuxV2KuxVDajdraWclwxACU3PTdgPEeOGIsteWfDG3zfe3k15cvczU9SSn
KlabAL3J8M3MRQp80y5TORkeZZl+U0IbXi5H2KEfTHJmNqj6Xc9gRvNf45F69qd4tnp9xcsR+6id
wPEqpanUeGarNk4IGXcHu8OPjmI95YZ5L0E3uqXXmK+UtJLLILUOK0jZ0mQrzBpSppRsx9KLHGeu
7stfn4IjFHpz+0M8zMdQwX8xvMBigGnQNRn3kIO/Eh0ING/hnOdua3hj4Y6/tD0HYujs8Z/HIq/5
caSLawa7daSTU6j+RpF8B45Z2FpuGHEeZ/a19tajinwjkP2MzzfujdirsVSXzB5P0LXbd4r62Qs4
I9YJGZBUMKhmVt/iJyyGSUeTISIeHeefyY1LSZJbrSQ11Z/EwT4pJAPjbpHEq/ZUZn4tUDsW+OS2
G6N5m8xeWr4G2llheFvjt5GlVCVYVDIGT+ShzIljjMMzEF7r5D/ODTNahittSZLW/oqsSUjRmoim
nOVmNWY5rs2mMeXJx5Y6ekZita10V1KuAVPUHfFINPmL8y/LI0PzBIkScbeTj6YpQfDHGT0VR1bM
PJGi9r2dqfFx78/2liGQdgvhleKVJUNGRgykbbg17YJCwgh9KflR5j/S3lyOORwZrYLEQTVqRxRi
u7MerZbpZ2CO54/tbT+Hkscj+ss3zLdU8L/PsNb+ZdNvoyUkSGBQ67EUlmaoIp4eObHR/SQjLj48
Uh5H7nrHkW+a+8naPcsSzvaxhmJqSUXgSTU9eOYWYVMtWn/uwD02+WyeZW3OxV2KuxV2KuxV2Kux
Vhf5r3gi8sS2x63PGn+wljbwzJ0o9Vum7dyVpyO/9YeJ5snhGf8A5ROP0xIvc0/4hLmJquT0Ps+f
3h/HQsz8/wB6qW9taHpLMlfkwdfDOV7YzcMYx75D9L6X2RiuUpdwP6GR6OirpNkq/ZWCID6EGbTT
f3cf6o+51uoP7yX9Y/e1q96llptxcsaenG7L7lVLU6HwwanKMeMyPQH7l0+I5JiPeQ8TvruTUNUk
mff1pTxG3RnJA6Dxzz7NlOXISep/S95ixjHjAHQfoe4afai2tI4R0Sv4sT7+Oeh4cfBEB4HNPikS
iMta3Yq7FXYq7FWJ+dfy70bzLbOZU4XgU+nNVzQ0enwh0X7T1y7FmMGcZkPnfzl5H1XyzfOk61t+
R9KWqCo5MF+EO56JXfNniyiYciMgWT+Qvzh1HRylnqbevZCvE0VOP22/YiZjVmGVZtMJbhjPHb6A
0jWLDVrRbqyk9SJq70ZehK/tBT1U5rZRINFxyKedfnvpay6LDegfFBy5H/XkhUd/4Zj5hs7vsTLU
zHv/AGvA8xnqmV+QvIt35pviit6drHvJLQN9lkBHHmh6Pk4QtwNdrRgj5vW/LPlW38l+YIbaGf1h
eRqrfAVoZZFU9Wk/33mLOfhakD+dED5l0+bOdVgJIrhP3D4d70jNs6B4L/zkTOv6ZsoP2vq8Un0c
5xmx0Q2Lfh5M2/I67abyZbxE7QqQo+c0vt7ZRqx6nBx7ZJx7j99l6JmK3uxV2KuxV2KuxV2KuxV5
f+dNy4/RkCmin1/UHj/dEZnaMc3lvaSZAgO/i/3ry/M15RmP5XXHpeZoY/8AfrUH0Ryf1zH1I9Lu
uw51nA7/ANRZF+ZF4x1OCP8A32FYfQ8g8M8+7dyfvAPxzL7J2Jj/AHZP46M38rXqXWhWjg/3UUcb
fNY1r2HjnQ9n5RPDE9wA+wOh1+IwzSHeT95YV+YvmD15f0dEfgjNX2/aBdD1X+Oc/wBua3iPhjp+
0O97G0fCOM/jkWJaJF6usWMf89xEv3uBmk0kbyxH9Ife7nVSrFI/0T9z3jPSHz12KuxV2KuxV2Ku
xVB6rpVlqllJaXaepDKrKwqw+0pX9kqejZKMiDYSDT5o8/8A5a6h5YlMy/vbE/Zk+FegQHb1Hb7T
5tcOcTcmE7SXyv5w1jy7diexkov7cfFDy+FgN2V6U5nLMmMSG7KUQXq3mX8xtI80/l/qEdfTv09G
kXxt1uVP2uCL9lK5p9VgMYuR2ZEx1Efj9xeMZrXsn1D+WehppXle1AFHnRJm37vDHXu38uZmMUHi
O0c3HlPl+spJ5t1Gvm+zof7oxJ/wMze2ct2ln/wqPlX+6Luez8P+DS87/wByHoNtKDZRTMdjGrk/
7GudTiNxB8nmsgqRHm+ZPzh1kan5wnINVtQ1uPlHPL7L/Nm600ai34xQZx/zjxOfT1GLt+5/XOco
1o5OrqtRPz4fue1Zr3KdirsVdirsVdirsVdiryD84XJ1S1XsvqU+lIs2Gk5F5D2jPqj8f968+zLe
aTjyddC2806ZKTQfWEU/7M8Pf+bK8wuJc3s6fDqIH+kyr8wZfU1tSOhhBH0yPnmPbh/f/D9JfeOx
P7i/xyCV2HmDUrK1ktoJOMcoYMKKftAL3U+GYOHW5McTGJ2Puc7Lo4ZJCRG4S53aR2djVmJLH3O5
zFJJNlyQKFBN/KKcvMFl/kyxN90i5ndmC88fePvDhdomsMvcfuL2zPQXhHYq6uKuxV2KuxV2KuxV
RurWC6t2gnXnE9OS1I6EEbgg9RhBpXzr+Zv5XTaC7X9gvLTzTkKgcf7tB9uR2NWc9s2eDUcWx5uT
CdvOIv7wf59sGuP7o/jq7Ps4fvh8fuKNt2jEymQ0Tep38PbOfhEyNB6bLLhjb6u0zzBo9zoYnsJ/
Uhhgop4utOEYP7ag9CMy8944knoHg4xMp13l5ZfXn1rzGZj0Nzsfb1SfAeOefZsvHqL/AKX6Xt8W
PgwV/R/Qn/n78xrHRvLcenWz89QntxGUow4q8TpWpjZTRl8c9H7PwmUIk8qH6HjMkLyS95+989XV
xJcXEs8hq8rs7H3Y1PSnjm6Apm9i/wCceGpc6gvj6P6p8wtbyDqsn+MH8dHuea5yHYq7FXYq7FXY
q7FXYq8i/OOJl1K0cjZ/UofkkQzYaTkXkfaQeqHx/wB688zLeZXQyNHKki/aRgwPuDXEhlE0bZJf
6omopayAjnDbxwv81qT2HjnmvtHglHPdbH9cn3D2R10MulEQfVH9EYoTOeerdiqc+UJFTzDZ1NOU
saj6ZFzP7MlWePvH3hwe0ReGXuP3F7ZtnoLwjsVdirsVdirsVdirsVdiqncW8VxC0Mo5RtTkKkdD
XthBpXzV+ZnkOPy3qgktyPqs32F7jgkYPV3bq+T1Wo4oV1eg7GHFInu/awadqLTxyHZ+K533ftdl
2pmAx8Pf+xOvKFlcNeG4oViVacqbEhlNPuzE9pu0I48Xhg+qX3ESDgdl6YynxHkP2Mr1GURWUzk0
ojb/AOxJzhNDjM80QP5w+96DUS4YH3F5vcv6lxI9a8mY/ea569gjw44juAeMyG5E+allzB7R/wA4
8ofXv2/4w/qnzB1vIOomb1B8v1Pcs1zlOxV2KuxV2KuxV2KuxV5p+dFnI8Om3KAcIfX9U71+IxKv
bM3RnmHmfaPETGMu6/t4XlWZzyLsVV7WcxyAE/CdvxGaTtzs/wDMYiR9Ud/kD5PUey3bB0moAkfR
I18zHfmO5NAQQCOhzzGcDEkHmH3HFkE4iUdwRbsi2IzR5xBqtnMTQRzxsf8AYuDl+lnw5YnukPva
NTHixyHeD9z3kUOekvnrsVdirsVdirsVdirsVdirjir53/OjWxfeYfqsTckg6gGv24om7E+GYuU2
Xrux8PDjs9f1lg+seWtW08QPcQsFuOfpni/7FK9VHjm20cowx2fxu67XZvFyUPxszDS7FLO0jiAo
1By+fEA9h4Z5l2jrDnymR5Wa+Zek02EY4AJd5svRBYemD8ch4kd6MrDxzbezOkOTPxdI7/EGLh9q
ZuHHXU/qLBs9KeXdir3v/nH3TZY9Mub1qcJvT4UrX4HmU12/jmu1ktwHURH+EZD/AFfuev5guU7F
XYq7FXYq7FXYq7FWJ/mdYNdeVbl442kmi4emqjkfimjrsAT0GX6aVTdV2ziM9PKue33h4Xm0eAdi
rsSLSDRtHWVzWkbHfsfuGcL7Q9jkE5YDbr9p6B9U9kPaMSAwZTv0v/NiBvL9CNzjn0gLkYq4YdVI
I+jEGigiw9w8vammoabFOrVY8uW9f2mHifDPRdFnGXGD+ObwOswHHkITPMtxXYq7FXYq7FXYq7FX
Yqgda1S30vTZr24YLFFxqagfaYL3Kjq3jgJptw4zOQiHzNoVje+bvNiK4LG4r6r/ABELwhPGpIkp
X08w4jiL2eecdPi9363qf5jyaLM1tZwRRs9rz+ILGQPU9NuozUdr9qGMfDgefP7D0LrOydESfEn+
OYYa7qiFm2Cgk/RnKwiZEAdXoyaFsB8x6ibu+YA1SOqjw+Fm9z456f2BoPAwAn6pb/MB5TtHUeJk
8h+1Kc3zr3Yq+n/yY017PyRYytT/AEmPmKeBkkYdh/Nmp1Urm6zHH1Sl3n7iQzvMZudirsVdirsV
dirsVdiqjeWy3Ns8DAFXpUHpsQffwwg0WE4cQp8239jNY3clrNT1I6cqVp8Shh1A8c3MZWLfM8+I
45mJ5hD4Wp2KtqSpBGxGQyYxOJieRbcOaWOYnE0QUxtboOArH4v9r3zzztrsSWGRnAXD7uZ6B9h9
mfaeOpgMWQ1kG3v+kdZEkklE5zT27Nfy98xi0uDY3L0hk+wxOw4h2PVgBUnwzoOxNdwS4Jcj+0ui
7Y0XHHjjzH7HqANRXOweTdirsVdirsVdirsVdirx/wDO7zeEgXRbaTd6+uFPgYpV+y36xlGaXR6D
sbSb8Z/HMJF5CEXl/SpNQKg6jcU9EMAePB3Rv5HFUfsc1Gt7QGGND6vx5uzz4Tnnw/wBTmnlnkMk
rF3PVmJJ2FO+cfOZkbLtIwERQY55n1hbe3NvE3759moeikMOxB6jOm9neyjlyeJIekfeOE9zq+0t
YIR4RzP7WFMxZixNSTUnPRYxAFB5om2skhEadaSXl/b2sQrJPIka1rSrsFHQHxwE0GrNKoH3Prny
bpx03yppNk324bWIP/rFQzdh3PhmlyyuRLh4hUQnOVtjsVdirsVdirsVdirsVdirxz82NCe01VL+
KICC6rVkXZfTSNPioABUnbfNjpZ2KeN7f0vDMTA2l+igx3yj5e/TmsQWjlltyw9Zl2YLRm2JVh+z
3y3Lk4RbrOz9H4+QRPLq9C1D8ntIMBNlcTicD4RK6ca0PXjFXrTMSOrPV6LL7O469JN+df8AEsA1
7yZrOkOxlhaSFa/vUV2WgrvyKKOi5lwzRk89quzcuE7ix8f1JECytUbEYcmKOSJjIWC4uDPPFMSi
akEfbXgYBX2Pj/tnOE7Y9nzjJni3j3fM9A+rezntdHKBizmpcr/0o5mXvRscjxuHQlWHQg0Ph2zl
ATE2HvyBIPU/JvnGK+iFreOqXC9GYgA1Lt1ZiTQDOy7L7UGQcMz6v7fN5PtLs04zxR+n+zyZhm9d
I7FXYq7FXYq7FUq8x6/Z6Hpkl7dOAqUotVBNXVdgzL/N45GUqDfp8EssuEPm101HzDqb6hqJYB6c
h8XZOHw8+f8AIO+c/ru0xDlvL8eb3WHAMceEMkLEgL0UdFHQV9s5TJllM2S3RiByTHQ9CvNWulhh
Q8DXlJRuI2JG4Dfy5kaTRzzSoOPqtXHDGywX8z9Oi0/zRNbxV4LyArTtNIOwHhnq3Z+COPEIx/Gw
ePlmlkPEWI5nMXYqz38nvKzaz5ohnlST6tYlbgSqPgMkU0R4MxVh0bpmNqcnDFxNSbqL6cRFRFRd
lUAAewzUsQG8VdirsVdirsVdirsVdirsVS7X9Gt9Y0uaxnFUl413I+y6t2K/y+OThPhNuPqtPHNA
wPIvM/y3X9G+aJNPlNXJUA+NYnbtX+bxzN1G8beX7Hj4WoMDz/YXrua97Ba6K6lWFVIoR7HFBFvO
PPf5eRyiXUdPWj0aSVKk1Pxuxq7/AC7Y/mp4t+cXV6vsTFnBMdp/E/prm8rngkhlaOQUdSQRsdwa
ds2en1MM0bi8brdDk00+GY+79vcrW940ezbr/n7Zo+1OwIZvVDaX9nm9T2D7XZdMeDJ6ofAVz7ok
8ymMUoYckOcDqdLPBKpCi+s6LX4tVDixmx8f0gdzNfLHn6e0At7795F2fZafaPRUJ6kZtuz+2ZQ9
M9x/b3BwNd2QJ+qGx/Hm9G0/VLPUIvUtn5r32YdyP2gPDOrwaiGUXEvM5sEsZqQReXNLsVdiqB1P
WbDToy9zJxIFQKMa7E/sg+GY+fVQxC5FyMGmnlNRDxvzVrDa9fiaUfuY/wC6Tw5KobcBT1XOP13a
08u0dh+PJ7HQ6EYY+aWUGad2DJfLPk661WQSy/Bbd22NftDoGU9Vzbdn9lyzGztH+3zdVru0o4RQ
+r8eT1ew061sIFgt04Itdqk9ST3J8c7TDgjjjUeTyGbNLIbk+W/zRvBdecb5gfhSSVfunk9h45vt
OKiG6A2Yll7JWtLWa7u4bWBeU07rHGtQKs5CgVJA6nATTGcuEW+rvy90B9I8s2MU4pdNBEZB/KTE
gK7MwNCvXNPmnxSLhR33PVk2UsnYq7FXYq7FXYq7FXYq7FXYq7FWF+c9IW0vYPM0CVlspFkuN+qV
jQ9SR9gHouZOGdjh73Tdo6cRkM45xNn7B93kyjSdQh1HToLuI1WVEY9diyhqbgeOUSjRp2eDMMkB
IdQjMi3OIBFD0xVifmzyLZatG80Q4XVCQfiNTRj3dR1bMHLpjGXiYzUvv69W+Rhmh4eUXH7unR41
qmjXmmzGK4Tiw91PYHsT45s9F2pHKeGXpn3c/wBFcnh+1vZ/Jphxx9WPv2Hd5k8ygo5GQ1U0OZup
0mPNHhmLDqdF2hl00+PGaPw/SD3o6G+U7Pt7/wC0M4ntH2anDfHuP7O+T6f2P7bY8npzek9+57+6
PuTGzvri1lSe2fhIpqrUB3+TA5zMZTxS22kHuv3eaHfEsjtPzC1yFQsjerTvSNfDwTNlj7bzR57/
AC/U6/J2Pily2+f60U35m6oVoIqHx5J/1Ty49v5O77v1NQ7Dx9/3/rS298869cgqJvTRtivGM7Gv
fgPHMXL2vnn1r5fqcrF2Vhh0+/8AWkU08szl5G5MxqTQDc79s1spmRsuwjARFBVsdPur6YQ2yc3P
aoHYn9ojwyeHDLIaiN2GXNHGLkXofl38vIYCJtQ/eMK/u91/mHVH+WdToexIx3yb/jyLzWs7ZMto
bfjzDOERUAVRQDtnQgU6Em0FrepwaVpk19O3GKHjyahP2nCjoGPVvDJwjZpQLfHeoXb3l9cXT/an
keQ/N2LeA8c3kRQpzAoDCpL238jvJP7s63dwcXLUgl51qlIZVHFX+ncZr9Xl6BwZ5OOVDkHtgAAo
OgzAS7FXYq7FXYq7FXYq7FXYq7FXYq7FVO5t47i3lgkFY5VKON+jCh6Uwg0xnESBB6sGjW58p6ww
PxaVdSEnoOBkfr/uxzRI8yTWQebpAJaTJ/tcj95+J5BnNvcRXEEc0R5RyqHQ7ioYVHXMYindwkJA
EciqYGTsVQepaVZajD6N1HzX5sO4P7JHhlObBHIKk24s0ocnnfmD8pyay6a+/wDvun+qOryfPL9N
lnj2JsOh7S7Hx5vVD0y+J7u8vOtS0m+02cw3kfpyDtyVuwP7JPjm3hMSGzxefTzxGpBQhneI/Cdu
4zC13ZuPUxqQ3+P63Y9ldtZ9HMGB9PUbfpB70bFfRtQNsf8AP2zitd7N5cdmHqHwH3yfTey/bXBl
qOX0y+J7u6KKUhhVdxnO5MUoGiN3ssOeGSIlE2C0jq9wlum80hConSpY0G/TrlmLS5Mh9IZzmIiz
yZzoP5dXE6Rz3zemrBW9OgOxoeqv883el7Bkd5/j5F0Wq7aiLEPx9j0Ow02zsIhHbR8E8Kse5P7R
PjnT4cEMYqIp5vLnlkNyKKy5qWu6opZjRR3xV88fm/8AmIutTnS7F62SfbNPtVEUg+0isKMp75s9
Nh4dy5GOFPL1RnYKu5OwGZjOcxEWeT078rvy4k1K/hvr1P3UZWVEqOitGwaqyA9CdqZi6jNwig6m
er8eXDD6X0Na20dtbxwRiiRKqL16KAO9fDNWTbkxjQpVwMnYq7FXYq7FXYq7FXYq7FXYq7FXYq7F
VC+soby2kt5hVHBHfuCOxHjhiaLDJjE4kFh4e+8qXlHHqaPK+7fCPT5N9qg9SRuMceZG0x5uo9Wl
l/tZ+z7zyDMLK9try3juLd+cUihlahGzAEbEA9DmOQQadvjyCYsclfAzdtirsVQeqaTY6lB6N2nN
O27DuD+yV/lyUZGPJpz6eGUVIPMfNH5WT28clzpZ9RUUsYtl2AX9p5PmczcWpvYvLa7sIxBlj3/H
mXn1xaz20rRTLwdSQwqDQg07V8MywbednAxNFu3vLm3Dei/DkCDsDsfmMhkwxnzDfptZkwm4Gvkn
HlHzJDoV5Jcm39WaVizycyv2mVjtxYdVzGOij0egj7VZ5REZ7ge7/iXo9h+bOiTAC6X6udqmsj+H
8seVy0sujmYu38Uvq2+f6k+g87+V5xWK95f88ph+tMqOGQ6OfHtPBLlL7D+pVuPN3l+3iMst1xRa
VPpyHqadlwDFItv53F3/AGF4x+Yf5k6rrqvp+lR8LI05PVDypwcbSRqwoynvmfg04juVPaemhvKX
2S/U87g8vzsayniPDY/qbMq3A1HtLjH0C/n/AMS9H8gflr+kJVnljpa7cmr1FUPQSBvsnMbNn4fe
6/BHNrZXk/u/h+ijyL3LS9MtdNsorS2XjFGqr1JrxULX4ix6LmtlIk2XpMOGOOIjHkEVkW12KuxV
2KuxV2KuxV2KuxV2KuxV2KuxV2KuxVp40kQo6hkYUZSKgg7dDigi+bGtR8ry28/17R3+ryK/qzQK
SiOASzALGu5Ow3OXRyXsXXZdEYnix7Hn+KdZebhFP9U1W3ltpB0ndPTiIBC/akbr1PyxOLqE49dR
4cgMT38h9rI4poZV5ROsi+KkEfhlRDsBIHkvwJdirsVQd/pGnX8ZS6t45ainJkVj37sD45KMyOTT
l08MgqQBYTrv5T2Vzzk05/RlNSEYqqV3PRIyepGZMNURzdHquwIy3gaP47gwHWPI3mDS2f1YGljW
v7yJJGWgr3KL/LmXDNGTz2o7LzYjuL91/qSBgVYqwow2IOxBGWuBKJHNrFi7FUVp2mX2oz+jaQvK
/cqrMBsTvxB8MjKQHNuw6eeQ1EW9L8p/laIh9Y1gI5PSIb0pyG6yR/I5h5dT/Nep7P7CEfVl3/B7
w9JjjjjQJGoRFFFVRQADboMwnpAANguxS7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FU
Jf6TYX8TR3MKPyBHMqpYVBFQSDvvkoyI5NWXDGYqQYvc+XPMmnO82kXpljFOEFxLKw8D8MajxJy4
ZInmHWy0mbGbxyvykT+hSTz3rVjJJHrGj3LcaUls7aQxmor9qRx4jD4IPIrHtGcTWSEveI7faUVb
fmh5YmUF5TB7StEh/wCTmROnkHKx9oYZcpD5j9aIP5jeUQKnUIR85of+a8j4Eu5y4zieRCCu/wA2
vJluCfriSkdo5IG8f+LB4ZIaeZ6NggSxrVf+cgvL8AZLG2uJZRXizJG0ddx1WavWmWx0curMYiwL
zF+dHmPVw8UcccMLVACCVDQ8hvSVhWjZkw0sYpOKFepiMWqarLcGQqzl2qwIcjc18cyKDp9fodJI
EkxifLhHezew8r6/eyrHFYTqHrSRopAgoCdyFPhlUssR1eKxdn5pmhE/I/qZxoX5Rzlo5dTlUL8X
OONjXuBs8XyzFnqu53ml9nzsch+X7Q9A0ny1oulJxtLWNW7y8Iw569WVV/mzElklLm9Fg0ePEPSB
8gmmQcl2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KqctvbzCksSSA9Q6hv
14QWMog8wkl95F8rXacW063h94oYVPb/ACD4ZYM0h1cWWgwnlED3AfqSS8/J7ytPC6J6iM3Rh6Ip
Q+0WWDVSaT2bHpKY+P7Ekk/IfRiTxlanuyV/5M5Z+cKBosg5ZJ/6YtJ+QmjV+OVqd6Mn/VHH84WY
0mX/AFSf+mKa2H5KeUreLjIrysTy5MIWPQbVMQ22yEtXItkdIa3nM/5yeaf+XXlGy+zp8M3vNDC3
h/kDwyuWeZ6shpIdRxe/dkMVtbwikUSRgdkUL+rKiXIEAOQVMDJ2KuxV2KuxV2KuxV2KuxV2KuxV
2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2
KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2K
uxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2Ku
xV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2Kux
V2KuxV2KuxV2KuxV2Kv/2Q==</xmpGImg:image> + </rdf:li> + </rdf:Alt> + </xmp:Thumbnails> + <xmpTPg:NPages>1</xmpTPg:NPages> + <xmpTPg:HasVisibleTransparency>False</xmpTPg:HasVisibleTransparency> + <xmpTPg:HasVisibleOverprint>False</xmpTPg:HasVisibleOverprint> + <xmpTPg:MaxPageSize rdf:parseType="Resource"> + <stDim:w>48.000000</stDim:w> + <stDim:h>48.000000</stDim:h> + <stDim:unit>Pixels</stDim:unit> + </xmpTPg:MaxPageSize> + <xmpTPg:PlateNames> + <rdf:Seq> + <rdf:li>Cyan</rdf:li> + <rdf:li>Magenta</rdf:li> + <rdf:li>Yellow</rdf:li> + <rdf:li>Black</rdf:li> + </rdf:Seq> + </xmpTPg:PlateNames> + <xmpTPg:SwatchGroups> + <rdf:Seq> + <rdf:li rdf:parseType="Resource"> + <xmpG:groupName>Default Swatch Group</xmpG:groupName> + <xmpG:groupType>0</xmpG:groupType> + </rdf:li> + </rdf:Seq> + </xmpTPg:SwatchGroups> + <illustrator:Type>Document</illustrator:Type> + </rdf:Description> + </rdf:RDF> +</x:xmpmeta> + + + + + + + + + + + + + + + + + + + + + +<?xpacket end="w"?> +endstream endobj 3 0 obj <</Count 1/Kids[7 0 R]/Type/Pages>> endobj 7 0 obj <</ArtBox[0.0 0.0 48.0 48.0]/BleedBox[0.0 0.0 48.0 48.0]/Contents 191 0 R/Group 40 0 R/LastModified(D:20161013192721-02'00')/MediaBox[0.0 0.0 48.0 48.0]/Parent 3 0 R/PieceInfo<</Illustrator 192 0 R>>/Resources<</ExtGState<</GS0 193 0 R>>/ProcSet[/PDF/ImageC]/Properties<</MC0 189 0 R>>/XObject<</Im0 194 0 R/Im1 195 0 R>>>>/Thumb 196 0 R/TrimBox[0.0 0.0 48.0 48.0]/Type/Page>> endobj 191 0 obj <</Filter/FlateDecode/Length 1243>>stream +H�lWI�7��+���0�L.W���|��|�!���#V����Y�}!�����>�����F¯�����}9^~���/�%�Ԧ����||}O�#� Rm�W�QO�z�< ���JK,E�u@���x������T?45��K�Md�(q��ZK�dhXʫ/ގq��X?�[]y����ռ����Ǝ ����qQd�ܞ��ۨࡴ5m|�{�8���'!�lY���� �|��08��3M@o��!dk*!���z���&�������r��gD7����夨R��˺�v卵�]7���A�5���u��ꂺV$-�U��B]��ޮ���)��]����}��j�,�>�?��(��P���z����"kҝ�!CH@��J!z�+$&��7Q�MJh/)x�t���3��C$�\� �o�W -�,R�e$~�u��˺��M���;\֨��ڍ<,����-�]�=[P Ws�zExx�4|@����~|��찡�L[A��@:j��$���<��n�w� +&�(�2a�s����D��L:B����]0'����A�����B5��X�µ8��=�C���.�ʗ��&�5��h�x��! +Ĵ��ZmF����K��@��uk��x�adY�{t�na#7ewE��$�ð����UGt�@��d�����6tLg0a-Of�].|�96�-��`y�4J��g�Q�:�����u9{�]� +xY#�,�7j2L�>N������"XMtkW�6foWiaGZi� �ت�"��Fi��x<a���|��#���U�������d]��=�xw���s.d���v�,;A�Է8�ߝ�g�HY�� ���RY�H&�MW�KTl��9�ÇV7V�1�Z�L�>�FX�ɝ�h��&&��T��l���ѵ���vB��p�� ��/[N���>�b9�Q9��/���V�3Q'Ҏ�qy�z��'DOAi;%(��=]@� �z��Ѧ��4xـ|�:T��tF�+��N\���"_�ځCZ�U3i�O�������y@\4eC�h�iSQN�+�X�� >�ơ��:�K�×�������0c�.��G�v�3�D�n#5iuz"Y�v(�f�1`@u���Ew��{�i{-�{�ٿk8X�:r����ł1�w.LՏ���*�M��_76�x4�DZ�~��N��i(�s�@�#��#���R�O���j� +endstream endobj 40 0 obj <</CS/DeviceRGB/I false/K false/S/Transparency>> endobj 196 0 obj <</BitsPerComponent 8/ColorSpace 197 0 R/Filter[/ASCII85Decode/FlateDecode]/Height 6/Length 54/Width 6>>stream +8;Xp,*=NntbilQcrP\BEq:Dh)?b\efqXp)5l`h#3lMpqi!97E),l~> +endstream endobj 197 0 obj [/Indexed/DeviceRGB 255 198 0 R] endobj 198 0 obj <</Filter[/ASCII85Decode/FlateDecode]/Length 428>>stream +8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 +b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` +E1r!/,*0[*9.aFIR2&b-C#s<Xl5FH@[<=!#6V)uDBXnIr.F>oRZ7Dl%MLY\.?d>Mn +6%Q2oYfNRF$$+ON<+]RUJmC0I<jlL.oXisZ;SYU[/7#<&37rclQKqeJe#,UF7Rgb1 +VNWFKf>nDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j<etJICj7e7nPMb=O6S7UOH< +PO7r\I.Hu&e0d&E<.')fERr/l+*W,)q^D*ai5<uuLX.7g/>$XKrcYp0n+Xl_nU*O( +l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> +endstream endobj 194 0 obj <</BitsPerComponent 8/ColorSpace/DeviceRGB/DecodeParms<</BitsPerComponent 4/Colors 3/Columns 630>>/Filter/FlateDecode/Height 201/Intent/RelativeColorimetric/Length 30600/Name/X/Subtype/Image/Type/XObject/Width 630>>stream +H���gs���_|�������9G��9��@H�����s���p�������$\O�UO�L���^{k�>J��vP-�4}�f����j4�?[V��5�z���:�Ɩ�`���6��64P����T+����:UL}�ʮ��W�٪�O]e-WQ��&����D�e��ʪ�S��]�`��ԓ[&����:E��ɝ��Y��\���X�%\U]��T+nT�.�U�.]�q�T0 W��W���\.;grIq��r���Ӳ�ɟ��[�S����Y����7�ٍ_O���Yr'ͮ�_�����߅�7�r��J.�DN)�鎞��cNrGO^<��c���ϲ�GN\8r�<�_Ņ�����9�?���Y�oɿ�cg��g����������ҳ��� l�dde#��Ŭ��tk�,�叒*,��H�&�V +X\*bA��+�Z��I$�x1�Ek�Y�,a!�H���-E)m�p|)��_bK�1��X*K�R��d0�d�Yd���9m s\r.�h2�-����?h� >2'3&�$6���^֔��y|Q��������l�ʚ)����3opy���0枓�N*F&f%fX���:]��/s�1Ǩ�1�c�4�̈a�V�3N�O�&��C\������� ��t�~Og���е�M*z'ۄ ��kմ0���.���i#���c�4���FHC+W� s-B���8����Ycw��l��m�������s#3�T�*���a���k��U}wj��B��s�Zq��t������.9o?�����������7�ן��{�UQo�YzI^�E�z+{nx���g/ +y�����-=���+�QaO_=T���|`���쾥G/�=W<|~7׃���3����f��]��]����c�=nK���hc��f����d}�[˵��Yͱ�y_���[��dL�jiu�$��Y�#I�bfW��ޑ%KB<�-�%�d�E�iYؐ��u&���ȼ&5����b6�B*hY�f�M�L�q�Y�� +�O�?�������E���47�syI��M �a�����$��9&���r�� 4��h��3��3�Æ ��#��54K:u��}@h�s����q-�Bs�4�ws6C�W����ݽ_rvۿ������?Ѯ�Uľ�͝���.l�d}����YĪ�Ǝ��|ַ�rA��\[LzU��)[�#��kC��XX4��eK��H"�7$���� +�YPD��Hb9, �s�2�|,m�*�"d�̆MR$R��M�>fds��2=�� �?�vJ���en7鋹}1ۙ�{���tT6�5D�qÔ�Ҍy�[w�dt�ɚ'��� q +s��%�f���\f`D�����\/��B��{hƤkp�t���t�s횶�)�^���p-=n��k�ٻ[פ��L4u�q�ȴs �6�o긱�2Z��iv�Z�� U���I�h���C7T^ϕi�N��j� +��s9x�˗���#�㞥�&�3�|��) _1�S/�I�z�m�LA�r������TV]����)�jYR�*�'���*rK*ҙ#��4��0�x&$��刦5KA�S5��% ���5Tf�TJ�"��t�D�4AxI%٘��$'�1�����2RR#2���Sa�"��:���z:o22�I1 ��5G��Β��L1����T�LJ�7$�&U��()�7L��>�z�J1��� ���{��ޥ`U��au �Bi�[�Hi%�-#����u��6�JSisT6q���V��AR���DaQ������(�Ud���ZDV6}� +�`YX��(�X��ta +�"����5y +�ݰ(, +�¢�(, +�¢�(, +�¢�(, +�� +(, +�¢�(, +�¢�(, +�¢�_���EaQX�EaQX���(, +�¢��RX�+ +[*PX�Ea��¢�(, +���¢�(, +�¢�(, +�¢�(, +��b(, +�¢��U�1�pV��EaQX�EaQX�EaQX�EaQ�ҁ¢�� +k�W�EaQX�EaQX�EaQX�EaQX�EaQX�EaQX�EaQX�EaQX֪�����(, +�¢�(, +��EaQX�=��-CaQX�EaQX�EaQX�EaQX�EaQX��6�¢�(, +�ha7Q�C]Xܰ(, +�¢�(, +�¢�(l)@aQX�EaQX�EaQ�/ZX9�(, +�����W�EaQX�Eaqâ�(, +�¢�(, +��s�¢�(, +�¢�(�!�¢�(, +�¢�(, +�¢�(, +�¢���EaQX�EaQX�Ea-�¢�(, +{����-�W�EaQX�EaQX�EaQX�EaQ�藺����(, +�¢�(, +�¢�(, +�¢�(, +��~υ�GaQX�EaK��"�(, +�¢�(, +�¢�(�a+�Y�EaQX�Eaqâ�(, +�����:j������l�m�z�����?�N���mg�;�zp��rԣ���z`=Q�$$ܐ� ����#��#!B$$�]����;⾓��.A��~��|'��y�oxx^χ���v^�5 0x��r�$���O +K +�S�C +K +K +���5�FL�N6���v� P�����+,�XoA|��g�,),),),),)��4d~����f����mG������}'�7�&2J�&�����zx:�RI�n@�R�+:�Ͳ��&i����+�"�p�B4@J���D����3[a-1Iag%l����}u�ka���o%���b֎WR��&,�+)��8(�gPVP~���ޑ��iA�a|���X�HY�!}�SCJ�a��܄����eU^aqin>��������ʵ&3;oҼl��K�/xPT��Ԋ��r��V��o(,d��ף���E��E +;����9�r���]�$mklj54�����jn-�+���K˫J��HE��'��A��AR'���mҶ�6��� +�AX�T.����5),),)��04����7����o�h!⼍�љ�v#e�ZʲU�k_w�[ 詫K����ӝ\�[m���;n�s��ᇳ3�,k�3+'?;�`�Aw���UTZQ�(��� %�$��h�+�j�R��1em +t!��JX�l��fW�J�Y����"L�`�)�X�ҼJ.��4��,�Ba�8<�� +=��.ҥ�QXE��+�� ��3Xe5���v�k}�ܾSR%��,_���@{5�ϟW�����$%w02��Y�d+� �o�_��9v��/���k7�88��z���[�C�Sg78���w����謄5���k��!����5��\���wvk�ơi����ڗ��ޡ1)��v�z�K+�鵜��|4z�/1ZI�m�B��va坽��d���ԉ[�.),)�֖�%/�apX�ڞ���;*i��P̕��My���!&VS�����h�ϓǞ������~�l����A*��J,��g�|�ږ��j\i�[���;o��-�ݳ�� �3����5,vH�#����R����R*�1��}��`�FI��$���b�^X�n����"��.W�^S�h�A��+���-`�Θ�A�XbE�-�L'%\��H�ީQ��S���������8�z�K +;a������G���E���j~kC'����?�IQ��|:<b�s���������{���ݱ`LNgp�������xʼ� 27:ܾ�|L��O�7�����ں�4ڵ�7��.� +?s�؉�����}�����������ٳ��٥1������hę��}�ƭ��{)��W����ݾ ��+��5}�X' +�**�z���Y���x�7��N�a��� +v ��<c�� �gdc��R�Po''&�MLJ��t���bb��ל܂|f!�q"�X��856�)&��fa����D�#G�>!m�BRXRXR؟������[�KX���VS?\_�����=���^�:%�o�W����'�uiY� u�:ʲUfj��W�����n����rŀi�ͅ�L�~}tt���������7<%T��5���w�=w�*,��={����� vuu�� =p⛰KW�K���ؐ��P��!��|a�h�����#�GGHa' +�e)c�,N5��?��cǿ9|����"��{pLJJ�O�������:t���G���>#02�'�y��x[�v��&�MRyFV����q�����'�SR�%)�=����N���&,��%���9�|&N���No-W��)*\����C#�l�^�� +� o��@�#���<��e�1�����P��� +���};)�F��+`�9�j._"miWv�jED�i.3�Y�QO�>S����+�{/����;v����>>&%����٢���~�-�x���U��i�iTzTt,F� W~0 �UX{d����J�k�����yyz����c9y��y��v�qh���HPP�a�&\Gc|�{�+Enn�h���S���H��3m��ɇ��+{l�E]}\A=���V���@��"�j�RXRXRإ%,l�,_K�`M}l���;�u��>{�O�TV�'����r��[ +�s��x��"��a��K"k������C#��aC!zL�i#�"؇�-���°�����;U=�Vy}��UXw���'0p?�&�8�"+�kD/�2o\XX���_?__0QZ��gV�3������?���4��;ga;��]��T&���������{����d�8<�@$ԉ��F�bb�!,���}�>�'dd�u�\dLp��^�7$�K���hl[̢���%�E�j��;)���A����f�u +a[�5P�eW&W���|��n�LwrF�<}���Nt?O�}¨��Vs=�Sk��I���+킏%R���"�md�V7���/F��æ�Q��*,>v*�Z�Mgd�9\|Ik �T�+�jh�ظ�بAFJ*�G������v�{[�QC���,D����6'+oyQ��-RX�ve�D���Ֆ��sX��"� +fa�@�خTM�� ��٭U��{�����У��ի4z۾�nmqY%�j�g��c�L�8��l6����l�fg'�d���&���f���&3*�P�]V�Un��AE@9-Ж +���A)Ж�����(N�;��f̎��Z�����Ҵo����}�|�/!,�^�KDzӸ���dž��z�$ܬmlcp��'zyy{{�fe3���&Y.�[*Wi��ª�kZ1��7o����!�2�����ڻz��$��� +K���Q��44wt�*m���������:������?�x���0n]l�) ����+*�ȳ쭎k/�BUm���t1aQ#�2�[�,�uzc!�w �'���'���$[U[���;�B�exE��Y�z�I*�1���l�_���~���+,���@���f���N4F�l�@�Ȯ\Xji+��PVYc#,�/�e�:#QpS�����Q��~_��W��MHL*�ɞ�.]=2��C����.)L$.��_PU���W���uQaj�k�9����!f`���ʻz�����®P�Z�������y��Ĥ���ފ�3��u�������g��~�ٮ�����W�tvbj��OV"�cA^FfN����xE"�\VQ�'W�NL-m�$�m׃^�Ew酛6Pk�g�]Eaq�jP_��Z�)��_�� �ٟPXT}c+o��fa�ju��>��ƭԴ;�c^��+�$�u#�6��'��p��ZH^ +^{�ڪ�&�U봬`Ʉ� ++�s�������ڹ��-�M�Ԋ�H�v]�r����?~a��a��;aP �{�ʅ%j��˻Gl�E\����B��X\A0j�%%�4-�aqV�6�0ꞌkb, +��(�'���~'#k�0b4/c�a]*�HRa������Xf~�qԲz��5���D!ժt�����{B�Ut!.����uVX� 3���q���q���X�����W��%��@��e�TZXZ�7O��7NX֯����O�*��E�Ŋ���d����v��"ɪ�vH��=D��+��*Iao$�89974�-������ATVɥ��بKJE�y��;�.~q.8�칐����DZ +:�.�Wi��:��{���f���ظ��!��h�lȭ�4B|��*��<�� �y®�E)�&��HyU-�4�G�\���6�BC�����,���W����0Y� +bf�d�!a7o��k�.�zy����Tô��.l-,-� �z{��� (��mt]P�f�-�ö:p�8n|a!�(�zyy'&ݘ|4=26Q]�0/��gg���a���<.���V��������=�psswu=�`�;v��IWH{�\h`��>�r��z�~� +����GK���̜��Hoo_tu萻�17<<��M +���e��� k��u�m��[�����)E�%�%V��p���i#����[:�o�3��Y9!�~~�0'�K��I�I���y>�A��_IKKk�²��*���M�Wj����䓜m;�Gv]��}a�J g.T��Qo߰���'Vak��URAM�r-)��� ���G��CBï|�p#9%%5�Cɰ�Ca��=����{e/�W�/�GFE�.<fsqv�&��� ג��L��I�O���#�Ժ!��j"1WE��at���7��Y�����Y3d� ++��cb/� �����Bz���u>����cn�||��£.}5>����j������*iaiaia�SX֖����=^"�>��?�W�&�������Av]��F��J���~�<l��e)a�[�����*�BqyL��Ҟ�G�Q#ݼ����3��"TNLM�M%B����z � ���6�u��Y@��p#`"����-U��јy|�_�&�"��������̘���[���5�K�/������._8�](ll�eRX�� �iJ�eԙ���!a���ף^>�Lv}3�f@�V��ݽ�Ft��¾��v��nha��v���[�����tC�Lf�����2�bɿ��Φa|,���蘽�ݥ�]ka���A����M�;6�����LC�����`��v��'g�!d�mli'u&�ktL`�^��~8��M�qt�2=2f1�N͓���� ī*�Vo��WQ),��:�@�����32��8j��8�`F��>ź�����;|�+#��BaU:SyU���$�<����{���a���&��=��<�e��j�r�|�J/S�T��·������C�{r7m��^�W���������a��6���ɴ�����Oυ�;9:�س(�k/����+Eb���v�����E3,�����b�B5�-��i��q.���/��p����h� k ��]=TD�z��Y4��8u�-��Ggk}�m�6��I[��:S�R+�T�X"_�Oprr~��Cs[7o�["������{zxxzyy�e�U���PZXZXZ� $�=��[��ҭ�>[\ض���|���?���^�x9=#�nf��Wj��Ʀ�E�X��z`��{�]��Tk_��J�5�[�BObl�Pu>{rBb�����X��x��-WH�8�#SOfr��Z +:�F4C6����vss�����NӘe��������Z�"�v�����`��\�pP?����W��S�,"����x����4��t#V[��������h²�z�l�������b�������}�~�wo�� ���=���Ҿ�zEom}'�7����z j*=����Cg��v��Q��z��nۙ~����v�[.� $� ����+*�E�"�&��$D!$!���X�;���궅��#�cHbt��sf�q��=�y����w�EkAX���~���nIy �8��gג�r�jGX\�Ti������-�����}'>��u��Ս>�Pm'%߀����5l��b���:%�)��(l�$����|}9nn��F�B=jSX��u���˂ڻ��fy������]n��^�[��;�~��Ta7m�W>s/z����[�yjj�ի�,֟��n�]�[pa5z#��w �J��F)��w�uqq���ǵv���]b��6 a�<�Lvꍌ���\,ahMm�LL���� d���MZ�u1�Uj�WX�aP�-��.){�/�+�����!�������w�+C@y�+�d�J˫��7x������]n����W� �m��FE�.a����[7o�Z��/5a�#��ƚEm?����;��w4��|D��;�x����<������L���j�al¾��LXxWU]K���������a�y%�Z��*��!���QH}�����3������),��m +{����(Sk� +�����}���u!��~�Z�o_����*���/,柶mK[���$����Q�3vK��ȧ�:'$&�1b�gd3���� .ή=Ҿ��I[��+�d��+,�L�+Dcx���h�nDcx���G=�~���&�\e�)u��Xml��wE�6.-#G��v�%ߦ��2A]��C +�%�ofXQ��|�������]���X1RZ6m���+,�y||��͛�lq�Sq��9D +;Xǟ�O<U�LPS�7'5*��Y9��`�=q��Hz�&&����&��9;�?y��^QP��GJ6�?��Oa�*]��)왳ѻv��gf�'5�x5��j�IG ��������?��bp��p��&&��U��Dh��k�scs����F��v��r=9]��`)¢p�Ya��S������]:�r?YY�����WSS�"l�2V�7�v��㗹�_�[<a����3�է��e�&a+I���1K|L����'���{Jj���g�v��m�'9��s8���+�vbH>B�;�>u:iq^�%����䠀�?p࠸w@g�%��*�X���h�}\��/���[0a�s����w��5�R;#,��I�`M�鉨�KP�g�+��F�*���BgGXو����\< V��C��kSX�ږ��� ������ZXZXZإ!�Ϲ�������B��3Q�HX�<����o��Ͷۣ7m)Z�8�b�N��rsc��?����Z�<�rH���.\�������*�s�UX㣉a��WTB����G�'Q�GO�E|�-���L��S�(�n�qG��j%�:TZ�~t!ע0Db����*�,��;�0�������_V���?����ڻťs_�paTL��b�=�}��-r��-�*��v1ue���A�Li�� +�C��T�0����Fa����$��!ZXZX�%x���p�r�Z������za�:9���E��Aa�5����٦ {��"��k�W���J"�� ����쀀@$ ���Ό������Վ��1�I�J���#������S�THT{����s���g�b�7�Ī����UU�66�ڻ$]�^s���v",����LX�=v5!��Kr�^KY���V�.����;Ln\IY�R3&S���oAaum9'�#AU +j����] X��#�76� �ܵ������uXX:�~Xao���Ì,G�r͋D��n�zǎ�ux",Jg{#��(�����y��(d6˃��pqvMLJQ����1V�5j�,�B�&܋�^�5�´.�#�H�MX$ӁA9��X9��A���pyhhX��'��K�_Rv��WTb��FK�;���:w����76�����Ԛx%��vP�����01��-�];+Sr���Ta�iaiaiaC�����>Y��;`?a +�W_���?$l�T�P�>���}aq2�p�gd��>����D:z�X��m��3�c���� ��Ta�;�P�H�4ڷ�YF������� +������{�utϗ�(��cakG��\��Ȼ�����C�=�@��@�vK���F�&[�{w�j��A_l��������7���Q�W�Li@}CX�YaQ�Cm�03��;�U[�Lȉ0���������#��u9 +���ߴ�G��&>za���_����bmܱ=p� ,��ohB���Ha��8cqަ��G��9UY�܊h�d�sr�r�b"���3��:�����]����F��y��8r�n��h�YD�2�T! v36�BBBz#�<2�5���| ���Z��k��Q�E�����V Oy6+�2>�)�A�����L�A���'3�U����������.1�llvm�N��W;��$�a����B~ �R�gwscP�T���._I������Y�|?"�,P&������`��-,-,-�b +���j�h{Ǵcv�K��i����ۋJX�al�fd݄t�����Ğ9q���~y�����fy �����G4�qt|�̫ua5zc��s^ONݻw?����*,�d��p�c@Tt\rJ��[�[��9�J�����B��ه608��E|q��� +Tߩ�Ga5�1|�T�^������ed�P��35-3&�<��������{PSWpf������ԝ��+ *�Zĝ��]��ζU# ��V�E@PEm}�""�<�#�/�������$��Pw;;m�u��ormPP��|�=��ù'��s���T�����y���mh�#a�\a�����KQ.�4��i���//������F�������E0�k���>-�Za`�2�n��>Gu��h��z�O�ָ��3Q��+s�n�C�}�+��yϞ�X49��@��mDX",ր�&-6��ק����х$��˗�[���Zo5,�?8����m�ngGX0up؉`�F�ߺu������Y^�-���F �/�����2� +�ivr�(T� +�s�RZVx�O>�w/��!�����&ض�w�LЎ`�͟m �8 �1���F��� +K!+�*��yxxm��K�d�Y��v���A��|�_�F7�����nn�a5Q�s��ⓢ�]8!9y64,���>��"L��`�mm�����/,� +{(]E2]^u�E����_]�Y�w��"�� +K!��Փ����VƎ�^�q+��bev8���d�e���7�g*�.�DX",��M��k��_������M�L�f��ي} ���������:v<"���+Wsr���.���ԭ�l�TX �C���6���DO]^u+Yjnaݎ��"8��!߽{��E��bu\w{z���={'����+��0O�#��� +�d��ZX +Y�\g�*j�vt�Գ��ډ/��G���E$$����\���}����`�����"T(Q��8G��Av��z ��}0�xpBrzs[�@,��|���uJa�i}k����L��f5O(�V�l7zʀ#��:�|��q�N���fe�q��������q������N|2�����.d�z;�b",�k(a㍌Ĺ�MX����.��Ywf�e�����ʕB�T$� +Ž�|h����C#mX_"���!L���D��LX����#��!6���������������8�1�L��bOУP O���uV���A�o�ؘ���YQ��W�54�r�"t@�2%$�);yB���Z^�BX���n��{��������pT�P��Q^�� +=E���9�H��"���#4�tjy���W�r��G�披Ze5��2zq9~�W�4�C���BY'_��9��f���+�K�5��w��~����������Yc����4= K %�SBXl�S-���Li�T�j餀��W*U}Jt�)��`�O9�9�҉�3��9V1:�U�ҋ�U�CR�XSPKi;��R�"%{�8�p�-�C(H��N_X���IQ�b[��Da_-艀c䗳(X�Q��C�������K���&-Y�i���G�GG����|dni�j�����M��AX��r%��"������^$�>��5 ;�PhN]^U[U�v�hx��tb�BXg��2*�`���Tty�LXT� �c�w�؊h��+�K�5���Z\����=[`�>z�x�� +�?�X�:�T5l�RUPT����q?�FVn~Dy}5,vN�ՅUoªa���sD,�������3����JZ��f���i�%�a��6�����DM���6�oa���NN�kV��^�0���cd��;[�V���Y",v��]iW����SRV�W��ʡg����u�m8�����J���%*��G7<�����ʡ�%�DX&v�{����l�9ca�y ��'�X�Z��ڵw��H_<���64��~v^�݄�7na��ㄅ��]B�2�~N�&�=Cm��7��:���ܞ�.�(��m��-�v�z�ki�Y",�ka㍌�ŌY���|��GV+W�Sa�>}����k���Eغ����ލOܼyk��`�K�����5���e��at�D�E%%��"F9j[���ë��� a�u.�K�կ�IK�R�(��g!�@(���ǖVV�QX +٫W�-3_���c��3%콤-[l�R��F��DX�-lݺu�d�-o'�z���5��N",��oa����TY�0a�l�4��%dee��-]om}c�!������tep�!�K�QZ�R^���9��w�m�ά���%DX",V��*�.a[�-,�Yfljbacsu����MHJuv�u��WDX"�a��n�Y<ٹ��Г۷Ӯݸ�G�%�a�K ��-ذq�&lj���װ��LSc����ŕK���-�ܬ\zVN>���Hդ�|pk�k�o�����p��-",��wa͒�3����B�A���E�^x�Q<B���1+^3�r��E����\%�����z��料DX"�!�Y����u:2*<"24,�����_���3S׳8 +����������y�f_TR��K��DX"�>�M6Yv��H�(����P� &&&%5���ne�Eb����#��� +��_��Y�r�w��wttZ�B ������&�K�}s��H�<[����;:::9:��nGCB���%$���QJ[m��7%-���h//o�����OE�cu +:yb",��waӝG���R����g�]��L��q���bL"��*,G�l'_���p����dxdjzNCs{�鳨g���/_�:!)%)%INMOLJ�s;�D������aqk��6 �l�x^��DX"�\��λ-��9��=�WXL�O�K��r%����UF�ga睰����_�M]w������M���B����&m��N��4e���� +]W�D� �_k�$B�g�v���ӱ?�����y�u�I�C[��}I��'q��7�ɺ9��s~��:����������l>�Ջvf��?lژ�e��;v���p���o�/ �������m[��Q|�#._�3��&x��}х��+%�!읗�Ņ����'�I�����TX���lNC]=�K�����4�N����"\��>36���9 �;0��F�5��R.l0�U-�h�s]���Hɞ={�+~B�Q��ڷイs�Ei�ޮ�x����!^)a)a)aS(lU�\���?y��(%�t���vx$"�H>����0��&�^-�I���+T�4Lv=:ܫ��c��0saqMڍ�mN��l3����v�}}�!�1 n� ��ܾ|�nKX�l�P����)���SA��v��h�՚zu&|� \�u&TEt#�� a�j�f��d���F �Y_]�b��VT��[qA�: a�3Z���u;%,%lbai���ET��=~��<w����MM�3�?���,6G�R��.m��5���1�MI[G�\a0[]^j� +��9ܰ����-�%*��+ 1ف�0[d���du�zT����L xx������7K����t�}$�)��kw�;��зK�"1�ID`���mD�ȝ����@P�5Iڤ\�kd�q#��z�v��U*Wz��hs���zS"����'at���N��I�����<6���4�����[� +� 8�#����CIXd +-�%<���(�Z�[��Z�Ƭ��Y;%,%,%lR��˸��6 ��zv���9F�?:����',���?@�P�-JE�^]"���5T�76E�8���Sa4�gi��^�ry�s�_�D6Ia����\���5� k�Ȅ�%tV ���G���^��z�����UՄ�S��kl�D<b�����V-� a1��T�ET�*�Xah���_{�K�1q��vi�Rc��9; a�V/��wuk�*�}��\i�4By�b8K"����UEXZ;�wp��� ���L6W$��j�S��Q�R�R�N*l�w^�\�4�b�/�|����_|�����h�� ���՜9Y�VMEX�nU�jQ��@��ȍ>~#���]��8|pp��?���"����e�?.=����C��q0�T�@UH�2�2�WM���T�i�n�T��c�=�4��]�* �����O��,�����.|�g�q�H��[Hd�$������-�2�h�)��� @vRa5�\�gsx ^!Ƈ -�E�ԫB�R�R�R�&��Ӆo�\X��g;p�����]�n���kV�y��ʚ����i��~�RV���իrV�ryA&-9a�{6��Y�FV��8x�',�Ӗvit���[�wl�-�I +�dq���v���vu+�ubaCE�Z�#k�����V֣������h6��h�CS-N�'���������I�I20;��K�@6Ia !^e +�r�3���� +�� ��\�]*��Ir#��v��6JXJ�HX��g&lU�\�/~��M)�V�R/^�xy��e+r~���� cӳ�܌��3�Gn��-�ܓ��NF�̬�K�?^��M�M�\XT��%TԤ�� �,��+,@�9ܨG�����щҼ�|b4�ƅ�p��1WEeՆ �Zۥ��� yr�D�-�3~�#��7��GE�d�13d���O,,�Մ���p�G|�8��wRaѮ39E�)�/�{-����t��¢z�kB��>��勺�&�d���R�R�?�c_�4�e,F3M?[�>{��e�s��e|�v<�"��$!���H�R����>�)��cLJ +ۭP�,`�T�۵�m��|o���CH^�H_-,���}������k�������ӥ$��iZ��L ,n9<~�������,9~2�����J =uoPQCg[���m^a��R��Lv}I�_�ܥc�ha��L���k^�^��WI�)a)a)ac;/��w��<{n4u���z�}6n\���qv��\��H,,Zz =c��<<&�\]C��}~xh���� �����g ?y�T~~��-o4�ā��qaQ�F��a��i����x¢zu�}u����-��P��� V�[��>s��'�����p#�I���F�mG��O+7m���V;<����]�n%1�T�I'];�)>���'";AX��4&VwR��s��Sgv��ӫ�FgT k�44&�.��1�xGW�X%K ��+%�l[�>��zݓ�_������P��s��ݙK��-]F�Ua�,�;g��bb> �ſ=�^:�..����i� +8��oVܸYQ~��������W���8¢����1���VX�+//���Q���Džm��~��i@ {�ʵ��1�u{�"Iڰ��X��k����p�ȱ���d���/_���6���qlΎ;ŭAdc�jux�y��9��Tީ�x�꙳狋K��(>ZRq�nĆ�¾����ܨp� Dkw�4:s�R���VeՅKWO�9{�p19�ᢣ%�O ���ˑΈz� /;w���Rk�&�7ZX4��t̄�������*/\�Rz�l�+8\T|���} +{������Ukr�� +p%m�Z:3�z�y���0lp]�� ���ڥԒ�l$������faiiLf��-c:��dɯrrfIت9�o�����_�Om�g�����ui�����ʐ?�n��N�c$�&`���o����s��Ӏq1�}�C ]HHHB��ɛ��S_�� ���e\��tRy�a@���ݝ�����]�{_�ǟ�m��W�u[���D'�ΰ"���a��QUumvN�7�с�� �����u��?���sIɩ��54�(�h��SJa��+C����n�}� ��� _#x%�����ɓ_'$&�Oɼjt���̽U\R���==�������re2X..L��>�ƃ�B���Ca�=N��,*-S��U�lmk���dk��u/',쌯�?�Z_���b0X_}锖~�� ���KZ�]�f�,�X�ly�N������u���<)���w&���8��~&'����q�o��b�O�!�Lm%,�^�� ր����!��ӹ�����`���0�l�iVS� ,�D�.����u�/�kh&p$�]9yx{��do������b+�<^���\X|g����]X��va��-}�7���m.lrr����;:�v�^�2l�����3tC�q�q|�-����4������;@),xU��Z�6�{Hs�ht��^w�8�ر�Hj�,74|''g��/��UR"�n�::{�'ddAg�ÿ����ED����4Zs�E!�N���}r���>����b-�Zk�*ɗ��B�FJug{`F"l �@�k�c���`JQ '-�NBbrTT���㏆L'=�.4D�+5V���Mʹ�������}�w�m�۸�-4���+��R3�f#s�Up��¦gd���+��G7�;B\��������f<����/���K��z�Fܙ�X�K�����qꚢ�_<����r���b�)��ӦW���V�pw�x +Ȇ���~#>.������h3,I�)�������n����n� {m����q���0|����;z���]X���.l��Hزw���?� �m�,��VW�{�AG�<$G� +�kO��vi}�M����p/�K���*�5����){>ϔ�bo�B�#:~���>�잙Ή%�9��AKF�]����L�le*�����ђW�)U�����Z�,-�b ���tye��+�a�y�D&����<#g�Ξ~ʝb�`+88��#~"@a/=}��#��Pi�%�I3�b�Eهq*����K˖������ x��ȭh�X��/����vx��y�D!Q,*�j���w� +� ��-`������;)���qXQi���?#��W��*�R+Q@L�@$�ψG&fZ�[��s||��s[{�e���sR}z���).((�}���]��p��k��L�N +$��R�tqF��[{U�J؉�y�]�[�_P|�Ǐ�+$�t�t��o,�~APp� �=�7�\}C��)kd�����.�]�������˭��z�X54<�m�v��w�M��l������ŋM ^�~������ݟ�>x�C#�ހ�A���^��ĊV�b��\����ix���+���g���Q��i�]gV8��,����)�h���^S�9�f%�p^VG�Q�$""*00�JX�9��DL�0�o��N�P,��`��%=Q*�n��Ditƾ��z0���8�*�j@��W|�����W\��W��@hb�w��S�V��Qr��$6V���t����dR��ܹ����2�\����5/_D%j^�?���54���Ʃox��p}|���G���66�ѽc�ԴLw� b�8�e����˗�R��rV� /����%?tJa�������j���xL�._���.�g哳�i�?�s�CBÁ>��N,Cc�V�څ��-,�r��Ѕ�������ju�o�����Ӫ]����ԏ;6w�UϞ}�����r���?�n�8Ή$�\e�O����K�ZRZ&_PARe�C�t����������UKaQ�4�?&�����8�J��Y +�+�Z��6��Md4�1�~k)�~����<VRZ��H�F��?H�eAꏥT��@'�ְb���� +lpdB��a����W��ܼB�x{�g[{'Sj��\����sb9��0%5�x�nn� �)SB�U���e֒������XFye���7�x{�Z,��H�Hj�ڻ�x5�f)�L�?�QGT���&X"Q&ao/�䬬��!���AJj:��R/\�:8&0�]�������I�i ���h�/���k�\�`���V1��eo�:8pt����4���ow4��O�^�i�9a���?ܱ㐣#���b�����}��7s��YU�[}����V������#p<4�4�F���l5�>"u�F��� k� �F�l%�B�!_�~x3.�o�r��w�V"SR$�BC��Mq&:���鍔�R +������PD_"2���\�au�D0�6'��Je��{9�˸<2���&��+W.��S- +�9��Ѣ�����UKd^)�EI�Z^C3nn��h6�b�0;{������882YU]K�J�n'�bv\�k�o%�V�t�[�A�i�bpt +{$ﺼ��/cҞ�)|��R�ug�ȧ�r��S��_��U�6ۅ���cva6�"ƶ��������=��#G|�����p~�E�ܲ��.���ܻo߁�C�ڵ�,�Z�omk���QQ1h�..��*��h��x%�����K+�<2�<�h!,8���N��_q��Z,�JX�R��7�u����?����h�[;�nU�+r��iwgvfgv�])��U��"�x�**�}�pV��� �BBB�H�����v���^������u~�Ay��}�'����mhbS ���"C"�����p��`�"y�����ex%��%��6__?"�0�� ��z��r[��bf���/����3b\��T.a��2lum��p*�T��тq(5-�J���TX�X>���5���ڏ9 +��J��W᰼��"HH��H�Www��L�8,Ѽ�����]QE�CL������-U�WJayB|ʑg��wn%���&���YZ�܁�������F���ڨ���V��}NEEmݱ��nw�͛,�� ��=������c��ݎ����*��i��2���~�7r�nE~d:{�����W�ay�2�"$��!��(�D^FJ�袗.�CؓaD�%�˛����&��;;�'�+!�f\���F^fIiEp� �9a=���~#��I������ʻ-���:�Zg��u��Cb�� ����^��X���ZKX�:8,%�]������치Q�f����"�vq�Ŭ +&����T�xE�ʵm�� 1���lH^� ^G�:�*U[Eay]���إ��P�:"2�����K�@��kj�/(^*�&%�������������z�ڿ���/W헉eii雷n��n��-[�"��u�5��ة���\\~gg��蘲e[� ��b�݉ܯ�'�D�������v�y�PX(z2<(��D�4 +;a�����ݭ��<u���{Nn�R��Z��v����Ȱ<� !,2�\��kl!����A{G��ͻ���j�E�B<H�'NL��mi5���۟<<=��'b/������|tL�%�NO�<�����x5/âp�T�C��LcvX�^j��,?�cX��#)%��ZKXЉW���3^l�[�D�%x]VX) +Ȳۺ)�j�3��(���?���}Ʌ��v%�� fdY%��&lv�����C�o�Y.,��;�n�t�����=o�m�����&���ȨNݙ���������j��x +��28�CdF�\�X؞�~r�������8���Y�fd�<����4 aGe�;�/�D�>w>�6�D���(�Y"��^�u\?4"%�a�y^���qć�����A96a]aj]w/�d���" OON�İy5[X������ã����,��^�"�<��Z���J�c���f`Շ{��D����¢�hG��j9��_Z�{�d������D17�T��y"�[�,� ���y�ݍ�7_�ū��/���WY?^_��g�M6v�S&F�o�y�.G���*�,""��խ��ujf�Z�2Y徾~�!�dخ�^2� ���G$�L�)���Z�����Gm��\X�TAf��"Ced�`�ZYXN/���� �@S���ΥW��>��!�d��8lok�C�fb-�E5���/��[�)����+"�to�hD:f�ՊUP�p3 ����q"����J��������rE����2�0����XE�_m9���/���2�hb�8)5�--���ַ�JI�OK��X��ӧ��������m�����n��̬[]}�Q84��4O��%�-b�����Ejuz���S��?���/ 22J*�S�NN�4���-das�n������*)� <�er���Z�j��N�L2:�v���qr\?��5��J��2ww�ɰ�zB��Z]X�ll@$��m ;%��//X��.�X�]��Z{�f����T(V�B�N�����/(:������Kiaia�������E���`F��1�@֊,� ��������]���99%���t~�+�n��������0�x1��),¦hDB),���ƈ�������u9aY|����FK),���U�=�vQ���/@_^X4�SQ��������Z1k��3D����X�BM�\#a�8\ +�J+����]���k$,_(�"���k��I-ҳ�Ċq�D�=�ⲿ���c��(ZSgc�W���`�s�-,-,-�����*��@ +k���_������쳷le-!,���o2�hD��y����& ��i����y%8;s��MNI����(�����`Q�IMYy�M�qS3>���¡�xXXT���~���S���2��2������n@v-���d��/��R<<1�v�jt�缮LXTk[�ϓ���ƹ��o���t�������L�^�ٸ�S�?�kxxo@<,+l�ʄ�(� ����snn�\��\�����RX<=;��*haiaiaW�koT����3�_d����۷l��v�-��DX����74�)2�H����� +�=0 ��A���J���sa 3.�$�\+ ��������n�<��200�ƭ���O!, +�5����,-� + +:aa�]t�^=�7� /-��e����~�ו +Uh�)�<��B�(~Eޥ�켫]Wi-vT��+B[���$a���vwgdd��a���~Q��C���"yu]#%�8�5�;�.��������JZXZXZXSd���O���g/�X�����`�`��������v�,�af�A'9B�)��u��vjf�,ay!���fd�9rt�~W��0T],�`p�vpIĸ�K��q���P�֒�=W�����'� a�C�K�q~Aq/O��O�NX�K��8}��z�|�\�]����/נ&�4�w����vvfYwۭ��V�����_���*w���B�Z[�t�����^AQ" �� !$BHȅ\Iȕ$���3;c���vu�ɩiL��:���y��=�y�9���4�4\'�vfÆ�Z�;'&g( K�W�˫�(�N�q��mcuQ.J������7��� +M߀��tF�#��r�.|P�Ӝ��� S���.����b�\B���(VG����Q�}���_�L����~��dff=~R����'l{���a}��{������E�,�z������$1���X�lE]d��Fo�or��2�DIX�̜��l�(�(A��KK�ؽ{�� b���q�3��+���c�V�@���'R֯�ܼ���w��W���q��6�@Z.���#�`("!���,����[��$2�gzA�E\Y��Ȅ�BX��#�R�>����f���Ya��ls��}�O7��A�� �R3Fy�8_|1+k�ť'x���Z�C��#��D� ;j����Hۣ��M:��υ�$,�k�O5�+ג�S~yH#l��1�FP�K?�fdݻ�� +Y�������-_�<1��:�q����/�!�p�QV!�����Q�4Z��tb�ؚ�X���ႂ���Բ� +��D�VGW7%2���G�VDŽ��q�'�[�f�B����+�~�yA�Ef��p�L����S~������1���~Ȃ����pJe�08r@��o��%�jE���AQ�����" i a� +-�F3�� �U�ZP���!V?f�(���fKS+K"S̎q�ܤ',a�Zg�p� O�X0� +�oAX�?�wrz(�q�� z�SOl�|�EW�T>�o)���d��7۩�"��d3��[$U�TcK$���Z�Ú.Noc��� q�Б���'�)41��a����s���q��^4�>���������k�B��$�wvN2$���X�l��B�����?hf�u��KQg"U3<aQ�����[�' O*�����csy�nb# �x��99��zS�����)P��4ER�ظkr�� yh����J�՛�a�hhYd�D�����+�קP��P����Ĥ=���am�:�R9"��;!�aa dEb +�V�`sE��d'�5�\��a��l5���6�0@��jt귱.�`�A�D._8�6�9;�79���O��J�X_�1���ۙ��[��L�Q��G �Mǵ��� Db٨J��l@�*��L��6�F���o;v�JMM+�x>7F�ac��Q�K?�NI��������o�����z��I���V�,]Q ag�.��$U����j�@-���c�l����~�( I'����˱�S��5[(�4�D3Jp�;r�/N�syg a!�wvD�� ��-�E1�p{�RوJ����J��+��0>8�D�<>����n�z�[�g�Y����Ѝ�����J|#*�:ѨnhD�'w�����h���57>�`[8a��{���`ZY]�ـxxxdT��@C#j���#�;U'�F���s��w����X��DSs�# �7���`�_4,VKej �\�'�^ak['�_z}��t���v�A냬�������W��i��tu�9=}<���t�y�U�f��g����y���N�\=#l��1�ҋ�r\����p8}�}�\s�XW�ݱ}ǎU����&��^}�w+���$,�{�J�N_~Qm`'����Nv�'��-�p�B��s���O/a�߶m�\1�"����� +�Q�L�9H�[�/�Ulܸ�ry�{j��`�ҟ@Å��7���aݔ����Ʊd�$�D:�*oxw��{�+,m�|���q�E�,L8{��%��r����+ʝt�k��D���������~"e*s��1��;����75/�Y[���ϥ�%lu�=����}�U�uMcucg|B����x�!,4=w[ �[Rj'_�6���©-��H�Ξ+ٲ��!�2��3&��Zu�ӏBYo��}�6--��Þ�[ �}b���*TZ�}�D�����_��p� +��ט��E}^.�HNNMIImeq6���eY�g����?��Ѥ"�_�A���Z��g�A�WNN^FzfzzfYsd� #l��1�Ҩ��e5q�H}���>?f������lqq�;zg��o3��&%2Eo�Y�l%^� 띙s�<��(���@�`���ӓ��|�Ŵ�t�<��������Ժ�UaC�33�$'��]���{X�Y����'͞���8���hbr6��>���Ug���u,b$� ۹3;+k�� � �~�ׄq�YŬ}X��ں��+�L��LX�Ϊ6�ˮT�\���XY#�vaa�kfFVv��>ш\m�6F�a�זW���o��������Y�;w�.�ɳ?Ύ[���� k�NHb�q͚�o�3�P�di�Fg���Zt +�}�y�'����fo��}�%�M-�hb@JR4����+��y}߀�35BX�;s{`p('7��R9!�S�w�۪�={��ˠ��ٳ�h�9�S��5[�'N�b^�C̋� ass��,����Х����BfM��S��p��"�PZj��#ǭΩ����,B���gޢp�b�[گ����_��1�C ���z�̅�ܼ�k��iV���� +�˝��K���Sh����_fAM�Y�a��g�j�� �E��y���陪�Y�}Gְ%�i�� �D�@�Ae��laaM��쪞������|1"���C7�S���~g�n����I� �M�m�nY���)����<}dO�s?����V}�r�@ ����?���q�3�����(��q��å:z�$,lq����5Q�q5u���6�C�A���� +7wO/�� +W�'%�Dž�(���a�v�]DZ]��;�&�����)T��g�����%*.�V绥�K�� �+�#�c��\�i�W&����`V�@��5aa���{�}<^pb%!?LE�����R�ĩ:�����c�y60�&a�Ր��-�ZY���&�znu� �� N��ֶP�L&����W2*��&,�lyU���Wn^A��K�����w@ +@��+�",�l��DR��ñ��ͧ��J����/���ؑ�f�9���g���/ ��6a� ��%,e:z��~��cG�m����E����W?���~����`�1C��g�jt��A���r�Ͱu���^,���]��.@c�p�Q"ZM�VV�|#1e�LCSJNIC�����ʦ�!,��jaIXX�`��Bî$%��dBlR&�LMˈ�� �h�&&�j1���h4saA����״\�~�������t�u�G:-\FWG��6-c�}����ʅ���",NG��~���l�c�s�ud���#e���\app<�r�ʫ����Vᗯ� �n�zz'g��$,��b��Q�Hg0/_����:�>���v����p�8P�lɹ��!���ǧ�� +-�����d�sM�m��=��S�f��ܩ�IT�������]���-\B��>���+�t���x�0����#�r��$*M0��{��Zaaq� �2�P)[�YLM�;���^� �M��aG���H��خ=�;w%:: +E������Ä��o�ԕ��⋦{����O���0:}�����N� +=z,]�p��^��/ۭ�aaP�%��l����?pY^q?�]ZZ����ˢc����e����b�nT�e&�INI�wp�-}|���� K ��_lim����;gB�YXX0�t&�"14R�a1ٸ�֊&I�#i�h�\��<�ƻa��y������ۇkfFsvvń�����Mum=�Q�NN^A�����p���,ےҭL6��/}�^�!,Q�c�i�����XZ^��� ��)"7����F�cu]}��UAfNDT̥�P8�z�Gp��`a�KH�,���n���������4�ƀ���,��f2Yn�aaWJJ+���*-�����`�!��t&"�J%����lvMªm���? �obbjo�����b)�7E%D��I�u��E)i7�]� + +]$I�y�R�x�@m�"+%M08:�&a� �L���j�6{y��71��ٰ�+( ��Rs���¢A6*Ͽ"���x���������2 ^݄Ղ�6a�]~)��Z��`���JX]�bh���d���;l����P2�R��Z�n���O�~��$��%����F�/���]���=x@��}C�SFF_�>mehr�X���Z��oR�jG�cC� d��Ɉ�h�spt �����O �bb�^�������ߢ���n��� 3�����P�����iP��K/���Uc*�����O�������D����`15=���qF17<*��ci����"�3+�j�',10}q�U��mff:�������ō2gWdA5pY�m�78��_���;���(T�U/G�P��T� ����eţ���<Rt��������\�d3���"`R»��&HT +�����)� +8��+��VTV�+'��ٓH{%�����K�e�ʱ 9�a��3�2������;:&����naA��&{���T�ʝ�B�~�<QIe�x�����w��y�w��'l�d�hrpd�5?|{×����q�LԖ2u<�A��~����qZF�c�v����믛��v��o"N�e߁�K�Z����e�� �����}_��w���ϯoh�x�)�+T�y-�����x������('77&&&(�DZ���W߭��]��Ǐ�>t����������q�� +*�`�9��93�a��',5T��??g��MMi�j9�Q�Lu�����LiA�K5uwG�������6�6�P܉K�_�3r��v�Bg�J�����Ј��'gfqy�%����2����;�ek�`�n�vvO{�� K���-�s��۫�l�2�gNQ��P�Led�����yw7���>��g��-��E�S��}�������|/�A� +��#c��t��t33~�����^ 0 +뗌�'$ߜ3�x�l��� ,����l�w-P��WBX-��.()ҧ��~p(DkK����q�̜���8��k��Ovs�����M��R��S����-���-lln�~*�PH�fZںy�P�hf4\�w��V�uM���pu`d��g���%#3��t�� +u�����i�L&�/����Y���I� M=�K���_��5(�������L;M;c�r ���L;��$�3��NUX@�F/ML2�icc�4k��hb�UX. +�mYA��H/�,�.{�]a����/͛��yvg{��,�f��sx�g�7��a!�,��r{�=Y?��d+:�� o~�ɗ�=gޖW�)����:<,,l�����$|�K�~>'*r�WFωY8?6f��߾��e�z��%K�,�`�b�U�M|�xU�r���X�Ȕ��%�^C__M�-A��z�N:F�����&3+��Rw����;w�}E4��=v��9��Ů��9HF#�Y�)�9�Ww���5���:F%,�nr��c]=vצ��� ��H�ں���\Xk7_W3� +�c&����ϔ�-,.IWf��TkJ��T\k��Y�m<�N:O�b��JX���'�q���zC�'�KO�k�]r�O䕞����&���Iz%X9k��b�8k���N�]E3騄5u��V֨ +�}�ʄ�9�GC嶏?є�_k�Ѹj��o���z��ݛ����FΚ��\�����k�ҳE%g��yG�ҏ���W���V�5j t�δ�:��EO��p$d[�7�:�(z��z��²�t&�d]H�Z��s+k�+���U��^j�uR���kК�7w��J� ,����җ��������?~�DX��9+�j�â�ED�05:f��Ww��~�x��E����(%&voL��蘃b�D.T +oW�{V��kDFT�; +D�7o~�Mo�u�� ++�Ψu t���,]f+��D��P�U�@)�u/�IX1�ԑ�����Wמ8��8Wդ��y�-�P/���.���p���T���:�k��y1Bv���G���&�x�����5��t@��KJ��2U�h���#4Q���aR�H��n����$�NL��f�{�(�Oۅ�T^U�@gK�Y�]s�WZ>n²��iW��3Ѣ0�ʂ�v��#�?�e4��ߐ����F4SP�P���<��&��� ϊ���7���OHJ�#}U�gd�` +�bnJ���I�Q�cw��BZ��>��k��X\�&J���6bT�k~�:3���ʣ��ӕY�농�W�Jޓ����i�&IX1Q�j7��<AѬ*ddAXa}��e2�w��~�o�ys鞥�fQo-������r��LZ�&>N�nݟ�\�x�W�)�� lPa�[eª�~�MJ�>�5�?�23'����:�����BX�����vtZ��H^��q���Y����+�֬Y�e��v�����+��}�j[��%�Ra)2�O}�� $litz�8�BXa!�Y�@��y�ZC�Z�����ʙ�Aʦ�15e(� +�ԗ�^'��N�v� ː=u�<�P-C�gt�lU���a���-�N�����O�:��&G�\S��S�s��� +�+����^ojQ?���E%�ֿ�z� C�BXa_T�A�;�� �B��-,���"h��7��J�)��B������Eo� ,����Wa!,�����Lz,=3C��_�..)-R�b��ܼ�te��>ݙ��zժdzն� ,����BXT؎N[���w7lںu��_��2��>�����ر&�Y���D�._��з�q�^��+����BXa�D)��5uW�}�I\�"ne�B����Dу">!^hӦ��N��P:a!�W;͂�6��e�6�vkN���_��}��?oذ��-����������ҕ&���x�� ��Wa!,����&�7�A���f��GX!C�,a�.��.��BXa!,������M��g)��B��#l���6$�n��CXa!,����BXa�E�BXa!,����BX�ºy���BXj��BXa!,����BXa!,���v� +�x���BXr�zx���BXa!,����BXI�BXa_tvF +��B�q{�BXa!,����N� ,����BXa!,����B�i����BXa!,����BX*AXa!,����"��+���/J�`�BXa� ++� +a!���BXa!,����BXaCKX�+���/J��� +a!,���B�BXa!,����BXa!l�a!���'��BXa!,����BXa!,������vl¦eAXa!,����BXa!,����BXa!,�������S,���BXaCG��� +a!,����BXa!,���v�a!,����N��n^!,����BX��BXa!,�������6D��� +a!,���AX�OXBXa!,����BXa!,�����Da��BXa!,����BXa!,����B�������va^!,����BXa!lHa!,����BXa!,����U��!�x4պ�lB������o��ñ�g2�&�_��� �O1��AS�_:-�,S��1�b���n�2�i��Vi2@�%��S�VC'K����<��Z����$��jjj�y��❶�ՠ5Jc����j����(�I*v����#�%YØ����bÞ^��y{*��"��e1m����fYL���*1&�P�Ŧ�ZwR���q'����:�C�5�R�z��Z/�C�ew�u�!��,��be�:Va)�Hj�S>M-KB�i�Hu�:Lj��B�l1�V���T�,��%�TJj�Ɋt����,���GݹU=�u�J������г���?}6���mO���z4��{��'>{@=�>G�>������{�Ԑ��>�s��h���{�Fv��C��u7x'P�����eݒ���s��ww�9�}���#��y�+�����/<m%A��?��R�7�n������{�cC��|����[�}~g@wR餟���hX�����O1>}V�ß�n��@�����ڬV�7��-��+����Z�_�5��*�r�@�~�W�jD�vG�}F��#z�J5W&��[�L��"iP R �Ir��$��dn�H<ێ ϶@,È���t3�� ��B ��q"�b5��U�h�����ʾ0��xB��A���k?( ������o�< {��%�A��uX�T +�8�vF�A�Ԇ�9'Wqp|��L����9a�bzK��-8 �i� ���}K�w�ۯ���z��8���G�����nG5��c��ku�n��QE�T������h��*V�TZ�&�,./��˕�e��.�)�y"�J�R�Kf* �a��e�� +$�H��H�qN���b��@�#�h>����!$�g���p���CB �AQi� 0�~$E�n�$��5�%����wz���w���96��\Q�+�/z��.�u�`ّ��Ym��z��r< +������;>7�3q������O�g��3{�� 4'�cP���02���S����9d:;"Z�T3��&�`Α;T_��<P�]�+�=ή�|��#clK�lI����`��=���À�<��( �����!�*�����BmC>JeT���2�A��3��*K?��K:�Q��H��Gr-8䓉;�j�ɾ��'Q�;*�+pH�*�����[C�16��"v� �ٺ�6"��DH�խ��� +��X��ubI���k�����V������,�ĘYܥfw�#|;�5Ϸ�v�x�m �b�B��3�����^�'��;j�o��� c�X����&�W&^cχ��_^��ZB~f=�Z|���z���&�� �ws�s���\w� +endstream endobj 195 0 obj <</BitsPerComponent 8/ColorSpace/DeviceRGB/DecodeParms<</BitsPerComponent 4/Colors 3/Columns 126>>/Filter/FlateDecode/Height 110/Intent/RelativeColorimetric/Length 10226/Name/X/Subtype/Image/Type/XObject/Width 126>>stream +H��W�WSG�O*��������y +����>VDD�]��+��U��UK[�TP�$7�� �����H����&���a' �Ġ��U�[�3g�ܹɝ�|��7���Y���,`X��o�GLR��{R�,W���d�m{H�TF\YN�$x уL�H�$��J�_yU@q[����@Ԣ���Vi���S�4�Hdz����d*gMɋ@�1Lt��������HX���1�oi��h~.S�FwO�c��b�P�,x�Qߴ��X^E��"9S��m�ѷr��2O�ۅ�]]y�ڄg�'�����h"}}%��0�� �P +=���jc{����s�(�Y,� }2<�A� �3�Cζ��M�>�Q6�Y[����� +�V+��q�AeD���dқ��>�CL2 �u�T��j�����qj��h�4�7�!�6P�<������M�{ ����v��V}�څ��9���Wmg�K�6�i~L&T��uu�ih���z��������_��)�@�<��]ZE��ڋL��eg� +J�=U������0�>V(����nl�@ˈ�dV͝���/q�o9̩[M���d�F(�M��4�������0$Mi��_A$��=�?���q��������s���й�����_n0�?����jL&�\��G������g�S�{�?0&�%��dp��R��jvaO��N���K��}(�p�+��&�������+M��2 �_:5퉀7>��u�*�0��5��]�Y� ڕ6�\�swP���~�/ r\yHg�~+��)�(�S�sپdrzM�l�S%ߌY#��j��Rc����U���Ȍ�y�b6Y�*�z���d����n2*|����m�hG�����0y��L�-�n�VH┰ݏA �2:'�����9k�#�T�0�U!y���y�ܾ����y�ņ�6��d"S'���0B'w���7�.y�y����g���49��s��g�(����Wk��ʿFع��{�:L#s��Kc>�rK,^�fư8����Љ�P'��1m���QY%�L�1=����˷r��*0�W�1� �����$�����9� x�d���_+Lln�Ҕ + +h<�,L�^�d���E����̣��83o}]�{�(J�J�Y�H�> �T�i��".~T�x�f�֢�1��yP��|�l�L2a�\&�Y�,i�W�mÅ�g��[��^�P�[2���%)��%�:,�� +�cmuk�hm�W��1��Q��C�lPm����e�Md��8�x��w�a��jn���C>�lLj����f�HiYY%��Nxzt(GA�=�,y�,�óRĦ�. +|o�.��J�C����1~ڧ#ec��(+�Vn�q��6�V��~���&"���@i� +�o)h'�t��E�,�Ɖ�~mV[������ݽ�p��!�O������٩�-�su֗Ť;���qc'�P��+��Y��D���}f�������c6�pz�It��L~��߹�V��� �}�A_q�f� ����(^Mqw� �xO[�Ě�@�rqaK�/� �_�<�u r�� *<����*�/�ܻX�&����t�g6����´��"�x۾N�0��i�{p?*����k�H�u�~�e +��o ���g2��>N�o�������ڽ���j��O����=;�Zu~��_���ڬ[r�������TIy��W�u��R��8(��T�ݧhh����t[�q������ݜ�I��q��Lɱ@��?;8�q����U��ͣB��3.9Ջ䃽A�Iױ��#n`�����cM-v�A�����?~�1�"�G`���sH�8�t�������p@-(�iGй�����Ђ�Χ!N�����&��_�h;�S�|���t���?�i��ã{�����M��/�,����Nɀ8��u`J�&�_�v<��!��Su{zqz��S��6��r�Ďd����: =(�^�ޒ=������lzlfީ�2�K~�L���C�5��d�&ιS �y��^qBc[wM�#�e��s���!�FcV�0���`B�5�o���AO�� �|Hޝ���Gc�v_�zp��Rv�Yz�~;�P�Mi��}�k��f�����������/�ح������{�H�Џ��ō£��~O��)0�p>���9�A�E^��Q��r+��"�w�3�ۓPV�^�y�^UI�th�E�@<f��b�ബ�xΎC%��N&��Ppig���U��e�}J9j�#7����赆�)�K�3/�Ӵv�No�^�����Bؽ�.:Brb���؎�(.FRf����wO��sI(����%�[R�Pߘٌ��&�*ˮ�5Ƈ��r#wt��ۺzZ�h�n�/�H���"�pRF��6��b6��k�A�p�g~���n>r +�3p���T?�q� +�Z1t|���8cK�_5���W�WY�Ot��iuN��3?��q�Q$����8�2����J��f�}Qhte4�.H@0�S��"s�*)*UQq��:���[��Ű(�<Bڂ�_S��߫�Q�)/�Wړ�]�OL36�.��_Z�}���G�Jm_IL���ԑ+AF\\�ΑC�����٥w��S���ƫ��y�㸮���\��kY��!Sk�7�]� �vY����[J*Do��ӿ"k� +���#:�]j�b�,Ȓ��&r�j�8Y#����(�@v��+����biԑ[!ے8��ؚ�B�Agf�?G�0�N��T�]���JA-����ڧ�H�q2�}��C�ߨK�i>V�������{�$լxZڡ�b/`b�j5��)r�n8av^C`�|�����6�`�lB�⮌�'g�%����� � �t^��A�u��o ����C'y%�����w~%�������A��E���>*�1� N7I��� ebcVZ'Gd�B=�������aK��)��k��*��4��M�7���3��N�D�V��n�����`���ק�!:�El������_��DY��ٿ�*CXܓ3MR�9���R1�x�����w��Q�pvzՆ�M���:�����X_f��V� _4�8�1�Կ��N9���1���Y�;u�i�aO�Z&o����2�����7x� ݄�����E�M�X��'{7���$3���//{61�-p�i�����l�pm�5��37���>�8[��g"f��\|;�'�&���{'D�}���H���m��?��xZ�|��J;�͗@��]�s�@-�R���T��=�!�������)�������Zq�V� x����Vec�ӷ���8���~�#�8a�Ӧy��x�}4�b�8��� �q�p�c�p�|B��v9nF���R��#����R�sT��с�c���$���~.�&�)���l���)BU�Iv�ȹO��ޔ�=�|���r����&yMpb�{�~J��k��-0����Vͥ,��#������'yK�7{(��b�I�����m;q3���#��C1�BK��������je/������Z�^2�sY�4C +�R ����;a����ͤ��%}�!��=����ޙr�r�H��� dmOZ�3�ο)�e{�M�5���gġ�_�����+A�?�O�n�Բ�"�ie�ltW'�+uy�!�*i'`�$۟��C� + o�\����9��ˊb����oB��3�C�W?~��i��郘�Pz��+yC2C�4�{�7��6-7Nq����~>�� nCDn���Z��V>��������$��ǩs�Qu����i��DF��!���4F.2��%6gp��Φ ��T܉/��7͎�YC�%�D����b�Y��^��]F�ZG�/u�<E�K91B�q{p���f�Ь8qU&g0��z�́~6�֡&M�&}���(��Д�#����b����v�Cz7��/�;����G�(~ ���:�YQV�B�[D��|yI]��FU� N<��^R9lt`WRHu�Gvum:]^@S�]���+��f�Xh*�0uݗ���'��@$�$��o�5��=��fk9\|� -���-;�O�H�K.W�O���x��ah���1;Ȭ��d~��cW���w-��g���{o5�/�:i:=շ�y��yy���rg��(���0�u MW��N"�� +��ē���I��쯐GѲ3�y�mw[�(��p\~!Z�6�m*Y����0X0�nUt�w�=��>_��̲��y��)V������)-/��c֠�bc���;T��Cz�1F-2g{���9fl�`wb~�����ǽٲ����[�:���g���6���%M2�j)J+�:�3�@j��K>�\���nt���O�8i+�0l�� +�㺻�xI�1�;Dx��:�We�Yj��$��觾D�� mѭ�P�T6�!ے�~+�{�>�ɺ��M;��j������9E�� J������ߤ=nM���P�}����u��j?�mr��%̂V]�����ٜYq���|{�1r�����hm�mJw�wj�m�hΖ���÷�O=A��Ȭ+k5�-��@���}Y�+ ~ӡS&Ÿ�3���$��z��).��s��':��[Xç��9r��|Iq�k� +A�0u�,T5����hg���$��'�j���Ŧ�˰� +�t��3w���즜{8�<�8�R1��=�]����B1��^U��y��G�-��o1_[��?c��,�K�%���!9oTk�5��3�eV:۩QR��P7`�CT�D�)K@6�I?�Cu�B�*M2������>�.s���B�r�Ĩp�s�^s���'��o��FL�sϟ��Q�'P������M�6%|����pd�S*� O���ۭ��ʏ�!�ց�����nϪ�j��Ge�k#�<�[�:�F�1��z��Izĭ���gCl �만Ź�'}�ٴ�wnwzAjO��o=e���tS�rR�ק2�G�1��)?��Q���nQ���'H�<��w��MiI��((fhHM�?P�.2g�a�O �0Zv��Ȅ���Wsƺ9��;����b��n�>�a�|n���;�������3/ZtH~�6�?��ī�,�� +����N�8=:��j� .���� ��6 +HX����f(Y�dhTDPQ6�}�-{*a^���*��D`�S��U��W����e!���q�L!�_y�����o�'T���DY[ �<��6ԋ�J�ی��C����`>5&c��4��waU̘z�:f�������nu��W�=m�o�B��O�*]�N~j�.ĺ_K6�T�?���֦��Aǒ�o���ٻ���߬���oiGL��t{��� +Pd�OOE��@K���Ai�!}y��f���r���� +:�H�v֎S`�:<����ރ]C�V �oRA="�����y0�L�Z��}����f�BH){X!�9۱���>�:��h��H�!�?e��Xy�:�zJ_��fj�;�k�n����o�U�<�=i�&����{2/�@�t�W��A%���ʻg�!)�� ����Σ� �C�suo��e�:9��:�Ox�|Y��=���=�m��uUc�g��� WC6_,�u� _l�t�.* ��ѥ���%d�,(>�Fx;�6�W���;�M(����%E��lϣgMYIOc��M�ө�1v�j�O�����i6� WX�*�,�Ī����sc�7V�������r+|�D/���ѱ}��<G}��Bby�����=D��<I7S`o] L*OG-�e�P�Ξ��{�i�F�T"�U���� ��77zU=5���0lE��@�M�����x�$�nv��� ��RFt����w�%~��3��(O�P�6ÿU3���qV�֝�zJ�B���r?�/�u �����!���_'����+�\�k��l�M��j��{'�X܆�,<��|b,�BĄ&���� +5��F�ðuSX L`��k}��_=JlAΧn��]T2�ͷ������,xa���Bt��گO����zC��h�i��1��oS�ZD���6��y|̵V�u���Y}�0�#p�-(.��|X}����@��ۮ�{�O��S�0�YXxj;�3����?�>h7QQc,vQ^��R���o�����Ҟ�0���#���RS�>+�� L"��P�/���{8�7���껺��J��_����[�dМ_��=0)���q����H&X +x�W`�Ϫ����d8�C0�Y��æ��I�̩��Z�X瀘j�v���uN��eD �I^q�o��/ȽT�|���魴Ȩ��)���ڷ2�rnTf���fDp=�V����vr��x�r�uP�`�Z6����MM��K�~\��x�t�n��O��v� +;[�8'Sx��8 ��$��د�s ���#�1эM&�hzTv�i�$���߂�5?;<��H���T�I��&�_�����gF����31��9:��g{OH��U�����CAK�y��K����~h�J�%���=.�c�IJ���9��y�9BjLz�f�:�~f�Ps�$i�!^�ZQ�H?}��K9�����Wl?�1�%.TM�N��J#b� ��;}C���ŧ���_RuW��HN�X�\���6Ƙ�B��b7������+�{i��ؗ��HPg�Pk��=�q ����{�:�Ԓ�����K�$q�i��:d�E�6*8�w*��8��ٔL>]g����-��z-��9g�h����"�s��G/W6��*�U1�"k�5����OT�V���'���1�D� ��:���!��{����]��J_|���G�� n8h�H��F}�O��.��Cg>xLi�a�t.IxF��)(������ȫ7��Jɭ�2$�,�����9P��4���^;��F��h_��3���O����z�]m�\5�X 4�s�,����p]�6��Ƙ�d`���w�uN�a1Җ�����J(�� /�}�0s��{��� ��_D661���̲m@�SiW>D}�� ��f��u��6�|cFtԚ�*��K��|��|��Ãy����ЅZ�5lI��A���'vDǗԪ���e��h��Z[u��ϒ�{,=���|2�a��YȄ���}2R����\눸������t�s�E/Q�.q�":�!��-����S�^����fU[�hj\�f���s�'�V����pMY��!��`�� �l%b�^��NP+��njR3�*�x�S�����c���"�؉�B�����3����{��D�Y.̤���=<�ahs�H����rAO�[Ջ�Ņ,�$�9d�*���x����q�)^�W+e��`���A驘lkj�Z�αj��Ѡd�7C������v���q��IҞ�Ty`5�u��O ���E<�����"�k��3�t�YeS�Ot���6d�M��:jA�-s�o�]ِ�V)�{P�5XK�bJ��jD�z�7�m�.� |Eۻ$y+���&g�����3�Iq�7r��햑�Ykir�z���K��J�Jk�Vw�D����Q$d*�o?��&티AY��58�距i�x�o�Z����������[A�����K�9a������.1:������x�����0z�D��p=W<��f�@��V7�w�$�Z�ÀOo)/�d��w�?Nj��bbV)��V��u���<�u2\�0���Nvx��6G*;Yk�̥�X�[�[�O}v��:�mO��h�8�eC�м�k(�S�����'nS��LO@�}b��ޓx��&����>N��c�@�5$j��ɲ����\�k�O��y��[>�~�5���t��V�</�x�?*L�q���Z��0�=���+��\R�cX,�1�����4�r�CmQ�{Z�^�V��</#0ŧ�L~� �FI�/�� �Z�2�@�[�Z6�l-���fAB#����%/��U��ԕ��Z��x�R�S<�3��83�k-�8*X(�Sg���ԺT��e����E�B¾$�����熄�ˆ�ez�{�yy����������݄5��� +m�-���;TOg�ʟS����k�f����Pc_�g*V���� +�.h(���5������������0<�ʈW*��k�L:�X����a?�:����l�Y�+�,�X��\�jݑv���O�������7Q*''A�u���/�1����.Vݶ?�Ayv���+n�B���C���C�O��1�.����e�V,���(ҊQf�U�1�؉�pѥ�X-N�֍�k& +�Ӏ���&�c��\x�E���D Z±>����G�Ų2��<��Kۓ�} �,hUTE��{�H! ��M�4�f���8i2�I��HIƎ{�n��WJ���H�m��a�Z��;�5��6<Ъ`ݸ�楻��QAe�]�;��$Q���n�S��2��� ��n���>��״~O+�,�<u�e8�G ��V�S�;#��{g��W^~(�ӡ���X� ���E�[1=����j�;�[��:_&�94����:7��!�h�+M��ي���Q�������]����tRޱ�{��uh���tk� ��7V|av��U/72B/o<%��L�d/q�5������YG�Lfq��h�T��\s��?b;Q�?�6�{x2}�-��P�msA����n{��.�}}�i��c���q]��la�$ͰT����9�e����ySJu,�y���՛q���+g܊�������N��;?D +0{]��A��#k��Q�ͽ�r�����W����ԟ=���S��l�[Dm��b�݉l��h�T���`�@ ������?l|�(>��^��/<?����Z�m�����m����juA+0�E��>7-��� x�}}s���+��i�V��]���,�n��l��^�����Z�LB��܄�}D�@�\_|��N�����N��Sso��F�0a�hJ��I�!��{Z�|Q��IH>����W}������t���M��k��.%�9���r�����6�2+9�d�jy�x��\k�5��W�K� ����>M=!��"�u�Y�\�#�n��# �f�H���? +"���I/��������|�Û�霾����ȗ@�2ы��|$�ך?����*��(�Ţ.̋�ZxC�m0�-��i�u��#������#�x~u������/p��ѷ(K��|Ig,�W|����"��`b��O�8q�AM�Pj[X���.��\*��t����M����;_�^:���=��O�9�!�u�"�*����7됷!fԚ��zO<}�+�'�Ii�@G?��A���wv���%��D쿺�P�Pj;82ɼ��s�ガ��x|ۡ��ٕ���Au��b��h��R2�;,�F���Ac0a�G?ik8.�����X ���z}�p"�����y�pO���K�� ���'R���oofnK�qzR8�B�6�������ӑ%3�������U�un�Α:qb�d������I�� +������p���n�Hn4p���C��[ݳ��}4(�=ci���{���� �en��Vj�X���,.ڎ�)x�c��l�O���(<�����6���k��(�s��y���h�P��ͺHc� +E"�zc��N�G�&�^��Ԓ��ΰ[��L$����5:o~�\o��'�8����8}s��M�p���8��J;sR�qq��?�V[�V�N3����zmrO{P� %�|�?��-��O��sEK +��L&���N�=�Z``ȍ�3ȥ�^���O�_z-2/�x��,:��;��Y2�]2 q8r,���7$�Bo��fS2����(�����5�T����M�V�p���?5>0 Jα�Ɂ��Ɵiei�?&���'}�n#��?�$��Dd��T�dǟL +!���c��y���o ��!��|�dT���TO�]�ͮ<t����^-��Ts!��S٠�!��:�JuF�ɬgrN_�������?��zw �d��[�Iu��b�4�A�bU�]ӳX�P +����I��{���������s�>ʩ�5 �����NK��R�2q���)��7Z,>�%�JH���ysz�ub���$Y Wp�5) zF��Mo{�>���>���>����?��> +endstream endobj 189 0 obj <</Intent 199 0 R/Name(Layer 1)/Type/OCG/Usage 200 0 R>> endobj 199 0 obj [/View/Design] endobj 200 0 obj <</CreatorInfo<</Creator(Adobe Illustrator 19.2)/Subtype/Artwork>>>> endobj 193 0 obj <</AIS false/BM/Normal/CA 1.0/OP false/OPM 1/SA true/SMask/None/Type/ExtGState/ca 1.0/op false>> endobj 192 0 obj <</LastModified(D:20161013192721-02'00')/Private 201 0 R>> endobj 201 0 obj <</AIMetaData 202 0 R/AIPrivateData1 203 0 R/AIPrivateData2 204 0 R/ContainerVersion 11/CreatorVersion 19/NumBlock 2/RoundtripStreamType 1/RoundtripVersion 17>> endobj 202 0 obj <</Length 1437>>stream +%!PS-Adobe-3.0 +%%Creator: Adobe Illustrator(R) 17.0 +%%AI8_CreatorVersion: 19.2.0 +%%For: (Quintas) () +%%Title: (icones.ai) +%%CreationDate: 10/13/2016 7:27 PM +%%Canvassize: 16383 +%%BoundingBox: 25 25 75 75 +%%HiResBoundingBox: 25.9999999999973 25.9999999935353 74.0000000000036 74.0000000000009 +%%DocumentProcessColors: Cyan Magenta Yellow Black +%%DocumentFiles:C:\Users\Quintas\Desktop\google2-01.png +%%+C:\Users\Quintas\Desktop\banco_objetos.jpg +%%+C:\Users\Quintas\Desktop\dominio.png +%%+C:\Users\Quintas\Desktop\logo_1__2_.png +%AI5_FileFormat 13.0 +%AI12_BuildNumber: 111 +%AI3_ColorUsage: Color +%AI7_ImageSettings: 0 +%%RGBProcessColor: 0 0 0 ([Registration]) +%AI3_Cropmarks: 26 26 74 74 +%AI3_TemplateBox: 49.5 50.5 49.5 50.5 +%AI3_TileBox: -256 -346 356 446 +%AI3_DocumentPreview: None +%AI5_ArtSize: 14400 14400 +%AI5_RulerUnits: 6 +%AI9_ColorModel: 1 +%AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 +%AI5_TargetResolution: 800 +%AI5_NumLayers: 1 +%AI17_Begin_Content_if_version_gt:17 1 +%AI9_OpenToView: -663 289 1 1103 725 18 0 0 182 216 0 0 0 1 1 0 1 1 0 1 +%AI17_Alternate_Content +%AI9_OpenToView: -663 289 1 1103 725 18 0 0 182 216 0 0 0 1 1 0 1 1 0 1 +%AI17_End_Versioned_Content +%AI5_OpenViewLayers: 7 +%%PageOrigin:0 0 +%AI7_GridSettings: 72 8 72 8 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142 +%AI9_Flatten: 1 +%AI12_CMSettings: 00.MS +%%EndComments + +endstream endobj 203 0 obj <</Length 12101>>stream +%%BoundingBox: 25 25 75 75 +%%HiResBoundingBox: 25.9999999999973 25.9999999935353 74.0000000000036 74.0000000000009 +%AI7_Thumbnail: 128 128 8 +%%BeginData: 11916 Hex Bytes +%0000330000660000990000CC0033000033330033660033990033CC0033FF +%0066000066330066660066990066CC0066FF009900009933009966009999 +%0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 +%00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 +%3333663333993333CC3333FF3366003366333366663366993366CC3366FF +%3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 +%33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 +%6600666600996600CC6600FF6633006633336633666633996633CC6633FF +%6666006666336666666666996666CC6666FF669900669933669966669999 +%6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 +%66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF +%9933009933339933669933999933CC9933FF996600996633996666996699 +%9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 +%99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF +%CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 +%CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 +%CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF +%CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC +%FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 +%FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 +%FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 +%000011111111220000002200000022222222440000004400000044444444 +%550000005500000055555555770000007700000077777777880000008800 +%000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB +%DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF +%00FF0000FFFFFF0000FF00FFFFFF00FFFFFF +%524C45FDFCFFFDFCFFFDFCFFFDFCFFFDFCFFFDFCFFFDFCFFFDFCFFFDD8FF +%A8AFFD0484608460FD0684A9A8FD6AFFA9AF84846060353C1336133C131A +%133C1336133C3560608484AFA8FD60FFA8AF8460353C13131319133B133C +%35605984608460846060353C1335133C133C3584A8FD5CFFA8843C3C133C +%133C353C3C6084AFAFFFAFFD07FFAFFFAFFFAFAF603C353C356060AFFD57 +%FFA9AF353C133C133C35606084A8FD15FFAFAF6060353C136084AFFD53FF +%A984353C133C1360608BA8FD1BFFAFAF8460353C6084AFFD50FF84601335 +%133C358484FD21FFA884353C356084FD4DFFAF5A3C353C356084FD27FFA8 +%60353C60FD4AFFA884353B133C3560A8FD29FFAF84353C35A8FD47FFA860 +%353C133C3B8BAFFD2CFFAF603C35AFFD45FF8460133B133C60AFA8FD2FFF +%843C3584A8FD42FF843C133C133C53A9FD12FFCFCFCACFC9CAC9CFC9CFCA +%FFCFFD13FFAF60358BFD41FF603C133C13352F537DFD0DFFCACFC9C9A0C2 +%C1C198C1BAC198C199C199C2C2C9C9CFFD10FFA8601384A8FD3EFF603C13 +%3C133653534C77A2FD0BFFC9C8FD04C1BAC1BBBB99BB9999939A939993BB +%99C2C1C9CAFD0FFFAF603584AFFD3CFF8435133C133528534C4D4C777EFD +%07FFC9C299C198C198C198BB93996F936F946F946F946F936F946F9999C1 +%A0CACAFD0DFFA8601384FD3BFFAF60133C353653774D534D774D777EFFFF +%FFCFCFC2C1BAC1C1C1BAC1BB99939A939A6F9A939A6F9A939A6F9A939A6F +%9A939999C8C9FD0DFFAF8B3CAFFD39FFA860133C1335534D4C534C4D4C53 +%4C537DFFC9C299C198C198C1BAC198996F946F946F936F946F946F946F94 +%6F946F946F946F9393C1C2CACFFD0BFFA8843CAFFD38FF60133C19365377 +%4D534C774D534C534D77A0C1C1C199BCBBC1BAC1999A6F9A949A6F9A9394 +%6F946F946F9493946F9A93946F9A939493BBC1C9CFFD0BFFAF603CFD36FF +%CB84133B13354C4D4C534C4D4C534C4D4C76999993996F9398C198C2A1CA +%A8CAA8FFA8FFA8CAA8CAA1A19A9A6F946F936F946F946F946F946F9993C2 +%A0FD0BFFA88460AFFD34FFAF3B3C133C53774D534D534C774D534CA099BB +%939A709A99C1C1C8CAFD0FFFA8CA9B9A6F94939A6F9A939A6F9A939493C1 +%C2FD0CFF8B60FD33FFAF353C13352F4D4C534D7753774C534C9999996F94 +%6F77709F98C1A0FD13FFA8A16F946F946F946F946F946F946F99C2CFFD0A +%FFAF6060FD32FF603C133C355377A8A8A9A8CBA8A97D9A999A6F9A70534C +%A0C1C1757777A9FD13FFCA9A9493946F9A93946F9A93946FBBC2CFFD0AFF +%A86084FD30FF843C133B137EA2FD07FFCAC293936F9B77774D7698C19953 +%284D4D7EA2FD13FF9A9A6F946F946F946F946F946F999FCFFD0AFF8460A8 +%FD2EFFAF60133C1360A9FD07FFCFC3939494C3CAFFA9A899C199764D774D +%534D787EFD13FFA19A6F9A939A6F9A939A6F9A9399C2FD0BFF608BFD2EFF +%84133C133C84FD07FFCAC3939370CACBFFFFFFC9C198C277534C534C4D4C +%5353A8FD12FFA19A6F946F946F946F946F946F99A7FD0AFF8435AFFD2DFF +%3C3C133C60FD08FFCA93949ACAFD04FFCAC2BAC2CAFFA27E4D534D534C53 +%53A2A8FD11FFA89A6F9A93946F9A93946F9A93C2CAFD09FFA96060FD2CFF +%843C133B1384FD07FFCA939376CAFD04FFCFC998C1C9FFFFFFA8A877774C +%4D4C4D4C777DFD11FFA19A6F946F946F946F946F9493C3CAFD09FF7D5A84 +%FD2AFFAF60353C133C84FD07FFA0949AFD06FFCFC1C1C1FD07FFA87E4D53 +%4D534C7777A8FD10FFA19A939A6F9A939A6F9A939499CFFD09FFA9598BFD +%2AFF84133C133B13AFFD06FFA19A9ACAFD06FFC2C198C9FD08FFA8A85353 +%4C4D4C534D7EA8FD0FFF9A946F946F946F946F946F939AFD09FFA85335FD +%2AFF603C133C353CAFFD05FFCA9A94CAFD06FFCAC1BAC2CAFD0BFF7D774D +%534C534D777EFD0FFF9A9A93946F9A93946F9A6F9AA1FD09FF7D5384FD28 +%FF843C133B133C3BFD05FFCAC36FA2FD07FFC998C1C2FD0DFF7E7E4C4D4C +%534C4D53A8A9FD0CFFA26F946F946F946F946F946F9AA8FD08FFA2285AA8 +%FD27FF8B353C133C3560FD05FFCF9AA1FD08FFC1C1C1CFFD0EFFCBA85353 +%4D534D5353A2A8FD0BFFCAA1939A6F9A939A6F9A939493C9FD08FFA2532F +%AFFD27FF353C133C133C60FD05FFA09AA8FD07FFC9C198C8CFFD10FFA97D +%774C4D4C534C777EFD0BFFA19A6F946F946F946F946F939ACFFD07FFA84C +%2F5AFD26FFA83C133C353C138BFD04FFCAC2A1FD07FFCAC2BAC1C9FD13FF +%A27E4D534C534C777DFD0BFF9A9A93946F9A93946F9A6F9AA1FD07FFA877 +%2984FD25FFA884133B133C133C60FD04FFC9A0FD07FFCAC998C19FCFFD14 +%FFA8A253534C534C4D53A8FD09FFA16F946F946F946F946F946FA0A8FD06 +%FFA84D4D59FD26FF353C133C353C35AFFFFFFFCFC1CAFD07FFCAC1C1C1C9 +%FD18FFA27E4D534D534DA2A8FD07FFCA9B939A6F9A939A6F9A939493CAFD +%06FFA8774C59AFFD24FFA83C133C133C133C84FFFFFFC9C2C9FD07FFC2C0 +%98C1C9FD19FFA87E4D4D4C534C77A2FD07FF9A946F946F946F946F9A9BA0 +%A0FD06FFA84D4D53A8FD24FFAF133C353C133C358BFFFFFFC8C1CFFD06FF +%C9C1BAC1C1FD1BFFCBA853534C534D777EFD06FFC46F9A93946F9A93A1A8 +%FFC9C8CAFD05FFA8774C5384FD24FF603B133C133B133C60FFFFCF9FC1A7 +%FD05FFCAC298C198C1CAFD1BFFA8A8534D4C534C5377A9FD04FFA1946F94 +%6F946F9AA8FFFFCA9FC9FD05FFA84C4D4C84FD24FF60133C353C133C3584 +%FFFFCAC2BACFFD05FFCAFD04C1C2FD1FFF7D534D534D7777A8FD04FF949A +%939A6F9AA1FFFFFFC9C1C9FD05FF7E534D5335FD24FF353B133C133C133C +%60FFFFCAC1C0C3FD04FFCFC1C198C1BAC8FD20FF53534C4D4C534D7EA8FF +%CA9A6F946F939ACBFFFFFFC9BAC8CAFFFFFFA87E4C4D4C59A8FD22FFAF3C +%133C133C353C1360AFFFC9C1BAC9CFFFFFFFC2C1C0C1BAC1C8FD21FF7D77 +%4D534C534D7EA8FF9A946F9A6FA1FD04FFC2C1C2FD04FFA953534D532FAF +%FD22FFAF133C133B133C133B35FFFFC998C19FCAFFFFC9C198C198C198C9 +%FD22FF7D534C4D4C534C53779A6F946F93A1FFFFFFCAC298C2CAFFFFFF7E +%534C534C5984FD22FFA83C353C133C353C133CAFFFC2C1C0C1C2FFCAC2BA +%C1C1C1BAC1C9FD23FFA8774D774D534D77709A6F9A94CBFFFFFFCFC1C1C1 +%CFFFFFA87E4C774D532FAFFD22FFA8133C133C133C133C13AFCFC898C1BA +%C19FC1BAC198C1BAC198CAFD24FFA2774C534C534C946F946F9ACAFFFFFF +%C2C198C2CAFFA8A24C4D4C534C5384FD22FF843C133C353C133C353C84FF +%C2C1BAC1C1C1BAC1C1C1BAC1BAC1C9FD25FFA8774C534D776F9A939476FF +%FFFFCAC8BAC1C1CFFFA84D534D534C5353AFFD22FFA8133B133C133B133C +%1360A8C898C198C198C198C198C198C199CAFD26FFA2774C534C946F946F +%7053A8A8C999C198C1A17E4C4D4C534C4D4C5384FD22FF843C133C353C13 +%3C353C3CAFC2C1BAC1C1C1BAC1C1C1BAC1BAC1CAFD27FFA8784D776F9A93 +%9A4C774D779AC1C1C199774D534D774D534D5353AFFD22FFAF133B133C13 +%3C133C133C60C8BAC198C1BAC198C1BAC198C1C1CAFD28FF7E7770946F94 +%704D4C5370C198C1BA994C534C534C534C4D4C5984FD22FF843C133C133C +%353C133C1360A0C1C0C1BAC1C1C1BAC1C1C1BAC1C9FD29FF7E9B6F946F76 +%4D534D9AC0C1BAC199774D534D534C774D532FAFFD22FFAF133C133B133C +%133B133C137C98C198C198C198C198C198C198C9FD29FFCA76946F704C53 +%4C7698C198C1989A4C4D4C534C4D4C534C3584FD22FFAF3C133C133C353C +%133C353C35A0C0C1BAC1C1C1BAC1C1C1BAC1C9FD29FFA89A939A70774D77 +%99C1C1C1C0C176534D774D534D774D5335FD24FF133C133C133C133C133C +%133C58C1BAC198C1BAC198C1BAC198C9FD29FFA16F946F704C5376C198C1 +%BAC199774D534C534C534C534C35A8FD23FF60133C353C133C353C133C13 +%3C7BC1C0C1BAC1C1C1BAC1C1C1C2FD29FF9B946F9A77534CA0C0C1BAC1C0 +%9A4D534D534C774D534C535AFD24FF603B133C133B133C133B133C133599 +%C198C198C198C198C198C2CAFD27FFA89A6F949BA84D7698C198C198C14C +%4D4C534C4D4C534C4D4C84FD24FFAF353C353C133C353C133C353C13839F +%C1BAC1C1C1BAFD04C1FD28FFCA949494FFFFA299C1C1C1BAC199774D774D +%534D774D534D5384FD24FFA83C133C133C133C133C133C133C357C98C198 +%C1BAC198C1BAC1C9FD27FF9A946F9BCBFFA0C198C1BAC198764D4D4C534C +%534C534C4D28AFFD25FF353C133C353C133C353C133C353C35A0C0C1BAC1 +%C1C1BAC1C1C9CFFD25FFCA9A6F9AA8FFC9C1C0C1BAC1C09A4C534D534C53 +%4D534C774D59AFFD24FFA860133B133C133B133C133B133C131A349FBAC1 +%98C198C198C19FCAFD24FFA8A16F9376FFCAC298C198C198C1704D4C534C +%4D4C534C4D4C4D53FD26FF843C133C353C133C353C133C353C133C59C1BA +%C1C1C1BAC1C1C1C9FD25FF9A9493CACFC8BAC1C1C1BAC199774D774D534D +%774D534D774D7EFD26FFAF133B133C133C133C133C133C133C133C589FBA +%C1BAC198C1BAC1CAFD23FF9B946F9BA8C9BAC198C1BAC199774D534C534C +%534C534C534C5359FD26FFAF60353C133C353C133C353C133C353C133C58 +%9FBAC1C1C1BAC1C0C8FD22FFCA9A6F9AA1C9BAC1C1C1BAC1BB764D534D53 +%4C774D534C774D5353AFFD27FF843C133B133C133B133C133B133C133B13 +%3C589FBAC198C198C198C9CFFD1FFFA8A16F9476C39FC198C198C1989A4C +%4D4C534C4D4C534C4D4C53287EA8FD28FF3C3C133C353C133C133C133C35 +%3C133C133C58C1C0C1BAFD04C1CFFD1FFFCA9A9493C2C1C1BAC1C1C1BAC2 +%77534D774D534D774D534D774D537EFD29FF60133B133C1360848B603C13 +%3C133C133C133C349FBAC198C1BAC19FCFFD1EFF9A946F9998C1BAC198C1 +%BAC1A1774C534C534C534C534C534C5353A8FD29FF843C133C1360AFFFFF +%FFAF843B3C133C133C133C35A0C1C1BAC1C0C1C2FD1DFFA1946FBBC1C1BA +%C1C1C1BAC1C9FF77534D534C774D534C534D53287EFD2BFF353C133C60FD +%06FFAF60601335133C133C357C98C198C198C1A0CFFD1AFFA29A939998C1 +%98C198C198C1A0FFA8774C534C4D4C534C4D4C534C5384FD2CFF353C35AF +%FD09FF84353C353C133C355F9FC1C1C1BAC1C1C9CFFD17FFCAC299C1C0C1 +%C1C1BAC1C1C8CAFFFFFF77534D534D774D534D774D7EA8FD2DFF85133C84 +%FD09FFCFA8583B133C133C13357BC1BAC198C1BAC2CAFD15FFCAC298C1BA +%C198C1BAC198C8CAFFFFFFA8774C534C534C534C534C4D53AFFD2DFFAF60 +%3584FD0BFFCA7C5F353C133C133B58A0C1C1BAC1C1C2C9FD13FFCAC8BBC1 +%BAC1C1C1BAC1C1C9CAFD04FFA953534C774D534C774D532884FD2FFF843C +%35FD0CFFC97B59133C133C1335347C98C198C198C19FC9CAFD0DFFCACFC2 +%C198C198C198C198C19FC9CAFD05FF7D534C4D4C534C4D4C53287EA8FD30 +%FF603CA8FD0CFFCFC27C353C353C133C355F9FC1C1C1BAC1C1C2C9FD09FF +%CFFFC9C8C1C1BAC1C1C1BAC1C1C1C2FD08FFA24D534D774D534D774D7EA8 +%FD31FFAF3584FD0EFFC2A0343C133C133C1335589F98C198C1BAC199C8C2 +%FD05C9A0C2C1C198C1BAC198C1BAC198C2C9FD09FF534D4C534C534C534C +%7784FD33FFAF3CAFFD0EFFC9A0583C133C133C133C357C9FC1BAC1C0C1BA +%C1C1C1BAC1C1C1BAC1C0C1BAC1C1C1BAC1C1C9CAFD09FFA8774C534D534C +%774D5359FD34FFA96060FD0FFFC9A07B3B133B133C133C13597BC198C198 +%C198C198C198C198C198C198C198C198C19FCACAFD09FFA87E4C4D4C534C +%4D4C5353A9FD35FFA86060FD10FFCAA083353C353C133C353C59A09FC1BA +%C1C1C1BAC1C1C1BAC1C1C1BAC1C1C8C9FD0CFFA953534D774D534D5359AF +%FD37FF846084FD11FFA783353C133C133C133C137C7BC198C1BAC198C1BA +%C198C1BAC19FC9CFFD0CFFA853534C534C534C5353AFFD39FF846084FD11 +%FFCFAE5F60353C133C353C135F58A099C1C0C1BAC1C1C198C2C9CFFD0EFF +%77534C774D534C535984AFFD3AFF606084FD13FF8460353B133C133C133C +%3559759F99C198BB99C3A8FD0FFF77534C4D4C534C2F3584A8FD3CFF8460 +%84FD14FFAF603C353C133C353C133C35847DA19ACAFD10FF77774D534D53 +%53591360AFFD3EFF846084FD14FFAF8460133B133C133C133C1335355A84 +%AFA8FD0BFFCBA9774D4C534C532F363584A8FD40FF846084FD15FFAF8B3C +%3C133C353C133C133C133C3C6060AFAFFD08FFA8FD04532F5A353C358BFD +%43FF846060FD16FFAF603C133C1335133C133B133C133C133C3560608460 +%8460602F351336133513193584A8FD44FFAF8B608BAFFD15FFAFAF606035 +%3C133C133C353C133C353C133C353C353C353C133C353C133C60AFFD48FF +%AF5984A8FD17FFA8843B3C1313133C133C133C133C133C133C133C133C13 +%3C133C84FD4CFF848460AFFD18FF84843C3C133C353C133C353C133C353C +%133C353C356084FD4EFF84845984A8FD18FFAF8460353C133B133C133B13 +%3C133513133584A8FD51FFAF608484AFFD18FF7E7E3536133C353C133C13 +%3C356084FD56FF84605A6084AFFD11FFCBA2A277774C532F35133C131313 +%3C3584A8FD58FFA8AF6060356084A9A8FFFFFFCBFFFFFFA8FFA8A87EA277 +%774C534D534C77533C133C3C6084FD5EFFA88435603535355A597E597E77 +%7753774C4D284D4C4D285328532835356060AFAFFD62FFAF8B6060355A35 +%5A2F2F2F532F532F532F2F2F5A595A598484FD6AFFA8AF84AF8484606059 +%6059605984608484AFA8AFFD75FFAFFFAFFDFCFFFDFCFFFDFCFFFDFCFFFD +%FCFFFDFCFFFDFCFFFDFCFFFDDDFFFF +%%EndData + +endstream endobj 204 0 obj <</Length 47758>>stream +%AI12_CompressedDatax��}g{�8����>O�$$t��B��@��@ +ՔPL0l9�o��܍e��sv��X��F�i���͍�;=�F����L7���������L�gSi�:����ִ����ҥH�m�!w���Lx��c��}��a��i��f�?�� ~^�� I{�;�����C��~��C�p�65j��p�ǐ��[��?�1C6��f�����|A�_��M��5�D��~�� ��x0�H���s���&7�Ǝ�4��VԎ���7��p�M]r���4eV��R��X�t,�|��>Y�|�Hz����3���H��=����Tm;n�T���{���lu�O��b���ᮨ���}_�m�.���`B�ý ���M�p_?sX�&χ��s��8���G$y�-�Y�g�{�_Z��Z�~fP�I������}4��1`�/;yGm�����������M��+�Bh�QO������5q��!�����C bL�� �������H��-�c������{�,��s�(C�5!W� �"�q�/ۢ=���=`_juأe��jW�����x�����\�=�u1���,��l��l�h��%7m�������G��/�c�����#LO">�,>�w��C�^�����Czu�ͤ� +r"�DX �a�G �Z��"�2�/����>S�����0�ǣ>,���!<�>#�������'����D���Zp$`�Yj �F2N.X"`]�O�/��qز�a8�kcV���g�Y��X��:lK�)u�#�;�Hp��SH��k�RM��p`��| ��v�9r +D��y^f~�o� WԖ~g���X 7Ý =�V�'C0N$lH�ߍ���u}���P���mYP/PY�4�AU]l�@�߆����n 'LP��/RbkI��s9L�׳�6��9�y�fB�T`� +t����fd���j�����bl����Ԧ�]�9�I�=�o�Y�Lw����1V��!��;�bl�[J����IX8��'��*�P�M��!`��bd�[�G�jA�y��_`�,�+��7�' I��uN�F�G<�؟O��?�N�t���8��bO +k�Zo��mj͇[Q�k�@��i,�ۀ.c�"�����2c�}1=���6��C���� �{�&�!��%����&A��g�������a&ѿ���y�����������ܠo�ˆژx�n�>פ����*��x9�n�O�Zv4��i��lGc�m����,��h��U����$ �!�� �g�����>��$0�p-GJ��e( }*�6 Dƴ�O���"���!,���m ;�[���0��m��R�mS��'l������ ]8I3_���>J��?���aXq<���p��h$��"A`��0��#�ع�����qȏ����bx4�E`�a�/��p(Ƃ���F��L��oe��DŽGM�5�L_�ir�6!���O��ɩ��t��M44(0!�6�]K���� Q��^�Bѭ8�����f�W�A��;��4'�������d��%D#̤"I�(�S���N/�#+�zC�"xg�M4&���;���1ı,������X����Jf���З�uq�����Y8��2�E��:� +GC_0��c @�`>���P �k)�|�`4��xJ�/#�U�3s��P�q"A��H����p�Y�lct���#B����gA*j���2B���������d�� �49SW��"!������U��v�Z�{�]�}/��A�U�����35!U?�l�W�� ���btؓ4Z4�qz�����Q��|���� � +h� �����%�Ƕ� ��c��E�T������7�h�� %�vloh�����i�J+j�$'���5u�+8Z�-�� ϴ��3�����_�).' +�Mc�X��7�2����wF8](��0.`���q��C����e�=��ԡ`����uӂ�濫?���2=��_���$9�Z����q��x�, E�x8�7y��p�1�?������-�R<�Dp���W��0��b67$r������~0��@8�a�`0���_���ex���F<�Eá����64���-��[��Q{`�T����74���5F��-��([�j���C�x.�L��<�S�q����b` +�%ܣ� .q��34���7���~7���!�86&�/�[8Cg��͞ܭ�c�qq��!#�P5�9����Q�¿b��;�cD��O���6V���� �+4���o}����K%���K�v�X/�����:\�E?��~8�W�L����M؝#C+R�� +�A��R&���nbC�d�M���m:ۑ��t��!����-��T��m�Ր.ḩ�#ir�ij��Q��p�X-�����2���ޑC&gE�V�YO�N��f�E��|9�9t j���&�+��-\W�\��&k2��!0����b&��D6�s�& �|zy�\��&���H��p`豏��(��k�s=F��Q#'���$���M�͉ҠMl�5�c�so:�qÆT#鹩9��Bae�����R?췇��K�z���7�̭nP[���R����N��0�p��T\�S����#gjzK��ﮇ4�)�7��p"ҧ�)}�S��9��M� 5^R�&3&�R�6j��`6��������e�� �-&&Z@�|���,|�vڣX��I��D{{FQ��ncA��O�x3eW���M��� ��(Y�3����%Ϟ�VE��Om��М_�u�\�Ē1��0K6"�RnH�(j�%�1Rm��2��X�Pګ6n�F�\�eF`_ȇ4�ē�3.Ig��p(�5���T��@0V�/j+�p�*�|xPu��8��um�&�"ɋ�J�`����2�7o��+AF}�H��j�����VDu�`�X�@[�@^-"�+Nof+�ֈ4������3{P�����?jTG�D���g���wlLѦ��[�K�a��t[���),���"W���^��R�+w��U +�Tג��m��Q+H�iʫ��f�0=9�b��@q�` ��D���Q�p����;.�6_��C�Rn?J���#rrԔ���0��4��C��5rl +V��~=��#;5�}�`eC�Tlת��p�� +~31e��)���&ML�X��w�~(Cgބ�G]�3&( D�rS��T���X�w࠲���WK���0!M﵆�2���2sf��/e�[Նce[B��m��P�rʈ�H9DJ���a4�V�X���gG.mm�:����}�Gt�$�߂[%0��Am�m"�'��Lp�q���Ȃ������h��4٘Ɛq�=�E\�8�4:�? ��" �T�5�y�y-̽�;�ȑc�-n�ߒ�y�$TEѩ�� ;�5\��t^��:%��;l7B�Mx%C�^;�Q�L �ZR��\1��h���v������S�yE� +��p�iA�g +Vq2|E���-�5Sm�ν�����9��`ZV��`��=��&}Q1�d��Q����8 +#n �r��-��C_\P���5�����ns��J����c +f�eڑ30��+�(h$~g��0�?P��i4\�<��r�) g�I���$�;�͂� +�}'M��ԣ*d+��-䰅�6R�ڊQ����!� +�$n,k�"A�� � ������~#� \���eQh������1����d/��"�� ��b;CHk�爙4XC�=�F�r�l��!�S8�������N�E�xj�R��=�݄�_��a{��MfZ���?���+�z��g�د�P�������og�hrBM�&�J�PTڣ�z��� +ݑ�?�$�����r;�^�ИZ�HD �r��ޯ<$�������Ǿ �3��v��W���N��g��W�&}�ݱ���4b;�M0�S�b�P����6�$�*�h�<K� +�$c-��V��Lӝ�F?��n�!=|K4��=�)��J�P0J\��'ow4ۨڃ�h�ń����.��%Z#6�Q&j��_FiF`���tb�Ǿ�y���i�2���pOMk@�)o���o����&`�����-��|�S���B�*Ͷ�v�&c �3�63���:$��7�a����������j���|b�7�&[�F{`a��y����m ��m�5���� Uk�a،�K���l�n�b1�X{x���/����Ї!n���P�z��;j��f�b3����Dexadx4��ZS*�8t����^<.��b�c�T��@k� +�o,��ʚn���JG"2���)u�������?+� �����h2Z@�Vk�iφ� E)9*��G�(� �^��@[�c���,�@Cz>��;R�Z������O��"<Y���6�k���^�lw���\��3%_A�!�26˔2{p:M� +�� +���ΟD�+���c-��Z�ZӏZL�hA�����/�$�P��7�@�X2�Ɏ6�wP��a3�b0���LG٠��� �v$l5��@�k�Yf������φ�h(��y��doowb�Riv@#��t�F\�o��{�AXQKj?'%Qh�^��\{��6vPU6���cN����:��\�_�!Io�P�d*�h^��� �蓮�Ƽ��������P6��[R\�)�h���y�6q>ن"���T��Kj�-Q� �V��4��f�����T����"J�ʲ�ݦ4�+o[gS Z���fmA����y� ���eNh5e$����C���b&�8�`k=r10 ҋi�O0i;�1����(��^�MI��j�%Қb��)nfZZQYǃ���-pJ7ZR�ۑ��h�� ;�jMa�M��pǹ���%�ejO�T�Gy`s���bB����f(��j���� ��m"�z�l���g� 0�h1Bz4rD�?�ڮ��mSǾ�s�D@�jL1ך���D:m�>غ��\�c��tU�w��̯D=F�A���ڶ�[�a�|�Y����\F/� Z`k.��-��HZ<��&6k����?���D3��Í��4|LC�̞��#�dgJ��#�R`S���1��� ��<s!A�2d���wӞ� Ƥi���д� �Ç[f�&����!�_ϡ�������<��QS��66Kx��G{�qL@�w������P?b�j +�/iG+�>�w`�B��r��ciAS��e[����T�@R���h3\��0;ZD9@s�X�ʂߛTvU�;��|>%wU�m���Q�c�{W�()�� �������D�V���n��4��v"I�/�DQ�����u +=�'��Fm��|G�IE�4� +_֠K�^e�h�f�JQ:�Z`V���H�h"�0��:�f����U_��n����<���݃+���mt��nĞaܙ�q���L���\$���4^Q&r����T�����I*��L�7�Q5���:�Ea�1A��xG��{��V,�����iTl�M)�EV�l�Kx�,`r��-�wt�*�ן '%p/3lXB��?<3[�y�˥ ��b�0����a��[��N�F���Dvq�1���-SB� 5��'��i��Jx �ڠ)#���7�u., .O�TG�$�&� ��H1��61єx3αN���R$�#�̢��d���{�>�]e�CݝI� +�yl�1� ��f�.��z-�Cw��k!Q$c�Ok-�;��D�W�����ѹ��̅YR��G*���)���4�Ǫyǵ*�3��K5����)1�y<�����s�},�+�s?_�@��J��*�.��sg"tw r�[�ge}hrS�<R�f G�����g���tԱ��žR�%�ў�3�?��d +� z����[8�J��c��|���{��"�������I�t��~Ͼ)���7W���w�ǒn��6L'އ�@��9��q�Ŗ���������yv �����ȒG�S��?���%��p��9�Ǽ��na���Ifu���w��C��z�����sx�_��Jo�ֵ��� �?�ᰗ��ӻq w.c8r�+�@������Il���$�'��EfV�ƚC�z�ʖ�woyW4�4ϕ>Bw�p��v�;���ot���&6�`H���N�G�-����Jd����e�Τ��_w��w ���� �� +j�`��R�}q&�8�)���0���������J���1g"�w�r����)�8�y�F�����g��*S��%t�=5a+2�~�3�>"7P�@���۹gn���C�%��D���z6��M[����W^:� t�}���Ф����N&����~v��>N��3";u����A8ܜP�H�w]I� +��O*u8Z3K���~�yq&;�_fH�Pd�zl�o����p<8qE��&�}g�@�� +�gag�7����d#>S~��A��q��*�-�/)qœ�M�>�9}@t����\-��e�Mܹ}�iœ����n��3=�R$thFI����g��2�z�_�:�RHش�Ȩ)���`pw��l��Ï��f:����Q\u$�oy�kU��蒬d�t�6qa���2��R�����]���œ�a�B�v�>�ao��\��s& +x��040�����L�]� ���������~�ά6*ݞ�[�����ͻ�g����ӹ���� 9�sVt�sSk1�K����9�0T��~"5{z��~��o���1-m��n�?V���;���� �U�♥m� ��&���c(&�-"эc�C����&h�S�ж}x:H��D��=�{|����G�5(g٧�� /f=�ɠ�A�!���t��OQc(��/��n{`�L�P��x��݄Õ�V����m�&��O�̧r�) +>�'�oÔ�7|�Ao@4�C�͊m���������:���@��]� >��&l�-��� l%�Ьsr���o�����O�w +�BÌ��ݲgZ�o,44.��.��i9�j���nj�#)z����A��$��S�}�8B�_DD`Hڳ>sP��q!�l)�禎!� ��\���ʶ�Hp��P�i'|e��D}� ���4��}*� +y͍ +{h�F�\�K��cz�����"bp�6V�+bѨY +D���"�aH�#Z�̀?���=��aʤSː�d�b(-ve���:�*���� lp*�u�Q�������^b��,{3�ia� �i���s�А�@��Z?�6�#��T6D�J��0���G4��sV%�n�0;<P�a�(�,���3�e���u�]|�S������m"#�o��;b[�����I=����mO26a�d������R�-����\��)�'��M��j}�Fи]�ָ���glՏ�%꽵�G��͏]mo&��E�%��r�#_L.d@�Q�6�u����;�e�W��GW5e̶#����֚�i�1h@[>ػ�y1� �B�ŀ��<�����Z�!/&����<��/Y�齜A�@*��:��ۜ�U��U2!+�`e^R�������X���H%vU�'BO�� +���$;�M1�YU���k�=X�� +=Q�9�&B!� +�Uh��|�Fp��J�s��= ��K�?���k_�ގ�Q�c�Y +����ĭ��)�[���>����dݗz5GYw�� ����������?�1��~�c�/�J�̲��Jc�J� ߙ���,<�y�M�+NUY�I�2D<��ᡄ��/�������G���\�G$<��3/�T�gﮟٮ����V��܃�?Kf�/�V�zV�N�d���)�~m�� ϙDj���b��$���%��b�h�$^�f���!��W�,����t�������E������\$vW���7���&���ѷ��p��T|��I��8bsgk�a���HV�:��\y���v�7�|�iʯd 4c��J? ��b6z+�/�)����'po��f�"���`T��2��"�/f�̹e���� +5���3��nc��t� 3�O��In���8��w>���;F9�)s���h��S0FH�Tņ7��4q���A�@��|~�|������3s�7�m�U�> �C�{@�h �Y~��-�� ����gUxu ��[mے�s�i8�ϓ����,�G({���؉}����o�>`���R���C��^|d��wO��ј��m'��}�+�Yⓝa̓7W��:��DM������i?XZD���eV�+W��m����2/f�K���ǩ�5W��j�I睎�T���|m���TDz��`�g�оJ@�0l{ܒgV3V�(�Y��Eq���t[X_j��s��\��P��]� �<~Q�Z�:�����.k�H~ۗ(�{�=.�.��1�ӭ �UX�V��6G�tG�R�3�M2�^�>g;I��{;�0��`�S�"���y������h�Da<`�VB�'�ϭ�A�@f'��Μ��Tvqk ��ӛD�Rb$47����x�M�x��WR����,g���v��J�T:�5y�M�o�G�d$���m`|w�Լ�D��oE���B�A��%�$�B~%.�.��v:m"{�����PI3R��o�Ȧ�fD65k-Ox)�.��MҎ�T�]��^� ��nS�7r��lw}�T@���h��/5�F���R(�ª�v& "�7���.?[~ 5�4���yHu��x"T>�<͉;{�Y�,w��%6Yv�_��i܊Ȭ�>�L�u坓���d@L�b��+~�t�5"�q���pd�7��'��L�r�ٲ��G��^��pmon����EK�D +������}�sSj�Q��(У3;�z'�Ӥ_XF�-�0�2�ay�Y`��r�+$�I`wDCL�v���<�G�V��A�J�������)���6��a�G���7`,~�u<��xr��'�w�E�YG���+"$F�z��k ��+/Pd� +hP+��o��VTR�Du�7���cW��5n�0�F�JOm*h��+56`Ta�X�����`6�d%�������,��&����`��ww�\�����(h�n*tS+��șΧr�,"PC_�U8eA��!�;a���f�=�����c��ˬVہ��q�H���#,n��,�� ��pO�n�`�&U��\�� g@-|�%��yȏoC_��1�|�Y�[ ��f�ӏ�����B���`Ԁ��{ЄC4���[�Y�: ��Z�5�+���(�hx�o����� t9����k�7�����q&�^T�Pt�Q=�^�]��<{w�8k�r����3�J��g�t�@��F����ݝ,��������i�N���y�$trLJE�!mg" ��o�eXF �=N�N.�)G�+z��cF���x���A�f��[��D��C�3F��^B �Л)�Z��J���964�G���m?q{n���1�O2XN&���W'Nf������`�����;W��o�}g�k�N#�����+�H�/N�����[5<ݦ����D$�S���6W)���e�JҕKh����f�f�r�`�6�:|.B�_G�I�_"N�Y��e/�8���4��9ΧT�6��@O���ք�CS}k�v��d2n�|CG#�r���{�}�f��L���с|�0�Ê�'�����O8��gfd�u�����7���9 �o�iEQކnص�@��=q/�)�io��k�-�/�L�T���o�0'��� �-F����VHE��X��c��]�J&q� �� Z����F}n�X�/l��8]���)����� +��q�F�@כ��'�Qj��~�����*��^�?������ ���ʏC�`�f�/ҋ9��0��j�p���ww#�L�������5K�s�#�[&��m�W�"�8��ŖO��E�N�n< ���V����Sw��ʾ������yG�*���F�E�H ���x��>j0?j烂����Ac�8A�n.�ҋ�����D��凃Wz�47�����g�l�bB9����R����_G`4$�ڎ��X�Q�`��v��S���e-�}g�挂��t��Ԧ��D�z}�Z���Kt�=iз"��{����x{�7|��4�.�.���D�����j�خȴ���Q�� :"�R���L�*d����9[l`a%���?(R��rJ�3����ȋy�5�39���'_ ���^�O���?��g�IQX�OC�$��>�S347���'��k�Q�3����Ͻ��5_�g����<�ZfW�=gvc5�}����9k �>h�`nH� &��F]�P�1��+�I����%�Fi�����D�D��T/���>{X�Gt��S�i��c�y��3���a�F3�A�o`.�q�u�Q� @c�3�]�|�j�Z��c�����R��VʻLj�W=GE-w�[^c��n�� +��d<uU3��|b'�J�v���/��&p +v�Ï��_�����A��KG +�Cw0bX��b�p��ݗ=Wü�3-�����^��s��� �o]����ZR�q�ſܩa�~��*X��Ps��)b�#o8t�U�[D��Ke����j��JXw���bY��V� +�#�,W���D�Qe���'F�3/�c�%�������T.V����X��j��F�����W�X�+��+����[���hjc���a��*�V+X_��+�*�}uFM�k�|�̼�X���gU�a�e��u#�Z�}Gǜ�2�F�;�>������DW��.�ݚ!�� t�Ş�������Օ�b��!`�s#���妖U�:� +�AGkK[I[������Εdw�6��I>�>���%!�ڋcհ�XGX�$�-�0�i��V?zC����rB|�a�a5�WT +@Cߖ~c���s!�cm=Z��X+dˏ�`�pc���a�$�x��"��ѳ��v���*���e0R�Zࣀu*۸2����W"Rƺ-ߪb���{��Qn{KVr�Xk�|����K�W}YR� +%4D�� N"F�/z�V����]ף�"�~ɽAX��9���4�`��b�ź��5��5���y�5�+`E�'(��p���o�-{�:t �>k�V���� �4��:�<�����oà���iw��'�>锍��������%�Pt��ׄb�X!VB���p�{V�c�6�`M��L.������IJ)V�n7Aw"���ݥI�c�Y.��?��5��Q��"mFߑ�~Hnr���TL�@x�}����s`�T��u�H�T�yxpfY��!ò����zN/#���;�<���ا����9P:~[eOEDݥ}����U�&�S:�OU�4���� R|(�_i��������\<��O�ۘ�����DSh��99�S�����kV���=ɞJ�6��[T_��7�Eէˎ/���Y/�ķZЉ�Ǡ�Ӳ/�xW}:ތZU �=�J�����ڈT}Z�%oq ���>�=��z���ܨc�G�Sg��N�O����)@�i�s�%ə�JO��T]�4�j�N����̺Ylb�� +6��~��7�y#�A �ͷ�@�8kv��]������0�r�,���^Ԃ^C��Yc� �p��pBtw�>5ܬr��� +#q�"?�q���&ZU�Zdc���9C�5��N��w�4�9w����["��X�q��Ek���u����bānO+PI?�*V��>�T�4P�����N�X-�k�9�a�<<� X�9���CK�������V���*V@�'�*V�еˆ]�o��/���t@jH#�B+t-��X�f�*Vd�U��p����)mɼ�Q?����ֲ���@S��a��m���ο�e��`��ip�r+:2`��i�(\$���m ����a�ʙ�V���p��%�Ilm�6� +�5��Ƿ<H���-?��h�#��0Q�� +��5|��q�(2�9Bw����LI� ��wN���?M������|�DS�A9�u���>@�����x�pѰ���2����������7���ԧe���'Ɔ>X�\>k+ �Y4��u�Td�?�:����q�_P\@>H�����9lݢ&�`��4��#t���į�s���4RJ��E/1(�hh�#�C�A3��n���es6>�WTkF�,��%+H��^�L/Z>�^R)d�I!���;/�_��3��,��4�z�d�����"e�}�y +�tǕw1X�1qZ���u�er\oy����������)��';���Vt6U:�s��<�,p��y�������!Ao�]� ^ʄ����:��S�3]�Z�E�Q%��r�*m�s���q��(z�Lf\ �1h��86����C2�8�}?h���z�]�χ�ߨ�B�R��bҖ�h�*�L��>f0B(9;�Z��o`4��b���6����_�G֙ƴ8��eR�Vzh4*�舵�Z�H�6%e�n��8{MM�8� +�,@�eƭLS6�&��>VS�}����b�n�e�Yo����g0�R����34�Q�l%khhy�9���C�f�� +����*i���#�������H4��D��wW#�T��N�����ݑw�O(�#N��b9O��j2-�>7��ъW^������g���bԝ�8��V P�TO"�Qw�(:x!�4��� F�ACC�h,�#=A�7F�@����8��Z�g�MO��\w���a��C�_oM�dvG��xS����GQ|*A��kS����|�D4��~�H��nq�1�Y�Ow�qâ�ko`�q����SD�������L�Q��z8�72�U��Jp[����p��4��x��.�|���0f�E��W���J?�r���bW�v�(.v�%��J{Y��ݸ�X�B00���A��,�˰��G�}�uYjܫX��#5�����!�&�R����!I�|�jj�����V,0ï�!�]>R�g��e���U"�L���F/:( +��luB�H$$! ���: 3[��`$��ofWdf�Һ1@��˽vwdz��l�U�?��곅�XAD��Ƴg�$��"�)�Sٝa�mE���Y�գ��� �z<S�m�ʑ�S�����#�|�m�̅�]V�"�M��N��+<�Q��T�oɷ2�V�-��JQZ�1�%x��������_�s'O[ `|E�i�e���R[�JPJХ� +b6��4]�M�˨nr��u.��͢lZ�� 0'ˢ,�3�ϑ� ��<'��R�t j�Ѧ��t���#�F/�"7�"�"h��զ&��j�y�K7Q�@��t{�I��(�>I��J0yW�n� +�n8M��tc�A]@W��E�4v�\��U\A�IS�E�&ށT�]�<2.�xDGQu���V�Y]pKݐ<�-6�]�,X�um1itg�� ����BB�(V��8�K<nan���r��ʱ�/���gUȠ(%� @*�����r�T7�5�u94ݸ�<?MK?�:����6��${���qx�T�90���]��SR���fD?���K�����=������b@2��<����b���5�b�BQU���I���Wk=*+G��+��]g��ɉ�j�F�������a��ƴ���b��һ�"<i����t#X#��nh��h��� +fӣj+��)���1�0 F�2�ʋL���7r<d�*�Q��In�/�>9hd����I;���������2#����������oy�T�LD�C�m,H'�o�`@�{�ݣ\,U�0�'[H�:OJ�\"X�(:�$��>zfvo^�fW�;ov��߰�/R9�v-J�F9�v-�L_Χ]������i���HK�/�Ӯ廑�.�]Χ]��\��O���FV�xv9�v-\7W)�Ӯ�c�����ۉk�X���r>���}�3��d �2����LB�9�|�H�i�5#�R�vr���A��-B��zR@J�!���ƺ�Rs�?r��-�I*Y@J�T�n�3S�K��U�c{�T����ٹW�fy���1fxt�>B!� +���4 ��'�|c�l���t֍v����=�i�De���3�ψv]{Q�����n6 6nΟ�_"�]��IAye2�('\�ݝ�_��F���K#[�PΫ��@�����3�����.��y����~��3��걻A1$nD�ŧ9�GS:��i�9PF�^��5�H�@�j��K#��@�MhD,��le�����q�-&c�S�ѸƓ�vB�b0E���8O�)i���Ib\�5r�r)`���O�;�>���4�2�7�:����%L +Ҩ��Imxw��E��hz.J��5����vL�^��t��O��b�B����D4��4;Ƨ���;���[�GU�.�1j�B}�G����Je�^�s`���N'�o��.r6W�x5pV���J��?� +COP( �YQ�(a�O-�W���t3ꨩJXl�'�H���)����+�U�ӑ 0$�/�h��h���*�r�S<d�Z#%ҫ1�N �n,HV���������:�$;�����v���))�}��f�T�ĂdF�$V�y��2��ٜ�-i�|F��!�J�N��h��D*�Z\�nI�7���ͺ��Q�4��M��� l���:��%�|Qћ�U����������z8���<���.���:��n��m���n�c�@J��)�*7��Y|il��Ǥ�tE�4Vא�a��'_�w���mE5�#*�0����c��U�QQ�`p1�Ń,aV +�è��{�X��KQ��z��z2��!�]��qf��~B�n�"��%Ŭ7��9խ��6���h���.45�ze�ؿ1�I~ne��n,��neޥ�f�2�@��5*�І�qq�ɰ��y��A}@�����.�Y���'����W�̓��\'b�2��ș)�W���+λve� W�w�,��B�?�w'�.1h��UR/aӡ����l~U�K7��l��q��y����R�:{� �Zî�:e|z��w}���h��8�j���k��(������o�ǎ��}���[Pu�n�, �]+�����:�y� +�z�*G#(�+����2⅍. #I�z��d��;6j��p��V6��v�q����ݢ�[X0bx �d�y'�����\�Hvx;R,�.�}�R����5�d!���º���B@��B(GE�j]뗑�)+�_B ��)L�zt+��wa0c�����Z���)�����[@����(�h�HQ���Ey������Ey�$T�wzQ����&��W�F�i��g�r.d+�����M�anT6} 4C�i�rQu��&K��(�� TKg䄸;n�SE]�h�=��tE��?U��1��*,cx��K%3��t�h�>/�:�~�nr�QK�h'��wo��d�������T�j���8��x+�څ֖SN����-���i�����E^b 1�ʋ����zM�a ��q3�V���u���+K���ݵ3��~�&�ցv�_�a�_�s�<Vy������QV�v+���p�*Vg�q�V���� >Ջ��Zpk�b?��V� +�<T��D�؏�*l|yWǚ�(Xo��)�l��}5�/G�-�}b�=���M �|V ��A�c�LS6S )X�� +&+���: .%N�5xρss���x�������y�����^��e�O +'�kft�w���a,����:�z�# ٰ��1��I���i<�&g���}�%7��@ �[6g���\��F(��n�ܮ��'�ȝ����'����@�\�$˫������(6n�Tاd���� +���c7����I�V���֮Uا�U��{*˪s +���� Ѯ\�wv����>%_N���(��T���O�W+�S���+�)y�H�]��Ou���}JU}��v��>%����\��Oi�U����ӳaUߍνQg�ɷ|��е����F~p��}��(^��O � W�y��>���(�S���t�œ�f����..�S����+�)U��://�S �X�Ja�RU�R�ʅ�}Jv���{va��@�G�v��>�YR��O��O��T����Ս�� +�dC::����>i��|��"Y����w�S:��) 7��w��ኰ_y�����O�-O19��g��[���j�]��z�*�6��i\owtg��}B���~F�MU��'�&��{�e}R6%���#����˔�˴�e�[�[yb��-�6;��?e����;?���OL����/�3�(_|�"���k�ԏ�5�}����.�����J�\�'��n9��?�=����W��?�g�m+�Wy&_�{��9;ͱb����?���rq�� <����~yM�fz���nT�wA]ӍPVzo8�Z��Q9-D�=��;rɍ'%�)$\B*�1X�T�Y�)#l]�M;olè�X�7g��\HrJ��f(��X��f$�\;�I��b�u�$��tq�/�"ցʢ� ����=���W��m�a��n�w�!��Z�r#��4R��kD��cK��O�m����T3+}cw{��.�������ȏu>�z�<RhU킌S.w�6��n6��7gb�TB��> +]�O��ƻ�1 ]�eh]@�������^�)%Na1��t�����9����{��ָ��:%M(-A��?��Q��?������ �����.#�{�D�v +�S=nS]z��r���{����$h�j_�{���yV��H�2"�>/6~D��]����W�{��=�V�ⷧ�/�����+�(�+dt!@F�,�F������KtUk��J�-�����W��l����)VL�r �������v�ʴoU3�B*80R���I�;�b�GB4�g�ChF��F�SJ����f�'cu�PK�"��;�B*��a�R��B*�L�� +G?�2�s,F����J�|�XFY8�+'��v�w|n�[~���v�<UK1��]�2��2B�F�@Ы�$D94�n�R;4�n�ON�ݺ�e�l��D5�*e�p6!��+>�sK<���rwd��K:[�'j��O�Sg��IL|��m�QD0",8jMR��l��J*��N�!�lI���e?�J�y7Lm�zI��0��X1s�U!��,��K��J��>� +�~u���ޫV�����4��Ԯ��k��5��y�5��gw�eE�v[�c�R#g�o�X�����V^xx� �*��X��t����{��`�%��r�M%�L:b�JG��X>�JH�����OlI����UjwÔ.J�������Kh�Q�<+����n@����((Ӭ��k>�K��,�k�.�Nʝ��y�}�ۓv}�Q0E���EsB�z���s7������3�-��8� �[2R ��@¥�Zzy����&n����P��j���r���B���1�A�n)���ާ�ݨj%5r�N\7�F�,�<ܣ�L@W���_'6��M������uڱ0>���^`�b��#+�+�����wΊ��~�r<-������Q;9�XI���uo��ەis�W#g�A��H*��N-���*]����ę1d�=X��a�0 +{���$ �~�2���<@|I�ݻ����,$u�z����`&Uƪ��"9����{*�uvZǽ1�%�R/�O{��*���r��R�[d[x'�%�_�&�F���i_m�c7�HBS� ��a��=/$�n5�ID��=�h�wB�0�j�S�hGU̪�� ���ܒD5�]-�̒DI'4�yS���D����qh�%�*|pT��du�P���s�T��J��#'��T�h��r�ybI�"�(�#�x�z%��x�g�$����K�B)��c�j2�N�� ��h�q�� +�h�tQ��e��m���cO����h���� +š��B^����PFIҰ�Qw�juƅ��O����C��O�CYf��j�_o�˱O��Pmp�+�@� &h�je��C���+�j�.<�J��e��yم�2k^v��p������ޜXPvfN�B�U��v(�gU:�]'�y҅�ڷ����ȅ����k��C#��W��#�r��C�{��m�jv���^w�b|�m�:{�/<���^xh�+�o;X� ��t�ԓ���C�$W��:��C�<��"N��P�:�ۊP���^x���� +����<��PunD[=�.<�9��P+f���-�����՛"�y����O�Z�xO�J��7�Y�����>��C5(^����/<Ծ���9 +��u���\xxBy�����m�Fd���7�O��P��CѾ�E�t��!�ȅ���)���C��q�Dž1g^x��CE�Ͻ�P��VJ��s����5\��.<�6~n�c�:X��C��M]v�P�T,���6�<��.<T� �/��\xx'ꈣ�]x�]�/ۊ8��C�0/l.��PV�&s�dj����{��\tᡶw/^�]x(#�ф�S/<4�{^��CCe��_x�}�!Bs���2 0W��PY(p{4�Ӯq���K��/<�;��<˲Q��P{gB�FO��E��m���:�]¨Q���v'���U�=-]Q�������~S����K��u��b�"��O[�u��)������C ���u2�S�Y�V���G��@͔�Ώg�}_��&���l�%J̶1{�ۀ7/��WZ6��{m�f~3Xq����=dB����> R���!�P��6����G8� �#5��S����j!0�4���I�z�����o�FN-oi{ �s�nV��U�SdҶ���w�M������Z��B�~�Q*����I����R��k��1{��)�o��q���Fd*����X!����Qێ�����������_��v>y�o5z���xw�'o���)�I��c�ڏ��/[�T�2�l;2oX�w�Sղ�E������b���6����N���lv^�����ջ��<��e�\�|pm�0!��A��4�n�cr~kPRk~+[F`p���x��C3�St(qJ�H�\� ����ٯB�=���ܦ��x9�'�D�n�ȿ��߀r�Da�y�LC�#l:�\�Q�\�ame�;�X5�и�k�J�+oo}g��^����+,%v1��D��C����`rC�{�ޠ��Hho���3 Kx���Ȟ�|}r��@�}���{��y_-�1g�u l�R wY�}�Of4��Yt?��Pq�T�c��[��;L�����L�=+d~aeóC�۫m�zv����]��-)j^t~��Gh��%^L6�//bࣙ����4[�1V���,���O8l⅕Sk|�,Aʽ��/�({�f��� ���������� �"�����#D��ϛ��g�H7��j�R2���7�Bh_��rK!���� ��AS��R}�Af����,|�"�t�`Y�{�Džl��:|����Ǽ�o?�d�h�d��7777��Kj�7/��������� g���R���?���u|�����1���W�� +�0PO�s0w����?�--���7�y�?An4=��Q�n�`�U�>�����:Y������2C���B6��~y��{������'���C���im�?z�B:�l��D�։�Zv�b�(�\��[��ѷ��4:�g�:kd���̳� 'y��K��ak���o�����3�9!�M��r�0l���'�8FD-�I��|WL�Z�U�� +줕�=f���lGˍk�����d�����S/bP���'�%�C��^�i��lp����L�Q<́v��� +g��3���5�!;0��O�S�r����*�Y'#b�U�Ŋ�D� �h�}�#��dV�B*e˄;��`���_u�a�b!f�TC Pg�k���V$L ��|�AH Q��r����:�`�[gi����甕�gžP�"k�yk��4�����Ͻ��9�������#�����s���|��n��iv��>��-�;�O�?���^4�w;��eX���;�L��l<9�~f����q��^*?䗩ͯw��X��t��ǖ+}��@ +�nS�$��M�_.Ѕ� ���rI��X��a�����K�]Żt}��۹�%7}����F���9lr���vO�;dc�r�z�<�/����.���F`��>\7�c�������Q��w���Q�y� \�n~��/��m2�F����SQF�Q��c����s�w�?����9�e�O���U��O��9!K�����}G^溲��Pq"�ɞ�A���%��D���]��L���"���^���O����\i���� +�0{kpQr�њ{�<��@1�>s����y2��8>�Ã���sqh�����1۫�G�Г���a�������]����V�L�Bg��wP�³��.{ +H^G�evG��f�bD�������I�-�$`��5m�s���,�/O{�Lu*O%��o��P}nxٟ/l�'�Dv�Qr0d����:�h�cF�A�<Ӫ��lhV�u,�����5�\,� �x$:O�짫u���̎9K��>�x��Y�>i���t� +얱^l�A4���h}]�irC��E���2��Z6��|���>�][,��<��3XN���5�#�_�bh����ר\��-�Lyw{Kf��kѻ`B�>f W��u|֤� ��q�y�9_��<�p�Cwt�������`��y��ج4������&�sD}�<�S_Yh6��Nj�$�6��b���'@�LA��Ә�A?�������/���߀���S��e���e�jT1h.3) U7���B�!����DvՉ47JpdٜoM^Հ�\�ޠ��+�� y���ѕP3}��9�a�!�� oQ������4=����>jTs��Ag�����ԔSƌ� ǹ��,�jԢ@��R�O<��3����q�Q +U��ZՔw�����WP?����*��MB�?�o4D�: �ߓ}Z��&lj�����H�o���Һ��y�VZ�m�U���9Ru7�%��>a�@�l-\Z�?��� ��wd�B8�cŒ��M�PxZ��=i�O���NU��s:��p���*j4�K��1��v�����ip0��8e���Ȕd�љ>a���ih���ȐS(Ygp{�+�Y�f��7]����Ξ-ev���՟��W��5���!�g���c�0e���%��M�fw9ڽv���#�^�^��AD�nD�Z{g���=���s=��"JCg=iC��N�\�5�����y���i +������7,.G-b|�i�z�d�V߿c�i`iيg��6��Nޑ�BDoa��Qrd����}�-�0؍*(l�tDg|zcSFއ�3[�J������N6w0�~�h?�`�C�MZ=���hBɦ�3�~��6d�OD�>=��`9U幛���}��/W"��X����$h���W;���*������v�������GS������/��gg_�v�O�>'����l�x���C}��ξ�����V�>���T��:�:.��D4�Da�[�k˨e"i �jP�d���m���O���3��b\H��+o�n�j-������~C�cp/�q5~E��C�W��f~�y��Qk�uGh��0�C�"�0��F��H��l;&o��[}�u&�X�N������`G?�it��-o�0�/�gN�<(8jt���#��"��<LZB�A_|ĥ3��qݔ\�ĩ����3��-|Е�e��ͻ�����]���/Ϲmdi~���@Vx$�8�����f��x����*z��#1�|G��_D���y��!������P�nb���[�˶>�t8|�y:�n�r tP%�?�b��D&�r%��=E���jO�1�DH�e�]{�'B��s�����T��9ۍ��p}�2��0��Ԙ��G9���f/��C̑*�h�`.Y�����9ge����@'X)�C̙g �9|�W�g + ��N��F�o�.�����7���i0lb��ֹ�"�+��M̞�`���y�Laccn�9�[�#P61{��wBNM�7eS*u +��冃�SS`�����R��NbO����D ^ +h�A�=�b�5���H��Ĉv��l����8Mc\v%)�r�Q���8M�UŜf8���oW��RNӆ!�S�-�iv�����}�8Mc�� (i�5������R���>G�9�T��#�쇒 <�2%}��w�M(�DJZ.��*i䑑?$4L�.�q���r��Szp�hv��.�bÂ~���ኰ��#�s�� K��A����C��փU��A�~1��Gu�n�2���bk��|�Vцj0a�=,�,:�d�ߺАn�b?�_�U�M/��|�+���/lb�Ÿ1������܃D#<�Y�������jULx ��BObԅ�5�a +ʾ���[ -����V��uk�:�� ��z/���,�F� ��XϰQr<��q�Uj��_�E8�3�_��@2�G��A�x�l=q��f���\�f�#��x$����<D�3��]D亣��Q��� ����U�wq�����3�O�l���q���+�t;�y�<�e>0fð�}���v��B��x�GU?iC �<�k5�rlxn���4���<H��D��dz�" +������'v~G� Z7l�m���3���x��|Z�Olw�Cߝ�� ++$�g��_�*��F��+Q��v=w�;�?�f�+�~��-����%�{��8f3��Ë�EA���S���d>�z����o\���;���M��6��+��� +��bC��X�?��K��:�If�a� +A��A�Z�+�2��ʵ�W,e��b-�A�Аr-�����M��'�|����6+rW�-f�� ,�Ǜ�x�%�L(bG�m�}���fo����V�T�s䘚�&������ +V��O5�D����4ZX�O���&�Iv� U�BCřXƙJ)�|1�� ��k�Z��ٍ�|0z�x��HD�B�^�= ���8�i���N<�Ү�s9U�҉H1��!�^���}��\�趉��ӘUu�X���ʍ&<�;�� ��:䞎0QN�)�ځ�7��S�L;5}m?��}T�-/��K�E�,oH��D�,R�ur�.�����/N\�f��R_��5�o@��"!l����2��g]� ���Ɯ�Y֧�/Z���/�d��K�+p���"���S�ωpe��C(*�C(\�8o{U<����hA +ܖ�\���ή��-�Ƴ���·�?1�Y|�Fa�'<��3�QQU}�+�E����y�/N��h���ߋ�_-�% �g]����[���b}��G_�>pΪ ���Z�xk� >{(�Ӧ�Q=6A̖�3��h���� �����x��p�w�>�B���s:�5��gm�Zf�����L�&K��������}��{_�Wb�0,�b������~:||3��y���~�͠`~�g]�Rdσ"߾�������d�f`���\���\<N~��U!�f�f�8\�չ��"���"��C��W_^f�?�^���d?冼�������ճ�/"�����Ok~�N!�0�.�bM��6�XPR�)=3�A~t�� Gž� ь}�k��*fxt8�=ke43g+ڹ%ޠ�/���MÍ!�wq�x`lO��9���}�� PHt2/:�j�I0^'o��:��c��M6d0By�c|6�C��1h2�6�O� +����H���e; �8ƾa�y��ł�JR�����f1�(I�q��b&�� +On�@��If�K07#S�t��ˊS�x"�a��BS�&�8Z)����"���RѾ�Mz����t6o��[~��s�K����k���pf-ɼ�_�E�~ن��m"Y�6T)�lC��%�_{��U���ޟy�{����=$�л� @ $�`���QD,���PC)���K�Bz�pߵ�̙3sfBB���l�qrf�.k�����٧�eS;s����}�4�W�YGtC�Xn��L:mٌ����ޔf�8q�]#�a�&2�� ���~喞�X�O�Q]电<�x�h�f���&��]��J+[�27� ��W�5<���g�����&�Ԏi<d�8�����fB�#�r3�Xb�����q=�Zf۰�qֵL����m4㳶x-�N�|o�r�閵�ݨ���l)�[�ܒVf�ʮ��4�ހ�uX%"�Z���4�Q��v���z�P!�Emv��:�Wv \��L4�+$�{��hڨ�z�]Ac� +j��D+VG�MӦ�(�4m��i^�a�o!嘑���iZY�j�������u���f@M7<�����5��M�۩[�W[�{��Ŋ-{��:���|�$���5��/�@���ܯ�T@ܛ���*��7Q)�HZs�� @喴�Be:aHZs��j�Yj�=��QǤ6��� �9��7e1C(�;���H�Ȍ!�4S�qy���Y��F�D����dv��5m٦Ot�~m[��aBQ�=:�E��:�����-���t�-���i���y���@o��kF�~�mRu��r�~�mRu��f�[���!t@o���Ϊ��4�<��v������yi4����y ��?��I՝�k�5�XZ�����8�� +O�u�d�a�ﳟ���փ��Ss9����}'�H�X@dI =�e�n���f"�?!عS'z�o��B\K,���ZI c��^M��w��A�!F�/�i�&��z-;t�,�ey@��v@�n��S�}�ߕ0h�6���0@�M�&�Nws�B��|��`暧�.oڀ6��>�3�<���9Bʎ u�Ú���S���AB)ձ�݇��x�<�{��|b��ҹ)��9�C�H�z'.�ǥ�Q�S&0yX���ѱ��G�y���?zWu/hA��LW#�7d���#"�~J��桓�ãG�G��FNz�т]�=��pG��a�MKGC�r|Ո-��������W};ttxoBܤx������c���a}���^�ĉa�kq�Pz�.u��q!�v�)�'�B8N�]dA]tp!��j��j���*� �5I�EU�%��uW]�yU�TN�4A�NDYp_F��Ԍ�\4�>�����ڻ�stwy�s���/�Ԯ��!�.QC�*`"d�A�yY��4��Vy���2�A8��U�dtB�BxEtY�uN�E�EUY�%�!(!�$钂�ʺ�8�ЎDm��1"N�9^�y�Y-��)K��)V�,�a^�y�@�8����9� +���Hu�Y ��S5I1�dI8I�E�� a^0�N�꿀607��!W�9�! +����� �~Ie��\�А�E�̱�s#���=o��k~��F�b�,�`'�aiHU1Ӛ�����n��_�L�=%�.SC��0�,�J��I�%At��9�l��^��ڱM�!b$`�J\q�&�Fa�OC*�I�vl��"b��[(uQ��S�#�d :"���+tD�0N���PG�[�xN�MԠ��� +��5ɭ"VM����*�农�S�� �!�Dӂ"�&�,�N���ӌk��z���n�(Rɘ�ȼ�F"k!��(PbU�e���hd�T"Rж� �T� ���ъC�C ��&2 ,H�x��WuU��8�����Yf� "�÷�ΉK�±j%M� [ +�F��2��U���$haJ�(8A��Y ��B&�$i��q2k���Q�-T,ѯ R�*�L�sԮ(I��Lc� ��R�5��� �TT��z ]g�&CFx��u���iTd5�BTpF���� +�RxL�,9$=D�!o2tD��5h���2���M#����AE9�E�*& +%;$�N&(rp�$"jU2`�ą"X��c2�pxMƜ��R;��% ��kȒ��C�BD���Q4��F�� �CTC�]jE��c��4Ř�mlvD9D�a6tQ�I����Fīd��z�E��_�FB9Eh5(��tN��0���~��0�)�:�Y�2h�o�1Ц�ʫ�ª��.��d�2L�KT�[ +\1R��5F���U�] )<P�`�&V���T^�Y5P$�$㔉�(����]�!��~��5h��nG }�z(D��h4[!1���EW�C�S����O|�C@�������\�rEf�5f�[�Y�; }Qh��a� xӉ��@��Q��� +k��'$�4hԌ�TWC� Nq���ɼ�P5F[��<��h q�,�1tV��Q �B��5��9HkGAg$����o4���wTدB1e +�/�Q�N�� +0>�����d`�B�gAF�1͜d4�µ`�9`�Hv��1y��L*")�b�d�S��/ ���*�$^0Fd^ $%��aF�R��x6�:�q�fx4 0O�*��5Sa�4���p�O�s@�%��p� �<}����L=p}�ch+�\���P Z���A�0#�?s%��2�75�=,?�:2�,�\��@��D�bT����<�(̋� +��3��ȟ"xb�M��L&f�!�����9�á�@Y� �T�����@J舁;��Ac�(��"O��C�$�L0s +p|�0;��A�z��@�`2Z塖�Bl�����p�Q�p�$�C"���c��\ +D �4�&MkH+!ph���[FA=����a�H��#8�~"�$8�A��P7�7�Pb=��sE�a�xg��ae��p# �Ր������`�]���0K"��9�U�!�(h:��<�Ԓ���� +�t�\`��Ր@n��A�(a>�L�>�'����Bx��9�!��kTC�).OU'�� �u�)O���d�v�U�)� t���@"߄�[&�9#��\���n�r�!�0�� �܆S��d )�h�1�2q�i3�T@g6�E�&�?Q�q`��O02��������|3h*j����2S�:�����@� /��� �C���R��`�]�\�8��$��W�I�0) +c�H����Yqd�uķ��Kq[ ;����8�j������34c����I� $Z*L,���@��K<sw��`��XL�������� ��Ɉr�-�}��*��#��y�:�$`8'.9��IUW3��'�GAC����f�զ��XL�L�sE��� +C�1w +y��i`,||�0�`ΨZ����N&�W46_b�)�@& � '�`a��p7a�a�H��L�`#�]̀e�.�5�h0z�\f���#b*�*��L%���o�`�̓&A�!~Ÿ@_h���yS)�!�������g����%�@U�4�HKnB������0:�#�%�Er!�4a���� +p��\��@z �<��I��k(�a�E&KH��K�a����a�i���+^s��(<)~a�Bq ��H^7��w���A���C���w���ar$C���N%` �d��O���]I�1eIi��$L>Ϻ�@�В;���F *!T�<n9��nQ�Gt!6y�h��p;4��N�bRHo�0����/E,��)s��1��T �I��� 0�� ��&����̰j�T�Mp���`���N�2l*�|� +�sM �$�P4�H9@�ur�)�"3��� �%e:D����> ������Co`�8 +PHX�)S��g���̅�C+�f2Ѩ�����Ib��;"9,"��(��(d��B�o���� +�e�RvwP� D�ǘMFP$܇(@�����%V�BF�M!�#Bpd@�e� ��6@!����Wx��x2�A[�����B�#�7�������J�����{Pp�Q@Q��K2���r!l�(�7F-� <�=�� +��l�x`!<��="ϝ($ +�e��:��4�r�8��۠��d}��C��:�#�\�$�j�ب��0�'����$$� �d['+&Q*C%��D� �ˠc�)K�|L)�%j%,U�'����(��W�ͬ�,�3E�&#��� �u�N!��G��Rɹe�#�M-�����0%�N��/a6��=��T�H��I�7������������39�:H:<8�ҝ�,����5��"{�� ���� ��;;H&}��D���)'*��!�Y^��hyS:8��@ �<�qF�N����VrF�6��D�i��2#���H*К���8�f + &���1��p��N�dH�����_��H�b"�s"P�JA��= ��-�T���,J{0�N^7��2��9�e�@*�A��r%4��C$k���%_I���QPX�R�M1RHp�)-�S x9 �-�i䭱�1��l������_��(�#Bg4Uvu��☄ӌ��l/��]C�3���F�hEf" �St��Pnf+�a��Q.�'w�zB�>pYf$���������H��Y|�Є�/��1f���LPY<�D-P�r�@{���@�����˓��l���I&,�AA�9&Uu<��N�\�P�A�l8��H^�_����A��#]��H#���� +�Uj.S��h��d�E�\��\���X��@f��� +�=�Rv!Pp̂0"��$i$�@��֔��bCae�k�(��:�rx�����M`�������$�Fc� KFq�F�ҕ�%ǜ��(J'�$%o�j����ƃ���D�sx�����Oe�p����Dq��%�TC!5B( +����&� w �!�e�?O�G�:�)��fI���-CJ��Ԫl*��r�� ���b���2���)tJo�Mb�]���I�7�t��( Ϭ�DIp�-S���5Bw���]dQ�H����8���2�37���+z,�,6��#�#��� R@*��oZ��P�ہP^�ZP�Y�W��I�2����"E"GXf�'R�U�����1!%sK������JY_�a!�P ��c���.R� s� h�V$���^(�����Z|.��X��M �@��x��XCP�h�p�Y&V�V�y��&�PCx�0�H&ׅ��y�@t�c�L +�b*h��P""*�c�ţuJ��$�*��H��%�R%�aX�?g)���b�)}�M�6x5�-հV�D��$�$�t3�� C� ��&�G0#đ� |V���x��\L(~B��Fc +�V H�hԝb+q`�J�H��J+l1�g�P2�Q��(�'O����p�p*���`(dEc��Jt"����U�U���X�-�,LW)lgpSH�0�Ϭ � [Z���sh@"@q� (.%R("a��D���1Ue��6S�2T)�S�R(�|��Ը�Z�m�p�U� 9 �S!��R(�N9mʂ�ѡ�d�"l *t� �$����A�O�?�y�laQf��eC��`na`W�2bp'Bp'Bp'Bp'Bp'Bp'Bp'Bp'Bp'Bp'Bp'Bp'Bp'Bp'Bp'Bp'Bp'Bp'Bp'Bp'Bp'Bp'Bp'Bp'Bp'Bp'Bp'Bp'Bp'Bp'Bp'���N�:�X<�l�ܱ��;�i}H`k���\��9e� ��-� �κrsöH�%p��L�pSP�#�e� ������pT�C+|/4��nѢOԈ����1Q����Fӳ��O���`_GD��wL䄨-:GƎ����#r|�� +[���W�ɶ;�����qx7ԢEXTl|Ԥ��Zv�}'2&z��X~�'nJ�H|��}���9���I�Q��D���2�E���?7�+�S�r?ww��[&CU��B�},1����Q�a�P�.����o#��{J��I���ϩ:�� F��?����c*�Gά��XX��?�=zL|eX�U���Ini�^��"�O��5��xz�D��C��w���b-8�ڵ�p!�h9��.G3��f"������ ���y%��%���</�N� �؎J9ȼ��0�2Y���ծ�0��С�'GM�<th�)ѱ��5y\|܄�Cc�F� � ��L�݈���%vD̔�Q4����[�Oݿ��a�Z���!v�� ~Q���Gn�Ʋ�n��9*��/�#`p���f���r&�sF+]4=�gZ�u͙��f0�!��YsI�x&�&J���h1�\S22n|tlt\���L��h�g��2\9D���6��"Ď�J���&�+p)₌"�#���U0�pq�}t���"ehd��`������R�A�!�7����^ +��~`0��e�jζn��* +�%Jͱ+<�H;�T]V\�9^��J���g��͜*ۺ��T] +�<_�lȥJli>��A�b�_�CĀ�/��O��x��ˀv��&I�S9��) +�����D�mI���q��jZ���8O�/��CE��&�+*Ў(Oa�<��E��v�?D����m��_�5�:�4=��O ���������07�����rU ���k��a�/G~F5��Q�%N3sj���ѭ%!�@��t���4Zb��0i�F�N���F�r�j�GƎ�7|lT|�䐱*������i�����?�=Yjېkעg�Ȏ�:�o�^n�tn*u�dr�~�4���zԛ-�*�������rtw�U��&�&v�j�4al�dqd����!}F�7�X?�Mx�vcߖ5i�1|�x�5��+�C� h�4�ܲɸNC'���u8�Y�6|��&��U��k0*����aB���tx<'�6�.�ުs��\�7�s�Z�o%���:6��5�-?2��<���&���ŪߤU���ǘ�_ֲc���hKS;�ۦW���mzv��e~��N-bNl�kD�\���6嚷i��o����خUdhh�:����S�wVX�h�U��Gt��0�_7�}L��]kעcH|Ƕ�bL���dKx�a�jo[M�#�aǺ�Nj�%�ݤ�b�NC��@���4� q�4K��u +��Z��_B=����'kq�<|���Zj1"�{HW!��.ۏk_�w�1Q_ԓ�v��FLssD��0||�������7 ��SgR�z���c��6�&D��3+�� U��ٹcx�P����_�ԣ��1�[o�|K"@��9��٠���C���6�[h�1�p�����6���z���7�G��\�*�F�톷�a�q�4~����C����)� �nҔ&�:���l_��|��;q��� oS�I�a�>ոw\��1 ����)�S�6ix��跇��ihá�J�����n�{�4�o��n����44bx�c�76jl�6Ђ�MH"z{�u��nr�:.j\XGNվ��Vk�� ��04���[c&��i�V��v i0���tnٞS�j%��0�5��g��6������� u�Q�fMGI�J���hh˔V��~�#=��=�zc�������f��m��)s4�J\M�~k�˕o�RL+�T������E��堜���T�i咃���4S�h�E*2�J�A1�yrP�s�ԬT�Tx4/&Uɴ2���̍R�"P�r�b���T9����˝�jt��7����J0�"rP=sc��P�uիD*˴r�A5�M���V��ze�J��|9��/��j�U��T�ʔ��27u�~Z���/&U̴@r�R禂)Ū��u�+,�17~���gu�A�FS�)���A�͍��BW��45�R-�T�ܘrP�F��堂�������%� �A��iU*/2�N��!/qn�dɱRL�*9xa���ҷ_9x��Y�rP��T�T�i5���+5���&�M�� +�V�K�9�9#]rP�Ѽ�T�jz�ې��ӪX^`4/"Uʴ�^��f�yk��GSurܢX ��(�(V��(���(ֈ�K�[_���(�(���(V���(�(V��(V�jz�;�E1�E�2rܢX�sS�K�咃-����T���؏n��;�^h����R�'mj'F�v�;a�cP�^����H�I��*v���0O�|�N��G֮���]:zVlj��W�tr��>�Rq�&���?���1�k ���~�>`,x�O�Ķ�Ʊ>�q:�꣼��'�4�=��pGGC|�>���a`87����w ��<�>߭<�i��cz� =�L7O ��L�5DUVuN����ӳ69^y�� zl�ƞ4U�S�F�Ł�B3������?�ȱ�:���*/�2=���x����~�<�zx=���8z)=��=B�z�=�rM����DU�� "���'γ���L=�zAeW�S����z��D�d��B;zD$=�DRy��G��g�ɪ�p��k�"���GO���[ӓ���t�*=��c���H +��K�J�� CC�D=.�F��f�mD�l$]TU�zb���_Q�c�y�<�gO���� �=1�N�Tz� jv���gz,���dz��/�(��K%z&�.�lﮍ�6j��Fd�_�"�4��k�J۰ma�t�#�n������1�-�ΑT1I��و��N6~���{��ɐvz����v +bh#�'�6"��L��Qd�N�tغ�K�h(����|)�A��a�/ y�B��xN��h������F�O�mD��Fd��[om��\y����g�x�֎�=��a��&�DԴ�w? ��;%z���ѣ���ׇ�3%>@�����\=NfG��W���7i|d̋y�/�o������<=;����������`����drŀ�F�b���. �@ˀP�|D��7�� �k��R����q +���u�.X�[���U$z�����w�0���o��|�, ��o��@�0M����g�m��ˈ�m<��aX鱙�b!� �'������r���g�FO�v{��G�E�ֻz*4G���P��4?�鯢�xN4e��ˑ9�mʠ~2�_0ƇL��i�n�L�|�����:�˦c'������)$y}���,\/F� +=��JFώ4��v�T�"�l+�@�s�v�GO��-=� Y)TEP��.��=��I�Z) .�\sf%9�d�Q4�+IO���4[e�Dm��eH�Ql��ӂ68h��68h�_� � Cc�b�z��ЃJUE�xMt�r=@e��Y�U�ev ���σK�gVz��wz~��� ���g�*�\�D���~��n�f��� �g~)�X`�(��H�D~�,U�HcQ���r�k�߱6|�ip��n��j*�\��M�Vm��Z���Nε�ͳ��u�!���p� [���^���%��D��ED���Rˁ���4���3��-��h嘭7,�+µk����j�j�N�>��;��]ks�EE�uJ0)�l��+�����&s�(3A���霮�y�;YWD8���x�.)Ҏ�Ac��j��Q��9D�a�ezZ��_������p(��Ԯ5�K�g�,�R�����v~�y]����'W=_�[�+�+��ܸ����z�'���fo���w��{`t��x���E|U��-k������B'�e�0�W_����`�!^n�����j� +���q%�t)��6cP~_�睭����^��=�F��M{ko�2_��Dѧ���{t�Z�f���Y��.����r�*�e�z��� ��X}������^>�����|��G8+2:� +T�O��O��@.���Txtv���j���s��N�#�ei_��Y��{��Zm���L�_2���[����U,!��? �W �3�Zٓ� �Z_L�ye���X���1k^գ�1p�������wt���U4���Y��=��1����?��}�Q��F���?Hڅ�*�ܰ�7:��.�F��qtV�4Fa�p��F�c�q���b�}���*V��vT��ߌ�ϗ�:��l����{1������?�@i}�wt���KW�?$���2Ӿ�<���3�@bi�j{WNO��S\���bi�pV���^���v/:uí +��.�F���.s��rf~�v��B�0(��;����FgK��!�U�~�gW��W<���F��*�<ܸ�eQ��~��dYC4:���H8�4k4w��2ƅᗥnf���s;�W �4 +�����i��+�~X�~bo��z�Y�0!���ԍ�ʛ��`�ה��;Ď�U�ڵu�m�E�^��h��x�K�")�"˪h�y)睤�-@���Sc��ká�j"�� ��,� +�n*蜢����"�o��t��*�'^T��uU�EU����Cv��k��q����ʊ�l۳�I�����})�})�})�����]*^G�{����n��dQR8����Y�8p�k�d\�t]`7 (�J[=l΅hV��h���{�\�̎�뒦ʪ�8d)D��d��u�c�����]Щ�hg#�`Dt��D�IVd;���5f�x���]�8:�B�� ��S�˒"��� �(���]��ӨZXl0˷Y�*McP��:l��Q��k�����K��Iv"j^�$����"P�*����F[>��C�=�0�"��J�q��ꍍH��8��$Y7n���(0�' +UE'���.�M��/@�A�K> W��ҭ +�J"���K�e `��!=D��^>�Se��~�G��|���N!C��M�yL����Dݾ��$�B~���<�u����K¤˚)|������͗�U����@,D�G�O%�tG�!`��f����.�!2&S!����9�4�ل8qqY�4<W����(8�:�O�*7n����ҝm:��*6:�K�y�����Su�n��+tU1p�l�s�`�7���Q_菄��W8���-%z�s�I��H,4I02DC�K@r��2Gbώ1��J�3c�t�šBH�w=A��)��3AϕCp�T���;��0f%���މ�S��S1g2�L+H~!�R���8M�t��L�p��j� IV�D���{:�G�eB�S�?�V�Lb������؈��tϯ��Ȣ��_`1�d +�8löQPo�@̿ + !A�D�HS����#;�BV6Cb�j����(��M�؈htX� �L+����s���=r�X���{GE�넠Ur��KA��B�(�(8�V +ѲE0":�R.�t��.p(��3�T�F�������o��OwD�:�C����������/� &N�t��i� fY�)D%�y�� ]��ڗ�z����࣪ۉ��`P�a�O[@|��H"�F��S94�A�D��&I���"�C��N��@&DwolD��2)�$;���CdQ�ܢ˘L��mؾ~�Ɨȟ�ؚ�M%(�#�H6�W�R��ɗ�YNïؐ�%����)~ņ������%�.5��-�� +v��Q�rÚ���K��v�OMVt�KO�����<o'� s�\�\��A�Ę5���Ҡ�p +���o"�s �H�S�\��1HȀ���O4��>dU0�\�o���+���� ?�Fa� >�;�V���(����9���O[ +� +�ZI�U�O�Px��7��@� >y���؈0P_L�DgX����{R$�\��Ȭ���! +td���K�����D0�d����ףrt���d��5��T��t\br����"ܗ�2{��.����za'�z +Q������ᅀx��qjV4J���Y\�Ms�IPv��=�+*��Lwt�dQȦ�h:�F�*;bD�E`4 �<M�<�� +�i�� +D%���˚�a�@����"u&�@l�N]c��_�oTk�0a�N'� �2j1� ,�*T�ݤ�A�$(�}�c͓t0:8A�c��%H��A?�1 +N���1�u�+#�4�q �����a�0E�"r�j�7�f<�j�hj$Q�Dg`c�~`"Df�p���������(&��ƣ�)�X>B����D�qYOD$�*�iKg��4'�]> =`��_ +:W��T`$Wo|� `���1���z" 1�Nk:��'� +�[��a ��HD`EE(��n�?̊��r[IU����I30x��xB�k�:�S)��H +��B,t]�T��#"�M4���J�G� 0<�U88��:�@��� +�B����x�ÛB��ٜO�D�3�Q�A`JfohɖU +La�������7�D��Z����F���2O�a��r�z_3x�ۉ"��3NL�-�rÐl��<�\��� #��L�&��!�����KP�z'����J��@�L�K+) +�<�H(�8�R�T��6����1�"B���Ɖ��#��Bs��U����8��H�����Y8� i��(x��P}�A6�1�F7�!���Ԑi~������:�O4�:��p�i,��C?�!��W�����C%�B9�-*��`�[ +n[�Q8O�f _�Y��2�n�C�S�Z�A�p!$�Q"�|J�ý�t(4B���hlqU��OEY�ɜ:|\���:"3Nj��@�t�/L����獭��B������рS�,�3}a]E["Yv:(��B�1��O����b��``Γ�'_��O4x�)��a�0b�C�&q2*�h0?��f��EI��qG�����Y������*w�=�����o��Tn��B�,���������rvp9����+uւ��pTUZoUh���*�L��u^h-�4Ǜ8E����*S������ +�O)x�B�K�K�K�K�����¢ۙ�g=>x����l����M�V%p�o���: �I ��DGRb�Ą��Z�Ǻ��z�����i'=x���x�4;������(`x��;�ϧ�8r|���Қĺ��3'��[_t����n�z�τ>I[?;ttͅ�����-����Kii�Շ�?����@��-��%�x��he���I���ݷ��/5>���ǎ�8sf���_=���� ��ټ�K�f�����{&����� �G��7���w�ܭ��8KKs��߸;~�?-7oi��dr������n��b[��C]��������۹����fe啔�����¢����r������ι�������'�Fn�G�� ���$&�7�ڲk�� .q:k�5Sn?�N�xuP�6�O\Ї��7vܵ��������O��y���gξ���f�6Lh����7��p�����S����p�ʈ����n���u�[��6�HڊkWOefB�������,�p~����&$N����2��O��`˘�{������b{ +$���Ǐ + +�A������ܤ۷�ؿ��,!q����/�(��vk�@�����}�iRr]��7ؘ�a��o/]���_�r��}ZT���=���\R��{^z�����%��������x-�� +�ݹm���Wr�k�o�5�[�ݻlH[�q��[�E5ۥ�*��%�o��Ʉ�ƛ7FN�u��K��@ݸ��t��3b�f}æyGO�{�Sӝ�ly��������!O"�e������+Z���w=��vǶ������w'���gi��{��t$��|D����O_[R\q����4�qi�M�Ë�;'J��+9�\||u��GW�XSr1�y3�y�3�riֽ�g/4��w�ٲ1t��3�K�{>�?�7�mL1���u���:|��O"�\<y㙍+�kQʊ�sa���ɢ�I���-H���[�܅-rf�ϝ�*��|%��W�~^��'�e|T/���Of�ً:���vᶩEG��\��|zǧr���QX�Cz��mkה������+{�ovڴ�L���?�)����Ύ�>����ݻ�C�g�3�J�e����K�ܐ�������C���n�ַ����� +��o{|p+|u3^�\�)�������:RZ\��6�>0��o�}[I��i��͗��Wά��Φ�'%��v]�������t� ��=���o?Zs���R�������%���5��;�����_���9R��8�P�v�:v�پ��v�R�D����~�筭������N�A|u��9�U��o��%*u��|6�lb�s罻�w�h�yKN���)(.��;s��p�_`���q]f�����?�:����Egֽ�3r���3���-�x���q��'�h�wxg�0�������qѸn���w�Χ�j};�Y��o�N@[hЧ�>�M]*-���a���|p�X��s��Ϟ��K6�cmĔ%cz�1X�zu�0tQ�/��߸_pzs���9�����{�y�����_����b�����n&[�߆]�^d�o��flq��gn�/����>���Eg���3<�W��'Ò���[��㥣{���y�)�:p��٣��k$��6<�� +�~:������uΏ���G�����7����tXf���V��m#vw�tz��tAXច�y�'�Y��(`�����[V]����Cw�KM5�*Z�����7�X%N�6c�ї�Z����0�;t_� ��g5������uo�'���w�>^�7og��� �Ѝu��$m������ǐ��}L�7����[��[ۈ���o��+���:���Sy3����m5eKʵ�5��2����U�?F���q؛��O��{=>_=⍇�~#�����p�eS��������nϰ�Yl��&sJ���,|��Qڱ�e+����������e1�&�{.���a]�E*����R�x���c�o����G�\~�x�;Kg�8e�����h\7ol�:��m>������n�7���@H��M��o��m�� +>gzݼ��Yw�٬�O�>�I�̌#'����`��m��<��ڔy7����v;ҿ���m��2�N{�f�8��c�E���#�]�R'ѝ�MLh7��ѽ��t����E?X�ˬ �n]1o��gO\1uЗ�LJ]-��lC�X�n��S��2mՈ!S�C�����ޜ��M��B�YT�{������ތ���V��&�@��>oU�����9��rs;�����/¦�.��A�{�˦ �k��[�o_}�#����w�����iS�����O�?���0k������O�F��#�?[w�����|���7�}�EYٗY���[n�����DX��K����=?v|Z��c�3����x\���HAgf?i��`{���ɉ_�p�����(����,��ߣ=ƻ�S��Ϻw�̹#W7�����?�O��p�դ1}�w�j���8.��;�)�@|��i\��>8�������j�����W��{�v�'Kx�\�@��O?zbZڱ�jX5+9� �~�'�l�|�K�6?�}��OS{w�H��3���?���R2N����1���O�{�����3m�� ��>���~>��_�u��%%O�_:��4/淶_����s�۟u*8�ݯ)7�<u�aפ-)Wk����O=zܳx��8��)���3?���S��Ji�}��1���/)(�����`�H�X�4�9�fWb���?O�5χ�z~�뻓�f?ͳ⿏�c^���Y�0��g�R��d����Y��gp��=���!�7���\XT��?�c��)�?x�u�Q�MNgz&f���O�?�_J��GNȾ|͛�Y|b x�;�NA��ҜG���[�������}o�0�ei�,}������� +&����?�r[�ކ�o�Ea��=Է]�o�8���=|�ۯ +�^�P��;���,����������IYt����Q��iq"2�4����Wʝ���V/����F�d��~��������;Ō���V����/���Qr��<�):cH~���w3��ɷ�<M�����ϙ��?����i�/{���[�,��(c��������][�ݶ�=������Ro�L��%������)-�]�u:�Of�}n�{�}��}��#L�mOvfn��]Z��8zbߛc���%���wg�.W�t(~��4{�^���li=��w��z��1�R=lONh�y�{�| ������i/u�|���9��$��됒k��+�Y�W�o����{�'������rh�>Vl@���[����:��pwz�L E�����I��|Sk֓�����OK;���O��� +|��]g23}��9�ɻ�zy�����]���p�G,3�J��H���uNLz�<~�t˪�3����2���W��o{�r�����g{<Wn3���)�81�{Nچg2?�L���s�_x�YY������nJ���y���;�>J�3u���e�;mh��ϝی8?�N���&%�+�n��`뻃����/�,۾�Pf��m$�)xz!��C� �b��wu�r���3�<�UA �Z�k�KO����*Q +�K>>v� ��)ǎfy-ܔd=�������,�/ +Qq�g���~���.�.���f�H�8g��ݼ����,�|��K�Z�.pk�/�ћ�ޟ��{�{��i���5t��x��Iݟ�xR?!�\�00g��3>X��g噉C�y��k�ŧ��)'9�NQ�"���s�f�UTX�s]ڧ�?��Z�s����u����������0={���d2[�3��T�];�X�aI������h�؈������Z9�,S���-�H��mH��W�RR��M�ˋ��{�fϝYwVG��jɵ�g�̱7�ot�8/���ۜ��Xh.���N����I�N�,. +�ee���Q����0�uw��srd��[�`�lf2Z�3�����KP�������lP�$����EW<��!�R��x8ŧ����r�2+���y�l�j~��%\�x�O9�و�aolĜ/�,�;�HI�oƬ���mG��⽌峤��#�Q�b���+�mFC�Λ�}ouoOxZX�p�5.��v�mڰ�r�3��&}�d��Ӎ��;���5ʵaf�kE��1�?��Y�}��ϑ�'B�;���1�N����.X9��;O�,��S������Z�tM�{�~{h�����cA��!��m�>ō�ջb��4˝�4o�I09og������%L�K)��M���ucSA�B��B�_~Z�������o91#�W���G��s�y���VRr��)m-Ic�������>����n������Dc~#�l�tͷ7UZ/]�"��=h�1yq�'�QxaW��[?�v�����xϡ}��-��||�NVƕgr��g�]p;�L[��k�����E�?�~�8ۧ�˿�A��ci�B�[�=} +��� +v/�77��U�r y{��s����)�ӎ����nr��sg���.͙٠ y������ά�ÜI� +�n]�����^f���L����kޏ_$\�x�:S���ޡ�O���/���Y� +N�D!� �:�I�F�czΝy�T ��|A��{R�ͫk +>>y�Hڔ�n� +��_9�O�6�Aޯl�À�uw��ҽ�-��c-�����^�2�g�0��O�/ٳ�xNV��[@���|�FOν�ڐY�,�n�zf\�6��E�`V����O�뮟���:��4^�OJ�9����ܝO��3��]���Lg��R�ϝӄ�����ܯ��v;u�R��S���[���� �9�u��r���W��eeSǒ=����ʿJ�yWg�m�%�[���k��w�e�����W�̬��02�-��+{0`ߞ��,������#(8�Ǖ\�c����QĪ�M��]�i����`�s �_�{73�g89֝'�#�̛�������6ؚ=�;t���͟�\ޕ;_ȝ۬��J�ZL����pި�ô_�=����+���O���mi��Pr�h�g�+�>���=.H�x�u�P���F�Ey�8V��g=�I�e����?������nݏo�6����hz��,��E����jH��o� +�\8s����zM珖{p1��%��=��[� �mHZ�&<f��_�0��}��s����n|/ǽ=���۔���{�?�p�N�ˈ���q]f��🖺���5�;:��n���O��Jt�p��n���_wO�ɶr1���GLYr����jy����6�o��٩���Ť�_�� ��y��>2�&�W�W�J����r�<���g���r8K��yB]�3t�5��W��6���Ⱥt��a���yK:�R��X+x�g�.>�'���=&������f�� ��9���?�w-��#� +)�{�=�W�Hn�|+{F�_��C\R}>ғg���ˍmz�كmCc��x`4 /:�쑛��s�y��� �}��u��s�;�V��T��y��;�6$|����f7�_��p�7ȼ�ᕂuc����E�_ +���>�>sW\Tr�@��C�w����)8oft�8m�҄����?���v����s��1˼����o�u�9��k��4��ǎ_���8p1�&�.̡\��qe�Ӈ���/��N���[�!�_txwS����oi���S N���㽩Og6rKΫ[&ra��/���3�{LZ�r��t�<e��k�ߦ���[�7� `�u#]`�'�@l)�ʳ�eʘA�K�KR������ǂᆅ]�� �����v�u�q߽�d�k�|õ;ڶ#����q�� +��T��z�%���7�$4ؘ����h��t+�7����������,�y�[�<�{��>�o�b(�ȼďz�hj}-�}��Ƿ����$��������j��{�l��{�R��?^���Uȭ�d���K:Ֆzk�>����W��-�ޣ���Ʈ��6�?���!ϱݾJ���~�}�+q3L���5+���Ӫ͟��4��xkAӤ��_:��OZ̔s�+p��tY v����2�����3{��1ng�-tX|�/N�4��'M�w&�x����_�]����N>����K<|��!X����y'�*9�>{q�K�?O�g5p>�s��s��'e������f�#i�_>>��W����v�v�����$d}��4��ş���|�+�3�k�:���f���U�%�����',W�AWN�2_է�|h��3%y��,IiK�5)l���>6p㻡c�|�J�2�՝?8�2V�o�tͽ� +�v�hy7��y���ciه�?&��{~����U� h3����d�>������/ J��kFO&�m���O���zWw�lK��z�l弑��m�giG��q�ْ�g�ӕ��-{ \5�ڬfn����b^�_���^�*�ޟk��yo��C�wtp#aӵw��^�0�_���K�˓�c�W�ǵ��W���7��� UU�}�?iM[оA⚙?E?�Q/��m[V�ռ��Jn���|�ޔ��$�����ۺg���%ν?����F�r����C>���5\u���?����ջ��~^�kq�<O2�DK��}V�����>O��q{��qMĬ���� +�E��89~=L���������_�ni)�����e@��|�� �O�wb�t��[�nk����ܨ�MŹE���D_����B��,پ����m��ּe��7�O�?,�����>�re�_�f��]f_�Q���pˇ�_ճx��3g�S���.%��xI�8���Ǜ�T�Fz'�lp�p|� ��z��v�df,=�c���f�g����c~�l���ﷅ�OSi� A͙�Jr���~Ν��\W�2���3ꍸn3�FO�\D����m�^���/����I��$�W���L@Ԋϯ�jj��XëW���4Wl��<�om�f��]=�|t�H��y5�����)����Y��{\�AQ߮H�^�j��Y9M�s����l�i l�%������l�t�k�jF����p;b�!����{��>`�O�8=c^���yߵt/��b��é�O�?�\���t��;O_� ��O� �=���.����+���W��u>L�n<�u�!0>8����M��u ݃�?�������1�̬����ܞd�l�2kT���S�^�ixۯ�,#{���gd�\1����w�!i3�$Ǘ�> +�F����ːs�+�7o�y�֞B{�~7&gY�ܙ�Y��6�&v{��Ԁ<���C��&5�el�6 +��A��ڳͷlj�=����~9O��%��;^�$�kn��KJ��5Z�`�oq��\�}���ow��'sCi)��%`y�]5u�sq�d��쁱���Tc��^�>|=h�1y���9,|~RX�t�֠�}ܖM~@))�۟�}�1��21�i��_�37�:6>�n�.�Y�ү��<`[ۈ��a��X�&��p>�����s=���Y1��fӱ��� +L�k `s���k2W_�6tjÍ<E�����Ȝ^���Wi�ŧ֕:� ep�o�k��sN|���vt�ʃ�Z�+KL��k��S j��^�|�l��=���|O�z e����^�?Wl�W����jNΏ�����ޜ���n��%#�|������kA�N`�yV���䛉���6��05��9_�}�/=����G�ս}ʟ&���[��7{�jω�,�F�����Oټq嵫ϼ�`~.,)9��NdʚIk��Ϥ�� F/���\-˽!�Ňy|�?sKsڑį���&�>f�3�b���㲦����s�͉�+��>j�چ��L���8� T��e������?u�����.Պ���@v�B�{��؟>H�y���k�x����6��zQ�{3�i� +p�=YZR�S�Wʑ=(�}��¸����N{���~U�`}�3�Y��Ĺja�'3C��=�cΊ]�5���ܼ�C��$����C�1�������3G/��Q>�n���>[w�-���+y?v,:���H�, �0e�� �v�x+kZ]���/��n�ܙ��ZU֓�%S��@�+zzc��;O���rʪs�l/���lWO��<����b�Ϟ�2{���W���X�ם�t#�ܦ�+>���A)�->��`]�OZ�Zsޢ���V��g�t�ƥ{_��fw����v����,���n�8����W�;=w���y���/�9b�4~�k�,����z���7ӛ�^�[Z��쒛iΧw�]Eyt����np+),-�E�Χ�Kn,�5;oq;�+��/�fZV��FtO��Kֳ]P�,=��a^���H����Y��X�K?��o��8sxjj�]ñ4����Q��<Y9d��Qak�����j�vٜ�F|�}0f��[ҡ !�p猢����,GP��}�iEA�YL���h��_#ۿ�X����y?�lw�������J��ڍ�� �N�tz��_���|p>{�'{~��� ��Y窟����-~��WM}!�y�f����+�xan���s�}o4�œ7��0��u������k���S�Y�J�sO��7o�v��{I��3��o��|�/?֯�'|�%�����o�?��%��yj�t�X �u�7.�_���4���ܥg?L]ȰF�?{sj�����M;��=* ��-�����_X�֤U_�=yf�����v�:��a�If�2�ź�N���_9���F���g��vZn91�Lx�e�>g��j����ZfVԾԷ��K��*��m���̛OҖ���M�u&�6����?#W~�������7�x��K;�n���p�{yn��g���`Y�:��;���۠��{�0*u���3�?���!�ɼu��{���?}�mn��j�����#f�b�"ϗ�>��������o!/���)����\��GkL�7_c#f��hJ�ޝ�_^*��ˁ���80%�pNqq������9G��=�6m��6���_?��˔C�Z=����Y��g4���Iz�t6nГ�mμ��yԓ�O���j��J������]{W��stƿ���8�������W�%X���MJ�}kp�f�7z�`��n��l���=k��-Z�w��Off]��!{?2�n<�����$��n0��z�-n�۟�ӯV1w��@��z��;ާl=+G���̿���������o'� �\9��%s�v�g�7JqqɅ�����< +��F����$-�����R��Η�{�(n���{=�X����o�"��Jv���.�ݱ=�j#��oHҷm����q��@����7�r�.���O9���e�#��9gH��.����_��5��'xڷo����%��Y�9�k��G32 +KJ!��Xn����˃�wڵӅ�~�w�.�a��2 ��-*{��g�Nοp����>sv���h1oE�V�_����g��Ci�����+�EO� ݚ���N�/��<��_�~i�~�jcR`E�l>��5��zݤ��'Og�7;�//�Ngʍ[�:w�Ѕ'�~%�,��)K���M�us��#���~��wk���!�o��KW���O�+�\}�t�������v�RNŷ�����C���>%�l��m+��v�RF�I=]m�����KW&��e[��r�Jl�nC��(���kn\�@*,,ޓ�l{����q�bL�rݾ���W���_��`Ğ}�_���U�X�} +Ti�����9��rQ� �~P��������/��~�fj�d�,<~:���~�w�<t�ĝ%�p�}��y�gҮ$,�5��գF-�1�e�ʺ��������.8~�W9���<�/Xz�<�Gߴy�����I���IV~a^AQQQ�yԡQLl�u8�Ey����{a��m_�Y��o�z���EG���;v���n$�u��������2z�������.!���ֵ�ym��[o=�aߙG�O�v����'�#�<w����v'M�u��3�����m��o\���t�g���v�$&4Y���칽���C��+��8/�d��g/pk�������������_����������~�uB�}WH#�D����7��mω?�}�L�����-=s���G�s��mϿ��R�1�,,�}���#����k����6Y�&�����?��W��ꂕ����.-�=>eOܶ=�H]|��k���S�\�����ĭ̬�w�^���ҵ��&^��w|�}���'Y���G�K�K�K�K�K�TU�_�C������ڵu�]�~hy��5�v��4�y������q����w��k\�$�����q +����}�"c �_:�G�Iѣ�cq��Ș�F���Ö�V���h��1h`�Z���K��ӽ����&5k��{E���7)2:��;zr�;Q���ظ���� ��1zR����IQ��c�ޥ+�#�~ώ�k����:� +endstream endobj 5 0 obj <</Intent 15 0 R/Name(Layer 1)/Type/OCG/Usage 16 0 R>> endobj 22 0 obj <</Intent 30 0 R/Name(Layer 1)/Type/OCG/Usage 31 0 R>> endobj 37 0 obj <</Intent 53 0 R/Name(Layer 1)/Type/OCG/Usage 54 0 R>> endobj 60 0 obj <</Intent 67 0 R/Name(Layer 1)/Type/OCG/Usage 68 0 R>> endobj 74 0 obj <</Intent 82 0 R/Name(Layer 1)/Type/OCG/Usage 83 0 R>> endobj 89 0 obj <</Intent 100 0 R/Name(Layer 1)/Type/OCG/Usage 101 0 R>> endobj 107 0 obj <</Intent 118 0 R/Name(Layer 1)/Type/OCG/Usage 119 0 R>> endobj 125 0 obj <</Intent 134 0 R/Name(Layer 1)/Type/OCG/Usage 135 0 R>> endobj 141 0 obj <</Intent 150 0 R/Name(Layer 1)/Type/OCG/Usage 151 0 R>> endobj 157 0 obj <</Intent 166 0 R/Name(Layer 1)/Type/OCG/Usage 167 0 R>> endobj 173 0 obj <</Intent 182 0 R/Name(Layer 1)/Type/OCG/Usage 183 0 R>> endobj 182 0 obj [/View/Design] endobj 183 0 obj <</CreatorInfo<</Creator(Adobe Illustrator 19.2)/Subtype/Artwork>>>> endobj 166 0 obj [/View/Design] endobj 167 0 obj <</CreatorInfo<</Creator(Adobe Illustrator 19.2)/Subtype/Artwork>>>> endobj 150 0 obj [/View/Design] endobj 151 0 obj <</CreatorInfo<</Creator(Adobe Illustrator 19.2)/Subtype/Artwork>>>> endobj 134 0 obj [/View/Design] endobj 135 0 obj <</CreatorInfo<</Creator(Adobe Illustrator 19.2)/Subtype/Artwork>>>> endobj 118 0 obj [/View/Design] endobj 119 0 obj <</CreatorInfo<</Creator(Adobe Illustrator 19.2)/Subtype/Artwork>>>> endobj 100 0 obj [/View/Design] endobj 101 0 obj <</CreatorInfo<</Creator(Adobe Illustrator 19.2)/Subtype/Artwork>>>> endobj 82 0 obj [/View/Design] endobj 83 0 obj <</CreatorInfo<</Creator(Adobe Illustrator 19.2)/Subtype/Artwork>>>> endobj 67 0 obj [/View/Design] endobj 68 0 obj <</CreatorInfo<</Creator(Adobe Illustrator 19.2)/Subtype/Artwork>>>> endobj 53 0 obj [/View/Design] endobj 54 0 obj <</CreatorInfo<</Creator(Adobe Illustrator 19.2)/Subtype/Artwork>>>> endobj 30 0 obj [/View/Design] endobj 31 0 obj <</CreatorInfo<</Creator(Adobe Illustrator 19.2)/Subtype/Artwork>>>> endobj 15 0 obj [/View/Design] endobj 16 0 obj <</CreatorInfo<</Creator(Adobe Illustrator 19.2)/Subtype/Artwork>>>> endobj 190 0 obj [189 0 R] endobj 205 0 obj <</CreationDate(D:20161006171817-03'00')/Creator(Adobe Illustrator CC 2015 \(Windows\))/ModDate(D:20161013192722-03'00')>> endobj xref +0 206 +0000000004 65535 f +0000000016 00000 n +0000000312 00000 n +0000027806 00000 n +0000000006 00000 f +0000133736 00000 n +0000000008 00000 f +0000027857 00000 n +0000000009 00000 f +0000000010 00000 f +0000000011 00000 f +0000000012 00000 f +0000000013 00000 f +0000000014 00000 f +0000000017 00000 f +0000135705 00000 n +0000135736 00000 n +0000000018 00000 f +0000000019 00000 f +0000000020 00000 f +0000000021 00000 f +0000000023 00000 f +0000133806 00000 n +0000000024 00000 f +0000000025 00000 f +0000000026 00000 f +0000000027 00000 f +0000000028 00000 f +0000000029 00000 f +0000000032 00000 f +0000135589 00000 n +0000135620 00000 n +0000000033 00000 f +0000000034 00000 f +0000000035 00000 f +0000000036 00000 f +0000000038 00000 f +0000133877 00000 n +0000000039 00000 f +0000000041 00000 f +0000029564 00000 n +0000000042 00000 f +0000000043 00000 f +0000000044 00000 f +0000000045 00000 f +0000000046 00000 f +0000000047 00000 f +0000000048 00000 f +0000000049 00000 f +0000000050 00000 f +0000000051 00000 f +0000000052 00000 f +0000000055 00000 f +0000135473 00000 n +0000135504 00000 n +0000000056 00000 f +0000000057 00000 f +0000000058 00000 f +0000000059 00000 f +0000000061 00000 f +0000133948 00000 n +0000000062 00000 f +0000000063 00000 f +0000000064 00000 f +0000000065 00000 f +0000000066 00000 f +0000000069 00000 f +0000135357 00000 n +0000135388 00000 n +0000000070 00000 f +0000000071 00000 f +0000000072 00000 f +0000000073 00000 f +0000000075 00000 f +0000134019 00000 n +0000000076 00000 f +0000000077 00000 f +0000000078 00000 f +0000000079 00000 f +0000000080 00000 f +0000000081 00000 f +0000000084 00000 f +0000135241 00000 n +0000135272 00000 n +0000000085 00000 f +0000000086 00000 f +0000000087 00000 f +0000000088 00000 f +0000000090 00000 f +0000134090 00000 n +0000000091 00000 f +0000000092 00000 f +0000000093 00000 f +0000000094 00000 f +0000000095 00000 f +0000000096 00000 f +0000000097 00000 f +0000000098 00000 f +0000000099 00000 f +0000000102 00000 f +0000135123 00000 n +0000135155 00000 n +0000000103 00000 f +0000000104 00000 f +0000000105 00000 f +0000000106 00000 f +0000000108 00000 f +0000134163 00000 n +0000000109 00000 f +0000000110 00000 f +0000000111 00000 f +0000000112 00000 f +0000000113 00000 f +0000000114 00000 f +0000000115 00000 f +0000000116 00000 f +0000000117 00000 f +0000000120 00000 f +0000135005 00000 n +0000135037 00000 n +0000000121 00000 f +0000000122 00000 f +0000000123 00000 f +0000000124 00000 f +0000000126 00000 f +0000134237 00000 n +0000000127 00000 f +0000000128 00000 f +0000000129 00000 f +0000000130 00000 f +0000000131 00000 f +0000000132 00000 f +0000000133 00000 f +0000000136 00000 f +0000134887 00000 n +0000134919 00000 n +0000000137 00000 f +0000000138 00000 f +0000000139 00000 f +0000000140 00000 f +0000000142 00000 f +0000134311 00000 n +0000000143 00000 f +0000000144 00000 f +0000000145 00000 f +0000000146 00000 f +0000000147 00000 f +0000000148 00000 f +0000000149 00000 f +0000000152 00000 f +0000134769 00000 n +0000134801 00000 n +0000000153 00000 f +0000000154 00000 f +0000000155 00000 f +0000000156 00000 f +0000000158 00000 f +0000134385 00000 n +0000000159 00000 f +0000000160 00000 f +0000000161 00000 f +0000000162 00000 f +0000000163 00000 f +0000000164 00000 f +0000000165 00000 f +0000000168 00000 f +0000134651 00000 n +0000134683 00000 n +0000000169 00000 f +0000000170 00000 f +0000000171 00000 f +0000000172 00000 f +0000000000 00000 f +0000134459 00000 n +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000134533 00000 n +0000134565 00000 n +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000071719 00000 n +0000135821 00000 n +0000028249 00000 n +0000072025 00000 n +0000071911 00000 n +0000030389 00000 n +0000061241 00000 n +0000029629 00000 n +0000029824 00000 n +0000029874 00000 n +0000071793 00000 n +0000071825 00000 n +0000072101 00000 n +0000072279 00000 n +0000073769 00000 n +0000085924 00000 n +0000135848 00000 n +trailer +<</Size 206/Root 1 0 R/Info 205 0 R/ID[<BF7041612CDA1248B542725B4EEBD5CC><FF417A6C0FF3E24A8349DD3D60C319D6>]>> +startxref +135988 +%%EOF diff --git a/public/img/logo_parceiros/logo_bioe.png b/public/img/logo_parceiros/logo_bioe.png new file mode 100644 index 0000000000000000000000000000000000000000..2b050782ab8ad609b68262c8220ba7ce550f846c Binary files /dev/null and b/public/img/logo_parceiros/logo_bioe.png differ diff --git a/public/img/logo_parceiros/logo_dominiopublico.png b/public/img/logo_parceiros/logo_dominiopublico.png new file mode 100644 index 0000000000000000000000000000000000000000..16c0737187890f5e9da4cdd8556a1b286faa3216 Binary files /dev/null and b/public/img/logo_parceiros/logo_dominiopublico.png differ diff --git a/public/img/logo_parceiros/logo_escoladigital.png b/public/img/logo_parceiros/logo_escoladigital.png new file mode 100644 index 0000000000000000000000000000000000000000..c1ed98e0fc0d8ba0bef95c6727297fe7427db2c9 Binary files /dev/null and b/public/img/logo_parceiros/logo_escoladigital.png differ diff --git a/public/img/logo_parceiros/logo_portaldoprofessor.png b/public/img/logo_parceiros/logo_portaldoprofessor.png new file mode 100644 index 0000000000000000000000000000000000000000..deb2ce6448dc5b36a04d05bd0e6ebd296379263a Binary files /dev/null and b/public/img/logo_parceiros/logo_portaldoprofessor.png differ diff --git a/public/img/logo_parceiros/logo_tvescola.png b/public/img/logo_parceiros/logo_tvescola.png new file mode 100644 index 0000000000000000000000000000000000000000..9067cbc112ec0b710ac2726f15ce59a62921ff60 Binary files /dev/null and b/public/img/logo_parceiros/logo_tvescola.png differ diff --git a/src/App.js b/src/App.js index fc1925780a702a4033886265c4e122a192efdacc..80523ca988f9386b244f9a4704aab7bb2cc40257 100644 --- a/src/App.js +++ b/src/App.js @@ -16,7 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { useContext, useEffect } from 'react'; +import React, { useContext, useEffect, useState } from 'react'; import Home from './Pages/Home'; import Search from './Pages/Search' import Header from './Components/Header' @@ -35,7 +35,7 @@ import TabManageAc from './Pages/TabsHelp/TabManageAc'; import PasswordRecoveryPage from './Pages/PasswordRecoveryPage.js' import PageProfessor from './Pages/PageProfessor.js' import ResourcePage from './Pages/ResourcePage'; -import {BrowserRouter, Switch, Route} from 'react-router-dom'; +import {BrowserRouter, Switch, Route } from 'react-router-dom'; import { Store } from './Store' import TermsPage from './Pages/TermsPage.js' import PublicationPermissionsPage from './Pages/PublicationPermissionsPage.js' @@ -45,10 +45,20 @@ import EditProfilePage from './Pages/EditProfilePage.js' import PublicUserPage from './Pages/PublicUserPage.js' import UploadPage from './Pages/UploadPage.js' import EditLearningObjectPage from './Pages/EditLearningObjectPage.js' +import SiteMap from './Pages/SiteMap' +import Accessibility from './Pages/Accessibility' +import CollectionPage from './Pages/CollectionPage.js' +import FormationMaterialPage from './Pages/FormationMaterialPage.js'; +import FormationMaterialIframe from './Pages/FormationMaterialIframe.js'; export default function App(){ // eslint-disable-next-line const { state, dispatch } = useContext(Store) + const [ hideFooter, setHideFooter ] = useState(false); + + useEffect(() => { + setHideFooter(String(window.location.href).includes('iframe-colecao')); + }, [ window.location.href ]); useEffect(()=>{ dispatch({ @@ -77,7 +87,7 @@ export default function App(){ },[window.innerWidth,window.innerHeight]) return( - <BrowserRouter> + <BrowserRouter basename="/react"> <Header /> <div style={{backgroundImage: "linear-gradient(to right,#ff7f00,#e81f4f,#673ab7,#00bcd4)", height:"5px"}}></div> <link href="https://fonts.googleapis.com/css?family=Kalam|Pompiere|Roboto&display=swap" rel="stylesheet"/> @@ -95,6 +105,8 @@ export default function App(){ <Route path="/termos" component={UserTerms}/> <Route path="/teste" component={Teste}/> <Route path="/sobre" component={AboutPage}/> + <Route path="/mapa-site" component={SiteMap}/> + <Route path="/acessibilidade" component={Accessibility}/> <Route path="/publicando-recurso" component={TabResoursePub}/> <Route path="/encontrando-recurso" component={TabResourseFind}/> <Route path="/participando-da-rede" component={TabNetPart}/> @@ -106,9 +118,17 @@ export default function App(){ <Route path='/professor' component={PageProfessor}/> <Route path="/upload" component={UploadPage}/> <Route path='/loja' component={ItemStore} /> + <Route path='/colecao-do-usuario/:id' component={CollectionPage} /> + <Route path='/colecao' component={FormationMaterialPage} /> + <Route path='/topico' component={FormationMaterialPage} /> + <Route path='/iframe-colecao' component={FormationMaterialIframe} /> </Switch> - <EcFooter/> - <GNUAGPLfooter/> + { !hideFooter && + <div> + <EcFooter/> + <GNUAGPLfooter/> + </div> + } </BrowserRouter> ) } diff --git a/src/Components/AboutCarousel.css b/src/Components/AboutCarousel.css new file mode 100644 index 0000000000000000000000000000000000000000..92e69e00e308af1fb61fc38c3de4789c8b19dffa --- /dev/null +++ b/src/Components/AboutCarousel.css @@ -0,0 +1,6 @@ +#You-Can-Caroussel > .carousel-root > .carousel-slider > button{ + display:none; +} +.dot{ + border: 1px solid black; +} \ No newline at end of file diff --git a/src/Components/AboutCarousel.js b/src/Components/AboutCarousel.js index 9bbe6db737ecc07c76646e603bcceb42694ec6ec..fc36515228cd3b234058e7e712d5630900be159e 100644 --- a/src/Components/AboutCarousel.js +++ b/src/Components/AboutCarousel.js @@ -17,12 +17,11 @@ You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { Component } from 'react'; -import ReactDOM from 'react-dom'; +import React from 'react'; import "react-responsive-carousel/lib/styles/carousel.min.css"; import { Carousel } from 'react-responsive-carousel'; import styled from 'styled-components'; - +import "./AboutCarousel.css" import Img1 from '../img/carousel/Icone_Grande (1).png' import Img2 from '../img/carousel/Icone_Grande (2).png' @@ -71,7 +70,7 @@ const CarouselAbout = styled(Carousel)` text-align: center; display: block; margin: auto; - padding-inline: 235px + // padding-inline: 235px } } ` @@ -81,50 +80,51 @@ const CarouselAbout = styled(Carousel)` function AboutCarousel(props) { return ( - <CarouselAbout showThumbs= {true} - showStatus= {false} - showIndicators = {false} - interval={8000} - transitionTime={1000} - autoPlay - infiniteLoop - - > - <div> - <img src={Img1} alt="Slide 1"/> - <span>Buscar e Baixar Recursos</span> - <p>São mais de 20 mil recursos educacionais à sua disposição. São recursos de portais parceiros do MEC e de professores que, como você, atuam na Educação Básica!</p> - </div> - <div> - <img src={Img2} alt="Slide 2"/> - <span>Guardar Recursos em Coleções</span> - <p>Guarde e organize em coleções aqueles recursos que você considera ser interessantes para elaborar a sua aula. Aproveite e indique aos colegas pelas redes sociais ou e-mail.</p> - </div> - <div> - <img src={Img3} alt="Slide 3"/> - - <span>Compartilhar suas Experiências</span> - <p>Você pode relatar suas experiências sobre o uso de recursos no seu cotidiano escolar. Aproveite esse espaço para sugerir e conhecer novos usos para um mesmo recurso.</p> - - </div> - <div> - <img src={Img4} alt="Slide 4"/> - - <span>Publicar o seu Recurso</span> - <p>Colabore e ajude a fortalecer a plataforma publicando um recurso educacional desenvolvido por você ou pelo coletivo da escola do qual faz parte. Compartilhe seu conhecimento e dê visibilidade ao seu recurso, torne-o público enriquecendo o conhecimento partilhado!</p> - - - </div> - <div> - <img src={Img5} alt="Slide 5"/> - - <span>Encontrar Materiais de Formação</span> - <p>A plataforma disponibiliza um conjunto de materiais de formação desenvolvidos pelo Ministério da Educação com diversidade de temas e recursos educacionais.</p> - - - </div> - </CarouselAbout> - + <div id={"You-Can-Caroussel"}> + <CarouselAbout showThumbs= {true} + showStatus= {false} + showIndicators = {false} + interval={8000} + transitionTime={1000} + autoPlay + infiniteLoop + + > + <div> + <img src={Img1} alt="Slide 1"/> + <span>Buscar e Baixar Recursos</span> + <p>São mais de 20 mil recursos educacionais à sua disposição. São recursos de portais parceiros do MEC e de professores que, como você, atuam na Educação Básica!</p> + </div> + <div> + <img src={Img2} alt="Slide 2"/> + <span>Guardar Recursos em Coleções</span> + <p>Guarde e organize em coleções aqueles recursos que você considera ser interessantes para elaborar a sua aula. Aproveite e indique aos colegas pelas redes sociais ou e-mail.</p> + </div> + <div> + <img src={Img3} alt="Slide 3"/> + + <span>Compartilhar suas Experiências</span> + <p>Você pode relatar suas experiências sobre o uso de recursos no seu cotidiano escolar. Aproveite esse espaço para sugerir e conhecer novos usos para um mesmo recurso.</p> + + </div> + <div> + <img src={Img4} alt="Slide 4"/> + + <span>Publicar o seu Recurso</span> + <p>Colabore e ajude a fortalecer a plataforma publicando um recurso educacional desenvolvido por você ou pelo coletivo da escola do qual faz parte. Compartilhe seu conhecimento e dê visibilidade ao seu recurso, torne-o público enriquecendo o conhecimento partilhado!</p> + + + </div> + <div> + <img src={Img5} alt="Slide 5"/> + + <span>Encontrar Materiais de Formação</span> + <p>A plataforma disponibiliza um conjunto de materiais de formação desenvolvidos pelo Ministério da Educação com diversidade de temas e recursos educacionais.</p> + + + </div> + </CarouselAbout> + </div> ); } diff --git a/src/Components/AboutCarouselPartner.css b/src/Components/AboutCarouselPartner.css new file mode 100644 index 0000000000000000000000000000000000000000..4ccfbadb16760548c55fdca453e17662174f706a --- /dev/null +++ b/src/Components/AboutCarouselPartner.css @@ -0,0 +1,6 @@ +#Partner-Caroussel > .carousel-root > .carousel-slider > button{ + display:none; +} +.dot{ + border: 1px solid black; +} \ No newline at end of file diff --git a/src/Components/AboutCarouselPartner.js b/src/Components/AboutCarouselPartner.js new file mode 100644 index 0000000000000000000000000000000000000000..eb9c9c2939dedce5bf90673951b2ffe29e6d431d --- /dev/null +++ b/src/Components/AboutCarouselPartner.js @@ -0,0 +1,142 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + + +import React from 'react'; +import "react-responsive-carousel/lib/styles/carousel.min.css"; +import { Carousel } from 'react-responsive-carousel'; +import './AboutCarouselPartner.css' + + +import LogoPortalDoProfessor from "../img/logo_parceiros/logo_portaldoprofessor.png"; +import LogoBioe from "../img/logo_parceiros/logo_bioe.png"; +import LogoDominioPublico from "../img/logo_parceiros/logo_dominiopublico.png"; +import LogoTvEscola from "../img/logo_parceiros/logo_tvescola.png"; +import Safer from "../img/logo_parceiros/safer.png"; +import FundacaoLemann from "../img/logo_parceiros/fundacao-lemann.png"; +import InstitutoCrescer from "../img/logo_parceiros/instituto-crescer.png"; +import RedeEscola from "../img/logo_parceiros/redeescola.png"; +import Educagital from "../img/logo_parceiros/educagital.png"; +import EnefAef from "../img/logo_parceiros/ENEF_AEF.png"; +import Impa from "../img/logo_parceiros/impa.png"; +import Futura from "../img/logo_parceiros/futura.png"; +import Impulsiona from "../img/logo_parceiros/impulsiona.png"; +import InstPeninsula from "../img/logo_parceiros/inst-peninsula.png"; +import Telefonica from "../img/logo_parceiros/telefonica.png"; + +function AboutCarouselPartner(props) { + + + const itens = [ + <a href="http://portaldoprofessor.mec.gov.br/index.html" rel="noreferrer" target="_blank"> + <img src={LogoPortalDoProfessor} alt="LogoPortalDoProfessor"/> + </a>, + <a href="http://objetoseducacionais2.mec.gov.br/" rel="noreferrer" target="_blank"> + <img src={LogoBioe} alt="LogoBioe" /> + </a>, + <a href="http://www.dominiopublico.gov.br/pesquisa/PesquisaObraForm.jsp" rel="noreferrer" target="_blank"> + <img src={LogoDominioPublico} alt="LogoDominioPublico" /> + </a>, + <a href="https://tvescola.org.br/" rel="noreferrer" target="_blank"> + <img src={LogoTvEscola} alt="LogoTvEscola" /> + </a>, + <a href="http://www.fundacaolemann.org.br/" rel="noreferrer" target="_blank"> + <img style={{align: "middle"}} src={FundacaoLemann} alt="FundacaoLemann" /> + </a>, + <a href="http://new.safernet.org.br/" rel="noreferrer" target="_blank"> + <img src={Safer} alt="Safer" /> + </a>, + <a href="http://institutocrescer.org.br/" rel="noreferrer" target="_blank"> + <img src={InstitutoCrescer} alt="InstitutoCrescer" /> + </a>, + <a href="http://escoladigital.org.br/" rel="noreferrer" target="_blank"> + <img src={RedeEscola} alt="RedeEscola" /> + </a>, + <a href="http://educadigital.org.br" rel="noreferrer" target="_blank"> + <img src={Educagital} alt="Educagital" /> + </a>, + <a href="http://www.aefbrasil.org.br" rel="noreferrer" target="_blank"> + <img style={{filter: "grayscale(1)"}} src={EnefAef} alt="EnefAef" /> + </a>, + <a href="https://impa.br/" rel="noreferrer" target="_blank"> + <img src={Impa} alt="Impa" /> + </a>, + <a href="http://futura.org.br/" rel="noreferrer" target="_blank"> + <img src={Futura} alt="Futura" /> + </a>, + <a href="http://impulsiona.org.br/" rel="noreferrer" target="_blank"> + <img src={Impulsiona} alt="Impulsiona" /> + </a>, + <a href="http://www.institutopeninsula.org.br/" rel="noreferrer" target="_blank"> + <img src={InstPeninsula} alt="InstPeninsula" /> + </a>, + <a href="http://fundacaotelefonica.org.br/" rel="noreferrer" target="_blank"> + <img src={Telefonica} alt="Telefonica" /> + </a> + ] + const partnerPerPage = (()=> { + var pageWidth = window.innerWidth + if (pageWidth >= 1200){ + return 3 + } + else{ + return 1 + } + }) + var rows = [] + var partner_per_page = partnerPerPage() + for(let i = 0; i < 15/partner_per_page; i++){ + rows.push(itens.slice(i*partner_per_page, partner_per_page*(i+1))) + } + + return ( + <div id="Partner-Caroussel"> + <Carousel showThumbs= {false} + showStatus= {false} + showIndicators = {true} + interval={4500} + transitionTime={1000} + autoPlay + infiniteLoop + + > + { + rows.map((row, index) => ( + <div key={(index+1)} style={{display:'inline-flex', paddingTop:100}}> + { + row.map((partner, index2) => ( + <div + key={index + (index2*10)} + style={{marginLeft:10, display: 'flex', maxWidth:300}} + > + { + partner + } + </div> + )) + } + </div> + )) + } + </Carousel> + </div> + + ); +} + +export default AboutCarouselPartner; diff --git a/src/Components/AboutResource.js b/src/Components/AboutResource.js deleted file mode 100644 index 87a0949e185d9dbdaa6f1661f4e6af9de358b7dc..0000000000000000000000000000000000000000 --- a/src/Components/AboutResource.js +++ /dev/null @@ -1,264 +0,0 @@ -/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre -Departamento de Informatica - Universidade Federal do Parana - -This file is part of Plataforma Integrada MEC. - -Plataforma Integrada MEC is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -Plataforma Integrada MEC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ - -import React from 'react'; -import axios from 'axios'; -import {apiUrl} from '../env'; -import {Col,Row} from 'react-grid-system'; -import Paper from '@material-ui/core/Paper'; -import Typography from '@material-ui/core/Typography'; -import CardContent from '@material-ui/core/CardContent'; -import Collapse from '@material-ui/core/Collapse'; -import CardMedia from '@material-ui/core/CardMedia'; -import CardActions from '@material-ui/core/CardActions'; -import Coment from './Coment'; -import Rating from '@material-ui/lab/Rating'; -import Tag from './Tags'; -import { Hidden } from '@material-ui/core'; -import Button from '@material-ui/core/Button'; -import IconButton from '@material-ui/core/IconButton'; -import Menu from '@material-ui/core/Menu'; -import ListItemIcon from '@material-ui/core/ListItemIcon'; -import MenuItem from '@material-ui/core/MenuItem'; -import MoreVertIcon from '@material-ui/icons/MoreVert'; -/*imagens e icones*/ -import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; -import ShareIcon from '@material-ui/icons/Share'; -import ReportIcon from '@material-ui/icons/Error'; -import AddIcon from '@material-ui/icons/CreateNewFolder'; -import FavoriteIcon from '@material-ui/icons/Favorite'; -import GetAppIcon from '@material-ui/icons/GetApp'; -import StarBorderIcon from '@material-ui/icons/StarBorder'; -import RateReviewIcon from '@material-ui/icons/RateReview'; -import VisibilityIcon from '@material-ui/icons/Visibility'; -import SdCardIcon from '@material-ui/icons/SdCard'; -import TranslateIcon from '@material-ui/icons/Translate'; -import InsertDriveFileIcon from '@material-ui/icons/InsertDriveFile'; -import DateRangeIcon from '@material-ui/icons/DateRange'; -import UpdateIcon from '@material-ui/icons/Update'; -import AssignmentOutlinedIcon from '@material-ui/icons/AssignmentOutlined'; -import OpenIcon from '@material-ui/icons/CallMade'; -import { TextField, FormControl } from '@material-ui/core'; - -import noAvatar from "../img/default_profile.png"; -import styled from 'styled-components' - - - -const TypographyStyled = styled(Typography)` - padding: 5px; -` - -const CardActionsStyled = styled(CardActions)` - padding:0px 0px 10px 0px; - align-items: center; -` - -const PaperStyled = styled(Paper)` - margin: 2em 0em 2em 0em; - padding: 2em 2em 0em 2em; - @media only screen and (min-width :500px ) { - margin: 2em 10% 2em 10%; - } -` -const elevateStyle = 3; - -const Overlay = styled.div` - display: inline; - background: linear-gradient(transparent,transparent,#fff),transparent; - bottom: 0; - cursor: pointer; - left: 0; - opacity: .8; - filter: alpha(opacity=80); - position: absolute; - right: 0; - top: 0; - height: inherit; - -` -async function getResource(id){ - let res = await axios.get(`${apiUrl}/learning_objects/${id}`); - let data = res.data; - return(data); -} - -export default function AboutResource() { - - var display = getResource(19133); - console.log(display); - const [anchorEl, setAnchorEl] = React.useState(null); - - function handleClick(event) { - setAnchorEl(event.currentTarget); - } - - function handleClose() { - setAnchorEl(null); - } - return ( - <div style={{backgroundColor: "#f4f4f4", padding: "2em 0em 2em 0em"}}> - <PaperStyled elevation={elevateStyle}> - <CardMedia image={noAvatar}/> - <CardContent style={{padding: "0em"}}> - <Typography variant="h5" color="textSecondary" component="h3"> - {display.name} - </Typography> - <CardActionsStyled > - <IconButton style={{padding: "0px"}}aria-label="Favoritar"> - <FavoriteIcon /> - </IconButton> - <Rating - name="customized-empty" - value={2} - precision={0.5} - emptyIcon={<StarBorderIcon fontSize="inherit" />} - /> - <Hidden smDown> - <IconButton aria-label="Relatar"> - <RateReviewIcon/> - </IconButton> - RELATAR - </Hidden> - </CardActionsStyled> - <CardContent style={{padding: "0em"}}> - <TypographyStyled component="p" color="textSecondary"> - Tipo de Recurso: - </TypographyStyled> - <TypographyStyled component="p" color="textSecondary"> - Componentes Curriculares: - </TypographyStyled> - <TypographyStyled component="p" color="textSecondary"> - Outras Temáticas: - </TypographyStyled> - <TypographyStyled component="p" color="textSecondary"> - Etapas de Ensino: - </TypographyStyled> - </CardContent> - <Row > - <Col md={4} sm={12}><VisibilityIcon style={{verticalAlign: "middle"}}/>Visualizações:</Col> - <Col md={5} sm={12}><GetAppIcon style={{verticalAlign: "middle"}}/>Baixados/Acessados:</Col> - </Row> - <CardActions disableSpacing style={{fontSize: "0.7rem", borderRadius: "2px", justifyContent: "space-between", paddingTop: "2em"}}> - <Hidden smDown> - <Button aria-label="Reportar" size="small"> - <ReportIcon /> REPORTAR ABUSO OU ERRO </Button> - <Button aria-label="Compartilhar"> - <ShareIcon /> COMPARTILHAR </Button> - </Hidden> - <Button aria-label="Guardar"> - <AddIcon /> GUARDAR </Button> - <Button variant="contained" color="secondary"> - <OpenIcon/> Abrir Recurso </Button> - <Hidden mdUp> - <Button aria-controls="simple-menu" aria-haspopup="true" onClick={handleClick}> - <MoreVertIcon/> - </Button> - <Menu - id="simple-menu" - anchorEl={anchorEl} - keepMounted - open={Boolean(anchorEl)} - onClose={handleClose} - > - <MenuItem onClick={handleClose}> - <ListItemIcon> - <ShareIcon /> - </ListItemIcon> - Compartilhar</MenuItem> - <MenuItem onClick={handleClose}> - <ListItemIcon> - <ReportIcon /> - </ListItemIcon> - Reportar</MenuItem> - </Menu> - </Hidden> - </CardActions> - </CardContent> - </PaperStyled> - <PaperStyled elevation={elevateStyle}> - <Row style={{padding: "15px"}}> - <Col md={8} sm={12}> - <Typography variant="h5" color="textSecondary" component="h3"> - Sobre o Recurso - </Typography> - <Typography component="p" color="textSecondary"> - Paper can be used to build surface or other elements for your application. - </Typography> - <div style={{paddingTop: "4em"}}> - <Typography variant="h5" color="textSecondary" component="h3"> - Informações Adicionais</Typography> - <Tag name="teste"/> - <Typography component="p" color="textSecondary"> - <SdCardIcon/>Tamanho: - </Typography> - <Typography component="p" color="textSecondary"> - <TranslateIcon/>Idioma: - </Typography> - <Typography component="p" color="textSecondary"> - <InsertDriveFileIcon/>Formato: - </Typography> - <Typography component="p" color="textSecondary"> - <DateRangeIcon/>Data de Envio: - </Typography> - <Typography component="p" color="textSecondary"> - <UpdateIcon/>Modificado em: - </Typography> - <Typography component="p" color="textSecondary"> - <AssignmentOutlinedIcon/>Tipo de Licença: - </Typography> - </div> - </Col> - <Col md={4} sm={12}> - <div style={{borderLeft:"1px solid #e5e5e5"}}> - <Typography> - Enviado por: - </Typography><br/> - <img style={{padding: "2em" }} alt="Avatar" src={noAvatar} height="100em"/> - </div> - </Col> - </Row> - - - </PaperStyled> - <PaperStyled elevation={elevateStyle}> - <CardContent> - Conte sua experiência com o Recurso - <Rating - name="customized-color" - value={0} - precision={0.5} - /> - <Row> - <Col md={10} sm={12}> - <TextField fullWidth="true" multiline="true" required="true" placeholder="Escreva aqui sua experiência com o recurso *"/> - </Col> - <Col> - <Button variant="contained" color="primary">submit </Button> - </Col> - </Row> - - </CardContent> - <CardContent> - <Typography variant="h5" component="p" color="textSecondary">Relatos sobre o uso do Recurso</Typography> - <Coment author="jorginho" coment="muito bom gostei mto bom msm"/> - </CardContent> - </PaperStyled> - </div> - ); -} diff --git a/src/Components/AcessibilityBar.js b/src/Components/AcessibilityBar.js deleted file mode 100644 index 7546ea2f92646dc4ee8da27a1f5550d8fc702a2a..0000000000000000000000000000000000000000 --- a/src/Components/AcessibilityBar.js +++ /dev/null @@ -1,60 +0,0 @@ -/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre -Departamento de Informatica - Universidade Federal do Parana - -This file is part of Plataforma Integrada MEC. - -Plataforma Integrada MEC is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -Plataforma Integrada MEC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ - -import React, {Component} from 'react'; -import {Row, Col, Container} from 'react-grid-system'; -import Bt from './Button.js' - -const acessibilityBar ={ - width: '100%', - color: 'gray', - fontFamily: '"Roboto", Sans-Serif', - whiteSpace: 'nowrap', - fontSize: '0.7vw', - textAlign: 'right' - -} - -class AcessibilityBar extends Component{ - renderBt(name, link=undefined){ - return <Bt name={name} link={link}/> - } - render(){ - return( - <Container fluid={true}> - <Row style={acessibilityBar}> - <Col md={6} xs={6} lg={6} style={{textAlign: 'left'}}> - {this.renderBt("Ir para conteúdo 1", "texto1")} - {this.renderBt("Ir para menu 2", "texto2")} - {this.renderBt("Ir para menu 3", "texto3")} - {this.renderBt("Ir para rodapé 4", "texto4")} - </Col> - <Col md={6} xs={6} lg={6} style={{textAlign: 'right'}}> - Tamanho do Texto: {this.renderBt("A+")} - {this.renderBt("A-")} - {this.renderBt("A")} - {this.renderBt("Contraste")} - {this.renderBt("Acessibilidade")} - {this.renderBt("Mapa do Site")} - </Col> - </Row> - </Container> - ); - } -} -export default AcessibilityBar; diff --git a/src/Components/AchievementDescriptionCard.js b/src/Components/AchievementDescriptionCard.js index 3af102fe901acb8f237a4ba1d1637caaf30c97fd..ad01fc46506825aef6570d3c342bdac2d088d8f2 100644 --- a/src/Components/AchievementDescriptionCard.js +++ b/src/Components/AchievementDescriptionCard.js @@ -1,6 +1,5 @@ import React from 'react' import styled from 'styled-components' -import { Container } from 'react-grid-system' import Paper from '@material-ui/core/Paper'; import { Grid } from '@material-ui/core' import RequirementDialog from './RequirementsDialog.js'; diff --git a/src/Components/Activities/Definitions.js b/src/Components/Activities/Definitions.js index 8ff971c8ee208612b34a6b567f489c4a965013bc..9b2e14344517041fcd61b7ac6a1f16b6c1bb4d6b 100644 --- a/src/Components/Activities/Definitions.js +++ b/src/Components/Activities/Definitions.js @@ -1,4 +1,3 @@ -import React from 'react' export const ObjectColor = { 'Recurso' : 'recurso-color', 'Coleção' : 'colecao-color', diff --git a/src/Components/ActivityListItem.js b/src/Components/ActivityListItem.js index 24a00b77a9afb3cc534a52925e70a622b06a4ff7..e6d9d2b7d0de16dbcad37d965ba11c4ed394f2c6 100644 --- a/src/Components/ActivityListItem.js +++ b/src/Components/ActivityListItem.js @@ -16,16 +16,14 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useState, useEffect} from 'react' +import React, {useEffect} from 'react' import styled from 'styled-components' import ListItem from '@material-ui/core/ListItem'; import ListItemAvatar from '@material-ui/core/ListItemAvatar'; -import ListItemIcon from '@material-ui/core/ListItemIcon'; -import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; import ListItemText from '@material-ui/core/ListItemText'; import Avatar from '@material-ui/core/Avatar'; import noAvatar from "../img/default_profile.png"; -import {GetActivityProperties, Tag, Possible_Activities, ObjectColor} from './Activities/Definitions.js' +import {GetActivityProperties, Tag, ObjectColor} from './Activities/Definitions.js' //icons import FavoriteIcon from '@material-ui/icons/Favorite'; import CreateIcon from '@material-ui/icons/Create'; @@ -36,6 +34,7 @@ import ReportIcon from '@material-ui/icons/Report'; import CloudUploadIcon from '@material-ui/icons/CloudUpload'; import ThumbDownIcon from '@material-ui/icons/ThumbDown'; import DeleteIcon from '@material-ui/icons/Delete'; +import {Link} from 'react-router-dom' const GetObjectColor = (tag) => { return ObjectColor[tag] @@ -72,7 +71,7 @@ const getTimeDifference = (timestamp) => { const then = moment(timestamp, moment.ISO_8601) let duration = moment.duration(now.diff(then)) - {/*console.log('duration: ', duration)*/} + // {/*console.log('duration: ', duration)*/} let timeDiff; if (duration._data.years > 0) { timeDiff = duration._data.years + (duration._data.years > 1 ? ' anos' : ' ano') @@ -104,7 +103,7 @@ export default function ActivityListItem (props) { useEffect( () => { const newTag = Tag[(props.actionType === 'CuratorAssignment' ? props.actionType : props.objectType)] const {icon, text, text2 } = GetActivityProperties(props.activity) - {/*console.log('icon, text, text2: ', icon, text, text2)*/} + // {/*console.log('icon, text, text2: ', icon, text, text2)*/} setActivity({...activity, tag : newTag, @@ -115,22 +114,22 @@ export default function ActivityListItem (props) { }, [] ) return ( - <StyledListItem> + <StyledListItem onMenuBar={props.onMenuBar}> { !props.onMenuBar && <> - + <ListItemAvatar> <Avatar alt='user avatar' src={props.avatar ? props.avatar : noAvatar}/> </ListItemAvatar> - getNotificationIcon(activity.icon) + {getNotificationIcon(activity.icon)} </> } <ListItemText primary = { <div> - <span className = {'tag-object' + ' ' + GetObjectColor(activity.tag)}> + <span className = {`tag-object ${GetObjectColor(activity.tag)}`}> {activity.tag} </span> <span className="time-ago-span"> · há {getTimeDifference(props.createdAt)}</span> @@ -139,7 +138,7 @@ export default function ActivityListItem (props) { secondary = { <div> <span> - <a href={props.ownerHref} className="owner-name-a" >{props.ownerName}</a> {activity.text} <a href={props.recipientHref} className="recipient-name-a">{props.recipientName}</a> {activity.text2} + <Link to={props.ownerHref} className="owner-name-a" >{props.ownerName}</Link> {activity.text} <Link to={props.recipientHref} className="recipient-name-a">{props.recipientName}</Link> {activity.text2} </span> </div> } @@ -150,7 +149,7 @@ export default function ActivityListItem (props) { } const StyledListItem = styled(ListItem)` - padding : 20px 60px !important ; + padding : ${props => props.onMenuBar ? "8px 16px !important" : "20px 60px !important"}; border-bottom : 1px solid #eee; display : flex; justify-content : flex-start; diff --git a/src/Components/AreasSubPages.js b/src/Components/AreasSubPages.js index f911ec1d0d1058885610be48f29f8b8387635106..b8d429a946ea7f27d93034d0baddef361cfc3582 100644 --- a/src/Components/AreasSubPages.js +++ b/src/Components/AreasSubPages.js @@ -17,112 +17,85 @@ You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ import React, { Component } from "react"; -import axios from "axios"; -import { apiUrl } from "../env"; import "./carousel.css"; import { Col, Row, Container, Hidden, Visible } from "react-grid-system"; -import ResourceCard from "./ResourceCard"; import MaterialCard from "./MaterialCard"; -import CollectionCard from "./CollectionCard"; import "react-responsive-carousel/lib/styles/carousel.min.css"; import { Carousel } from "react-responsive-carousel"; import recursos from "../img/ilustra_recursos_digitais.png"; import materiais from "../img/ilustra_materiais.png"; import colecoes from "../img/ilustra_colecoes.png"; -import Grid from '@material-ui/core/Grid'; -import ResourceCardFunction from './ResourceCardFunction.js' -import CollectionCardFunction from './CollectionCardFunction.js' +import ResourceCardFunction from "./ResourceCardFunction.js"; +import CollectionCardFunction from "./CollectionCardFunction.js"; +import colecoes_obj from './FormationMaterialsResources/formationMaterials'; +import ExpandedMaterial from './ExpandedMaterials'; +import {getRequest} from './HelperFunctions/getAxiosConfig.js' -const areaStyle = { - paddingTop: "5px", - fontSize: "16px", - textAlign: "left", - backgroundColor: "inherit", - width: "1000px", - margin: "auto", - padding: "20px", - minHeight: "190px" -}; +const materials = colecoes_obj(); class ReqResources extends Component { constructor(props) { super(props); this.state = { - resources: [] + resources: [], }; } + componentDidMount() { - axios - .get(`${apiUrl}/learning_objects?limit=12&sort=["published_at", "desc"]`) - .then(res => { - this.setState({ resources: res.data }); - console.log(res.data); - }); + const url = `/learning_objects?limit=12&sort=["published_at", "desc"]` + getRequest(url, (data) => {this.setState({ resources: data })}, (error) => {console.log(error)}) + } + + resourcesPerPage() { + var pageWidth = window.innerWidth + if (pageWidth >= 1200) { + return 3 + } + else { + if (pageWidth > 766) { + return 2 + } + else { + return 1 + } + } } + render() { - var row1 = this.state.resources.slice(0, 4); - var row2 = this.state.resources.slice(4, 8); - var row3 = this.state.resources.slice(8, 13); + var rows = [] + var resources_per_page = this.resourcesPerPage() + for (let i = 0; i < 12 / resources_per_page; i++) { + rows.push(this.state.resources.slice(i * resources_per_page, resources_per_page * (i + 1))) + } return ( - <Carousel showThumbs={false} infiniteLoop={true} showStatus={false}> - <Row style={{paddingBottom: "5px"}}> - {row1.map(card => <Col md={3} sm={6} key={card.id}> - <ResourceCardFunction - avatar = {card.publisher.avatar} - id={card.id} - thumbnail = {card.thumbnail} - type = {card.object_type ? card.object_type : "Outros"} - title={card.name} - published={card.state === "published" ? true : false} - likeCount={card.likes_count} - liked={card.liked} - rating={card.review_average} - author={card.author} - tags={card.educational_stages} - href={'/recurso/' + card.id} - downloadableLink={card.default_attachment_location} - /></Col>)} - </Row> - <Row> - {row2.map(card => <Col md={3} sm={6} key={card.id}> - <ResourceCardFunction - avatar = {card.publisher.avatar} - id={card.id} - thumbnail = {card.thumbnail} - type = {card.object_type ? card.object_type : "Outros"} - title={card.name} - published={card.state === "published" ? true : false} - likeCount={card.likes_count} - liked={card.liked} - rating={card.review_average} - author={card.author} - tags={card.educational_stages} - href={'/recurso/' + card.id} - downloadableLink={card.default_attachment_location} - - /></Col>)} - </Row> - <Row> - {row3.map(card => <Col md={3} sm={6} key={card.id}> - <ResourceCardFunction - avatar = {card.publisher.avatar} - id={card.id} - thumbnail = {card.thumbnail} - type = {card.object_type ? card.object_type : "Outros"} - title={card.name} - published={card.state === "published" ? true : false} - likeCount={card.likes_count} - liked={card.liked} - rating={card.review_average} - author={card.author} - tags={card.educational_stages} - href={'/recurso/' + card.id} - downloadableLink={card.default_attachment_location} - /></Col>)} - </Row> - </Carousel> - ) + <Carousel showThumbs={false} infiniteLoop={true} showStatus={false}> + { + rows.map((row, index) => ( + <Row style={{ paddingBottom: "5px", margin: '0 auto', width: "80%", justifyContent: "center" }} key={(index + 1)}> + {row.map((card) => ( + <div style={{ marginLeft: 10, display: 'flex' }} key={card.id * (index + 1)}> + <ResourceCardFunction + avatar={card.publisher.avatar} + id={card.id} + thumbnail={card.thumbnail} + type={card.object_type ? card.object_type : "Outros"} + title={card.name} + published={card.state === "published" ? true : false} + likeCount={card.likes_count} + liked={card.liked} + rating={card.review_average} + author={card.publisher.name} + tags={card.tags} + href={"/recurso/" + card.id} + downloadableLink={card.default_attachment_location} + /> + </div> + ))} + </Row> + ))} + </Carousel> + ); } } @@ -130,90 +103,105 @@ class ReqCollections extends Component { constructor(props) { super(props); this.state = { - collections: [] + collections: [], }; } componentDidMount() { - axios - .get(`${apiUrl}/collections?limit=12&sort=["updated_at", "desc"]`) - .then(res => { - this.setState({ collections: res.data }); - console.log(res.data); - }); + const url = `/collections?limit=12&sort=["updated_at", "desc"]` + + getRequest(url, (data) => {this.setState({ collections: data })}, (error) => {console.log(error)}) } + collectionsPerPage() { + var pageWidth = window.innerWidth + if (pageWidth >= 1200) { + return 3 + } + else { + if (pageWidth > 766) { + return 2 + } + else { + return 1 + } + } + } + render() { - var row1 = this.state.collections.slice(0, 4); - var row2 = this.state.collections.slice(4, 8); - var row3 = this.state.collections.slice(8, 13); + var rows = [] + var collections_per_page = this.collectionsPerPage() + for (let i = 0; i < 12 / collections_per_page; i++) { + rows.push(this.state.collections.slice(i * collections_per_page, collections_per_page * (i + 1))) + } return ( <Carousel showThumbs={false} infiniteLoop={true} showStatus={false}> - <Row style={{paddingBottom: "5px"}}> - {row1.map(card => <Col md={3} sm={6} key={card.id}> - <CollectionCardFunction name={card.name} - rating={card.score} - author={card.owner.name} - description={card.description} - thumbnails={card.items_thumbnails} - avatar={card.owner.avatar}/></Col>)} - </Row> - <Row> - {row2.map(card => <Col md={3} sm={6} key={card.id}> - <CollectionCardFunction name={card.name} - rating={card.score} - author={card.owner.name} - description={card.description} - thumbnails={card.items_thumbnails} - avatar={card.owner.avatar}/></Col>)} - </Row> - <Row> - {row3.map(card => <Col md={3} sm={6} key={card.id}> - <CollectionCardFunction name={card.name} - rating={card.score} - author={card.owner.name} - description={card.description} - thumbnails={card.items_thumbnails} - avatar={card.owner.avatar}/></Col>)} - </Row> - </Carousel> - ) + { + rows.map((row, index) => ( + <Row style={{ paddingBottom: "5px", margin: '0 auto', width: "80%", justifyContent: "center" }} key={(index + 1)}> + {row.map((card) => ( + <div style={{ marginLeft: 10, display: 'flex' }} key={card.id * (index + 1)}> + <CollectionCardFunction + name={card.name} + tags={card.tags} + rating={card.score} + id={card.id} + author={card.owner.name} + description={card.description} + thumbnails={card.items_thumbnails} + avatar={card.owner.avatar} + likeCount={card.likes_count} + followed={card.followed} + liked={card.liked} + collections={card.collection_items} + authorID={card.owner.id} + /> + </div> + ))} + </Row> + ))} + </Carousel> + ); } } class SubPages extends Component { + constructor(props) { + super(props); + this.state = { + currMaterial: { + open: false, + material: {} + }, + }; + } + areaRender() { switch (this.props.banner) { case "Recursos": return ( <React.Fragment> - <div style={{ backgroundColor: "#ff7f00" }}> - <Container style={areaStyle}> - <Grid container style={{ display: "flex" }} spacing={5}> - <Grid item xs={3}> - <img - src={recursos} - alt="aba recursos" - height="155" - style={{ float: "right" }} - /> - </Grid> - <Grid item xs={9}> - <p style={{ textAlign: "justify", color: "#fff" }}> - Nesta área, você tem acesso a Recursos Educacionais - Digitais, isto é, a vídeos, animações e a outros recursos - destinados à educação. São Recursos de portais parceiros - do MEC e de professores que, como você, atuam na Educação - Básica! + <div style={{ backgroundColor: "#ff7f00", position: "relative" }}> + <div style={{ textAlign: "justify", color: "#fff", minHeight: 195, paddingLeft: 10, paddingRight: 10, paddingTop: 20, paddingBottom: 20 }}> + <img + src={recursos} + alt="aba recursos" + height="155" + style={{ float: "left", marginRight: 20, marginBottom: 20, marginLeft: window.innerWidth >= 825 ? "25%" : "0px" }} + /> + <p style={{ textAlign: "justify", color: "#fff", marginRight: window.innerWidth >= 825 ? "25%" : "0px" }}> + Nesta área, você tem acesso a Recursos Educacionais + Digitais, isto é, a vídeos, animações e a outros recursos + destinados à educação. São Recursos de portais parceiros + do MEC e de professores que, como você, atuam na Educação + Básica! </p> - </Grid> - </Grid> - </Container> + </div> </div> <Container style={{ padding: "20px" }}> <p style={{ paddingBottom: "5px", borderBottom: "1px solid #ff7f00", - color: "#ff7f00" + color: "#ff7f00", }} > Recursos mais recentes{" "} @@ -226,23 +214,56 @@ class SubPages extends Component { </Visible> </Container> </React.Fragment> - ); - case "Materiais": - return ( - <React.Fragment> - <div style={{backgroundColor: "#e81f4f"}}> - <Container style={areaStyle}> + ); + case "Materiais": + + const HandleExpandMaterial = (id) => { + if (id !== this.state.currMaterial.material.id) + this.setState({ + currMaterial: { + open: true, + material: { ...materials[id] } + } + }) + else + this.setState({ + currMaterial: { + open: false, + material: {} + } + }) + } + - <img src={materiais} alt="aba materiais" height="165" style={{float: "right"}}/> - <p>Nesta área, você acessa livremente materiais completos de formação, - como cursos já oferecidos pelo MEC e seus parceiros. São conteúdos - elaborados por equipes multidisciplinares e de autoria de pesquisadores - e educadores renomados nas áreas.</p> - </Container> + return ( + <React.Fragment> + <div style={{ backgroundColor: "#e81f4f", position: "relative" }}> + <div style={{ textAlign: "justify", color: "#fff", minHeight: 195, paddingLeft: 10, paddingRight: 10, paddingTop: 20, paddingBottom: 20 }}> + <img + src={materiais} + alt="aba recursos" + height="155" + style={{ float: "left", marginRight: 20, marginBottom: 20, marginLeft: window.innerWidth >= 825 ? "25%" : "0px" }} + /> + <p style={{ textAlign: "justify", color: "#fff", marginRight: window.innerWidth >= 825 ? "25%" : "0px" }}> + Nesta área, você acessa livremente materiais completos de + formação, como cursos já oferecidos pelo MEC e seus + parceiros. São conteúdos elaborados por equipes + multidisciplinares e de autoria de pesquisadores e + educadores renomados nas áreas. + </p> </div> - <Container style={{padding:"20px"}}> - <p style={{paddingBottom:"5px", borderBottom: "1px solid #e81f4f", color: "#e81f4f"}}> - Materiais mais recentes </p> + </div> + <Container style={{ padding: "20px" }}> + <p + style={{ + paddingBottom: "5px", + borderBottom: "1px solid #e81f4f", + color: "#e81f4f", + }} + > + Materiais mais recentes{" "} + </p> <Carousel style={{ padding: "20px" }} @@ -251,54 +272,58 @@ class SubPages extends Component { showStatus={false} > <Row> - <Col md={3}> - <MaterialCard name="oioi" /> - </Col> - <Col md={3}> - <MaterialCard name="oioi" /> - </Col> - <Col md={3}> - <MaterialCard name="oioi" /> - </Col> - <Col md={3}> - <MaterialCard name="oioi" /> - </Col> + { + materials.map((material, index) => { + return ( + <Col md={3} key={index}> + <MaterialCard + name={material.name} + thumb={material.img} + score={material.score} + modules={material.topics} + handleExpand={HandleExpandMaterial} + id={index} + /> + </Col> + ) + }) + } </Row> </Carousel> + { + this.state.currMaterial.open ? + <ExpandedMaterial material={this.state.currMaterial.material} /> + : + null + } </Container> - </React.Fragment> + </React.Fragment > ); case "Colecoes": return ( <React.Fragment> - <div style={{ backgroundColor: "#673ab7" }}> - <Container style={areaStyle}> - <Grid container spacing={5}> - <Grid item xs={3}> - <img - src={colecoes} - alt="aba coleções" - width="180" - style={{ float: "right" }} - /> - </Grid> - <Grid item xs={9}> - <p style={{ textAlign: "justify", color: "#fff" }}> - Nesta área, você tem acesso às coleções criadas e - organizadas pelos usuários da plataforma. É mais uma - possibilidade de buscar recursos educacionais para sua - aula! + <div style={{ backgroundColor: "#673ab7", position: "relative" }}> + <div style={{ textAlign: "justify", color: "#fff", minHeight: 195, paddingLeft: 10, paddingRight: 10, paddingTop: 20, paddingBottom: 20 }}> + <img + src={colecoes} + alt="aba recursos" + height="155" + style={{ float: "left", marginRight: 20, marginBottom: 20, marginLeft: window.innerWidth >= 825 ? "25%" : "0px" }} + /> + <p style={{ textAlign: "justify", color: "#fff", marginRight: window.innerWidth >= 825 ? "25%" : "0px" }}> + Nesta área, você tem acesso às coleções criadas e + organizadas pelos usuários da plataforma. É mais uma + possibilidade de buscar recursos educacionais para sua + aula! </p> - </Grid> - </Grid> - </Container> + </div> </div> <Container style={{ padding: "20px" }}> <p style={{ paddingBottom: "5px", borderBottom: "1px solid #673ab7", - color: "#673ab7" + color: "#673ab7", }} > Coleções mais recentes{" "} @@ -316,4 +341,6 @@ class SubPages extends Component { return <div>{this.areaRender()}</div>; } } + + export default SubPages; diff --git a/src/Components/Button.js b/src/Components/Button.js deleted file mode 100644 index afe4acadacfa68b9e44d0c98b042352108c9305d..0000000000000000000000000000000000000000 --- a/src/Components/Button.js +++ /dev/null @@ -1,75 +0,0 @@ -/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre -Departamento de Informatica - Universidade Federal do Parana - -This file is part of Plataforma Integrada MEC. - -Plataforma Integrada MEC is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -Plataforma Integrada MEC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ - -import React, {Component} from 'react'; - -class Bt extends Component{ - constructor(props){ - super(props); - - this.state ={ - color: "white", - hover: "#F0F0F0", - iddle: "white" - }; - } - componentWillMount(){ - if (this.props.backhover){ - this.setState({hover: this.props.backhover}) - } - if (this.props.iddle){ - this.setState({color:this.props.background, - iddle: this.props.background}) - } - } - onHover(){ - this.setState({color: this.state.hover}) - } - onIddle(){ - this.setState({color: this.state.iddle}) - } - onClick(){ - if(this.props.link === undefined){ - } - if(this.props.method !== undefined ){ - console.log(this.props.parameter) - this.props.method(this.props.parameter) - } - else { - alert(`goto ${this.props.link}`) - } - } - - render(){ - const acessibilityBt = { - borderStyle: 'none', - padding: '10px', - textAlign: 'center', - display: 'inline-block', - backgroundColor: this.state.color, - color: "#ababab" - }; - return( - <span id={this.props.name +"-Button"} style={acessibilityBt} onMouseEnter={this.onHover.bind(this)} onMouseOut={this.onIddle.bind(this)} onClick={this.onClick.bind(this)}> - {this.props.name} - </span> - ); - } -} - -export default Bt; diff --git a/src/Components/ButtonAvaliarRecurso.js b/src/Components/ButtonAvaliarRecurso.js index 3e41d4fa84953a557ca68378dd2d6cd683f9670c..8b307048182a36bd0cafa1063a86b45ad64105b8 100644 --- a/src/Components/ButtonAvaliarRecurso.js +++ b/src/Components/ButtonAvaliarRecurso.js @@ -1,4 +1,4 @@ -import React, {useState} from 'react' +import React from 'react' import { Button } from '@material-ui/core'; import styled from 'styled-components' import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; diff --git a/src/Components/ButtonGuardarColecao.js b/src/Components/ButtonGuardarColecao.js index 65ae71a2ab7c2de703e21e81679c32f7c4454481..4d8865f7cb57e8c35ece36587f77922b0d0ab48a 100644 --- a/src/Components/ButtonGuardarColecao.js +++ b/src/Components/ButtonGuardarColecao.js @@ -1,30 +1,67 @@ -import React, {useState, useContext} from 'react' -import {Store} from '../Store.js' +import React, { useState, useContext } from 'react' +import { Store } from '../Store.js' import Button from '@material-ui/core/Button'; import styled from 'styled-components' import CreateNewFolderIcon from '@material-ui/icons/CreateNewFolder'; import GuardarModal from './GuardarModal' +import SignUpModal from './SignUpModal' +import LoginModal from './LoginModal.js' +import Snackbar from '@material-ui/core/Snackbar'; +import MuiAlert from '@material-ui/lab/Alert'; -export default function ButtonGuardarColecao (props) { - const {state} = useContext(Store) +export default function ButtonGuardarColecao(props) { + const { state } = useContext(Store) const [saveToCol, toggleSave] = useState(false) const handleGuardar = () => { - if(state.currentUser.id === '') { - console.log('abrir login modal'); + if (!state.currentUser.id) { + handleLogin() } else { toggleSave(true); } } + const handleSignUp = () => { + setSignUp(!signUpOpen) + } + + const handleLogin = () => { + setLogin(!loginOpen) + } + + function Alert(props) { + return <MuiAlert elevation={6} variant="filled" {...props} />; + } + + function toggleLoginSnackbar(reason) { + if (reason === 'clickaway') { + return; + } + handleSuccessfulLogin(false); + } + + const [signUpOpen, setSignUp] = useState(false) + const [loginOpen, setLogin] = useState(false) + const [successfulLoginOpen, handleSuccessfulLogin] = useState(false) + return ( <> - <GuardarModal open={saveToCol} handleClose={() => {toggleSave(false)}} - thumb={props.thumb} title={props.title} recursoId={props.learningObjectId} - /> - <StyledButton onClick={handleGuardar}> - <CreateNewFolderIcon/> GUARDAR - </StyledButton> + <SignUpModal open={signUpOpen} handleClose={handleSignUp} openLogin={handleLogin} + /> + <LoginModal open={loginOpen} handleClose={() => setLogin(false)} openSignUp={handleSignUp} + openSnackbar={() => { handleSuccessfulLogin(true) }} + /> + <Snackbar open={successfulLoginOpen} autoHideDuration={1000} onClose={toggleLoginSnackbar} + anchorOrigin={{ vertical: 'top', horizontal: 'center' }} + > + <Alert severity="success" style={{ backgroundColor: "#00acc1" }}>Você está conectado(a)!</Alert> + </Snackbar> + <GuardarModal open={saveToCol} handleClose={() => { toggleSave(false) }} + thumb={props.thumb} title={props.title} recursoId={props.learningObjectId} + /> + <StyledButton onClick={handleGuardar}> + <CreateNewFolderIcon /> GUARDAR + </StyledButton> </> ) } diff --git a/src/Components/Card.js b/src/Components/Card.js deleted file mode 100644 index e721b5504a51eb1a24130c0028bba39da9ee6555..0000000000000000000000000000000000000000 --- a/src/Components/Card.js +++ /dev/null @@ -1,105 +0,0 @@ -/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre -Departamento de Informatica - Universidade Federal do Parana - -This file is part of Plataforma Integrada MEC. - -Plataforma Integrada MEC is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -Plataforma Integrada MEC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ - -import React, {Component} from 'react'; -import {Container} from 'react-grid-system'; -import Card from '@material-ui/core/Card'; -import CardContent from '@material-ui/core/CardContent'; -import CardActions from '@material-ui/core/CardActions'; -import IconButton from '@material-ui/core/IconButton'; -import Typography from '@material-ui/core/Typography'; -import FavoriteIcon from '@material-ui/icons/Favorite'; -import StarRatings from 'react-star-ratings'; -import animacao from "../img/laranja/ANIMACAO_SIMULACAO.jpg"; -import apresentacao from "../img/laranja/APRESENTACAO.jpg"; -import aplicativo from "../img/laranja/APP.jpg"; -import audio from "../img/laranja/AUDIO.jpg"; -import vazio from "../img/laranja/EMPTY.jpg"; -import imagem from "../img/laranja/IMAGEM.jpg"; -import grafico from "../img/laranja/INFOGRAFICO.jpg"; -import jogo from "../img/laranja/JOGO.jpg"; -import livro from "../img/laranja/LIVRO_DIGITAL.jpg"; -import mapa from "../img/laranja/MAPA.jpg"; -import outros from "../img/laranja/OUTROS.jpg"; -import software from "../img/laranja/SOFTWARE.jpg"; -import texto from "../img/laranja/TEXTO.jpg"; -import video from "../img/laranja/VIDEO.jpg"; - -import AddIcon from '@material-ui/icons/CreateNewFolder'; -import Options from './CardOptions' -import Video from '@material-ui/icons/OndemandVideo'; - -var types = [{label: "Animação", thumb: animacao}, {label: "Apresentação", thumb: apresentacao}, -{label: "Aplicativo" , thumb: aplicativo}, {label: "Áudio", thumb: audio}, {label: "Vazio", thumb: vazio}, {label: "Imagem", thumb: imagem}, {label: "Gráfico", thumb: grafico}, {label: "Jogo", thumb: jogo}, {label: "Livro", thumb: livro}, {label: "Mapa", thumb: mapa}, {label: "Outros", thumb: outros}, {label: "Software", thumb:software}, {label: "Texto", thumb:texto}, {label: "Vídeo", thumb:video}] -class ResourceCard extends Component{ - constructor(props){ - super(props); - this.state = { - hover: false, - thumbnail: null, - isVideo: false, - }; - }; - decide(){ - var aux = this.props.thumbnail; - if (!aux) { - aux = types.find(function(element){ return element.label === (this.props.type)}); - } - this.setState({thumbnail: aux.thumb}); - console.log(this.state.thumbnail); - (this.props.type === "Vídeo")? this.setState({isvideo:true}) : this.setState({isvideo:false}); -}; - render(){ - {this.decide()} - return ( - <Card> - <img src={this.state.thumbnail} alt="thumbnail do recurso"/> - <CardContent style={{height: "60%", textAlign: "left", paddingBottom: "0px"}}> - <Typography variant="body2" color="textSecondary" component="p" style={{height:"45px", overflow: "hidden", fontSize: "0.8em"}}> - {this.props.name} - </Typography> - </CardContent> - <Container style={{textAlign: "left"}}> - <StarRatings - rating={this.props.rating*100} - starRatedColor="ff7f00" - starDimension="20px" - starSpacing="2px" - starHoverColor="red" - /> - </Container> - <CardActions style={{justifyContent: "space-between"}}> - { this.state.isVideo - ? <Video style={{color:"#ff7f00"}} /> - : <br/>} - <IconButton aria-label="Favoritar" size="small"> - <FavoriteIcon /> - </IconButton> - </CardActions> - <CardActions style={{borderTop:"1px solid #e5e5e5", justifyContent: "space-between"}}> - - <IconButton aria-label="Guardar" size="small"> - <AddIcon /> - </IconButton> - <Options/> - </CardActions> - </Card> - );} -} - -export default ResourceCard; diff --git a/src/Components/Carousel.js b/src/Components/Carousel.js index 3e8e9029c2ffba6e2c068378b7f3c73f8277e030..ba3602311c2fa2b3607a89c7e196d01c828ffe4b 100644 --- a/src/Components/Carousel.js +++ b/src/Components/Carousel.js @@ -18,13 +18,10 @@ along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/> import React, { Component } from 'react'; -import ReactDOM from 'react-dom'; import "react-responsive-carousel/lib/styles/carousel.min.css"; import { Carousel } from 'react-responsive-carousel'; import styled from 'styled-components'; import Grid from '@material-ui/core/Grid'; -import ArrowBackIosIcon from '@material-ui/icons/ArrowBackIos'; -import ArrowForwardIosIcon from '@material-ui/icons/ArrowForwardIos'; @@ -524,7 +521,7 @@ class TermsCarousel extends Component { <p>Como repositório, a Plataforma hospeda somente Recursos Educacionais Abertos (REA). Todo conteúdo inserido por usuários deve ser aberto.</p> </div> <div className="content"> - <img className="twoArrow" src={Arrow_double}/> + <img alt="" className="twoArrow" src={Arrow_double}/> <p>Como referatório, a Plataforma aponta links para parceiros, e<br/> esses recursos podem ser abertos ou fechados.</p> </div> </Grid> diff --git a/src/Components/ColCardOwnerOptions.js b/src/Components/ColCardOwnerOptions.js index 76b5b750be97631f4262bc89408dac4524116fdb..37dc26977cd9133db5b644dad03eb6860f40ea04 100644 --- a/src/Components/ColCardOwnerOptions.js +++ b/src/Components/ColCardOwnerOptions.js @@ -28,6 +28,7 @@ import {Link} from 'react-router-dom' import MoreVertIcon from '@material-ui/icons/MoreVert'; import styled from 'styled-components' import ModalExcluirColecao from './ModalExcluirColecao.js' +import ModalEditarColecao from './ModalEditarColecao.js' export default function ColCardOwnerOptions (props) { const [anchorEl, setAnchorEl] = React.useState(null); @@ -43,11 +44,17 @@ export default function ColCardOwnerOptions (props) { const [modalExcluirOpen, toggleModalExcluir] = useState(false) const openModalExcluir = () => {toggleModalExcluir(true)} + const [modalEditarOpen, toggleModalEditar] = useState(false) + + return ( <> <ModalExcluirColecao id={props.id} open={modalExcluirOpen} handleClose={() => {toggleModalExcluir(false)}} /> + <ModalEditarColecao id={props.id} + open={modalEditarOpen} handleClose={() => {toggleModalEditar(false)}} + /> <div style={{fontSize: "12px"}}> <Button aria-controls="simple-menu" aria-haspopup="true" onClick={handleClick} style={{color : "#666"}}> @@ -66,7 +73,7 @@ export default function ColCardOwnerOptions (props) { </Link> </StyledMenuItem> - <StyledMenuItem onClick={() => {console.log('TODO: MODAL EDITAR COLECAO')}}> + <StyledMenuItem onClick={() => {toggleModalEditar(true)}}> <ListItemIcon><CreateIcon /></ListItemIcon>Editar </StyledMenuItem> diff --git a/src/Components/ColCardPublicOptions.js b/src/Components/ColCardPublicOptions.js index 2ba27fd6551072f69d9218be353c78d2e84413eb..48a7bab2be1d264fb8681bb3e79637c68d08894f 100644 --- a/src/Components/ColCardPublicOptions.js +++ b/src/Components/ColCardPublicOptions.js @@ -27,76 +27,105 @@ import MoreVertIcon from '@material-ui/icons/MoreVert'; import styled from 'styled-components' import ErrorIcon from '@material-ui/icons/Error'; import ReportModal from './ReportModal.js' -import {getAxiosConfig} from '../Components/HelperFunctions/getAxiosConfig' -import axios from 'axios' -import {apiUrl} from '../env'; +import ReportProblemIcon from '@material-ui/icons/ReportProblem'; +import OpenInBrowserIcon from '@material-ui/icons/OpenInBrowser'; +import {deleteRequest} from '../Components/HelperFunctions/getAxiosConfig' export default function ColCardPublicOptions (props) { const [anchorEl, setAnchorEl] = React.useState(null); - function handleClick(event) { - setAnchorEl(event.currentTarget); - } + function handleClick(event) { + setAnchorEl(event.currentTarget); + } - function handleClose() { - setAnchorEl(null); - } + function handleClose() { + setAnchorEl(null); + } - const [reportModalOpen, toggleReportModal] = useState(false) - const handleReportModal = (value) => {toggleReportModal(value)} + const [reportModalOpen, toggleReportModal] = useState(false) + const handleReportModal = (value) => {toggleReportModal(value)} - const handleUnfollow = () => { - let config = getAxiosConfig() - let payload = {} + const handleUnfollow = () => { - axios.put( (`${apiUrl}/collections/` + props.id + '/follow'),payload, config).then( - (response) => {console.log(response.data)}, (error) => {console.log(error)}) - } + deleteRequest(`/collections/${props.id}/follow`, (data) => {console.log(data)}, (error) => {console.log(error)}) + } - return ( - <> - <ReportModal open={reportModalOpen} handleClose={() => handleReportModal(false)} - form="colecao" complainableId={props.id} - complainableType={"Collection"} - /> - <div style={{fontSize: "12px"}}> - <Button aria-controls="simple-menu" aria-haspopup="true" onClick={handleClick} style={{color : "#666"}}> - <MoreVertIcon style={{color : "inherit"}}/> - </Button> - <Menu - id="simple-menu" - anchorEl={anchorEl} - keepMounted - open={Boolean(anchorEl)} - onClose={handleClose} - > - <StyledMenuItem> - <Link to={"/colecao-do-usuario/" + props.id}> - <ListItemIcon><OpenIcon /></ListItemIcon>Abrir - </Link> - </StyledMenuItem> - - <StyledMenuItem onClick={handleUnfollow}> - <ListItemIcon><ErrorIcon /></ListItemIcon>Deixar de Seguir - </StyledMenuItem> - - <StyledMenuItem onClick={() => {handleReportModal(true)}}> - <ListItemIcon><ErrorIcon /></ListItemIcon>Reportar - </StyledMenuItem> - </Menu> - </div> + return ( + <> + <ReportModal + open={reportModalOpen} + handleClose={() => handleReportModal(false)} + form="colecao" + complainableId={props.id} + complainableType={"Collection"} + /> + <div style={{ fontSize: "12px" }}> + <Button + aria-controls="simple-menu" + aria-haspopup="true" + onClick={handleClick} + style={{ color: "#666" }} + > + <MoreVertIcon style={{ color: "inherit" }} /> + </Button> + <Menu + id="simple-menu" + anchorEl={anchorEl} + keepMounted + open={Boolean(anchorEl)} + onClose={handleClose} + > + <StyledMenuItem> + <Link to={"/colecao-do-usuario/" + props.id}> + <ListItemIcon> + <OpenIcon /> + </ListItemIcon> + Abrir + </Link> + </StyledMenuItem> + + <StyledMenuItem + onClick={() => + window.open("/colecao-do-usuario/" + props.id, "_blank") + } + > + <ListItemIcon> + <OpenInBrowserIcon /> + </ListItemIcon> + Abrir em nova guia + </StyledMenuItem> + + <StyledMenuItem onClick={handleUnfollow}> + <ListItemIcon> + <ErrorIcon /> + </ListItemIcon> + Deixar de Seguir + </StyledMenuItem> + + <StyledMenuItem + onClick={() => { + handleReportModal(true); + }} + > + <ListItemIcon> + <ReportProblemIcon /> + </ListItemIcon> + Reportar + </StyledMenuItem> + </Menu> + </div> </> - ) + ); } export const StyledMenuItem = styled(MenuItem)` - color : #666 !important; + color: #666 !important; - .MuiSvgIcon-root { - vertical-align : middle !important; - } - a { - text-decoration : none !important; - color : #666 !important; - } -` + .MuiSvgIcon-root { + vertical-align: middle !important; + } + a { + text-decoration: none !important; + color: #666 !important; + } +`; diff --git a/src/Components/ColaborarModal.js b/src/Components/ColaborarModal.js index cc2e2950c326e7c898f65ea3b8f6d8a40a26a761..f12fa1100e9976ec96e3155a4a0b5be45e485058 100644 --- a/src/Components/ColaborarModal.js +++ b/src/Components/ColaborarModal.js @@ -1,12 +1,12 @@ -import React, {useContext, useState} from 'react'; +import React, {useState} from 'react'; import Modal from '@material-ui/core/Modal'; import Fade from '@material-ui/core/Fade'; import styled from 'styled-components' import { Button } from '@material-ui/core'; import Backdrop from '@material-ui/core/Backdrop'; -import { Store } from '../Store.js'; import CloseIcon from '@material-ui/icons/Close'; import LabeledCheckbox from "../Components/Checkbox.js" +import {Link} from 'react-router-dom' const StyledDivContainer = styled.div` background-color : rgb(255,255,255); @@ -77,7 +77,7 @@ const Styledspan = styled.span` ` export default function ColaborarModal (props) { - const {state, dispatch} = useContext(Store) + // const {state, dispatch} = useContext(Store) const [checkbox, controlCheckbox] = useState(false) const handleCheckbox = () => controlCheckbox(!checkbox) @@ -86,7 +86,6 @@ export default function ColaborarModal (props) { aria-labelledby="transition-modal-title" aria-describedby="transition-modal-description" open={props.open} - centered="true" onClose={props.handleClose} closeAfterTransition @@ -121,9 +120,16 @@ export default function ColaborarModal (props) { na plataforma com toda a comunidade escolar do país. </p> <StyledButtonsDiv> - <StyledButton> - <span style={{color:"#fff"}}>SIM</span> - </StyledButton> + + <Link to={{ + pathname : "/termos-publicar-recurso", + state : true + }}> + <StyledButton> + <span style={{color:"#fff"}}>SIM</span> + </StyledButton> + </Link> + <StyledButton> <span style={{color:"#fff"}}>NÃO</span> </StyledButton> diff --git a/src/Components/CollectionAuthor.js b/src/Components/CollectionAuthor.js new file mode 100644 index 0000000000000000000000000000000000000000..c81f227aadb22527f80b95f72cd226920a63379f --- /dev/null +++ b/src/Components/CollectionAuthor.js @@ -0,0 +1,72 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + +import React from 'react'; +import { Grid } from '@material-ui/core'; +import styled from 'styled-components'; +import { Link } from 'react-router-dom'; +import CircularProgress from '@material-ui/core/CircularProgress'; + + +export default function CollectionAuthor(props) { + return ( + <Grid container + direction="column" + justify="center" + alignItems="center"> + {props.imgsrc ? + <UserLink + to={`/usuario-publico/${props.author_id}`} + > + <UserAvatar src={props.imgsrc}/> + </UserLink> + : + <CircularProgress color="secondary"/> + } + <InfoText>Coleção organizada por:</InfoText> + {props.name ? + <UserLink to={`/usuario-publico/${props.author_id}`} > + <UserName>{props.name}</UserName> + </UserLink> + : + <CircularProgress /> + } + </Grid> + ); +} + +const UserAvatar = styled.img` + border-radius: 75px; + width: 75px; + height: auto; +` +const InfoText = styled.p` + margin-bottom: 0; + padding-bottom: 0; + color: #666; +` +const UserName = styled.h2` + margin-top: 10px; + color: #673ab7; +` +const UserLink = styled(Link)` + text-decoration: none; + &:focus, &:hover, &:visited, &:link, &:active { + text-decoration: none; + } +` diff --git a/src/Components/CollectionCard.js b/src/Components/CollectionCard.js index b6006301eb54fcacc73708254a8ebcaf33c8e928..a252100acd4083d796247c109c3f99da46ddb7e2 100644 --- a/src/Components/CollectionCard.js +++ b/src/Components/CollectionCard.js @@ -26,7 +26,6 @@ import CardActions from '@material-ui/core/CardActions'; import IconButton from '@material-ui/core/IconButton'; import FolderIcon from '@material-ui/icons/Folder'; import FavoriteIcon from '@material-ui/icons/Favorite'; -import StarRatings from 'react-star-ratings'; import noAvatar from "../img/default_profile.png"; import Rating from '@material-ui/lab/Rating'; import StarBorderIcon from '@material-ui/icons/StarBorder'; diff --git a/src/Components/CollectionCardFunction.js b/src/Components/CollectionCardFunction.js index 424c0de04b6d1bb4082a7fc098d6cf3b07834a87..de9bb18ce27f388c031c9bf7e40b104ea61d359f 100644 --- a/src/Components/CollectionCardFunction.js +++ b/src/Components/CollectionCardFunction.js @@ -16,19 +16,15 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useState, useContext} from 'react'; +import React, {useState, useContext, useEffect} from 'react'; import {Store} from '../Store.js' -import Card from '@material-ui/core/Card'; -import {apiDomain, apiUrl} from '../env'; -import Options from './CardOptions' +import {apiDomain} from '../env'; import noAvatar from "../img/default_profile.png"; -import { makeStyles } from '@material-ui/core/styles'; import Button from '@material-ui/core/Button'; import styled from 'styled-components' import Slide from '@material-ui/core/Slide'; import Grid from '@material-ui/core/Grid'; -import {StyledCard, CardDiv, CardReaDiv, Footer, LikeCounter, ButtonNoWidth, EnviadoPor, TagContainer} from './ResourceCardFunction.js' -import CardContent from '@material-ui/core/CardContent'; +import { StyledCard, CardDiv, CardReaDiv, Footer, LikeCounter, ButtonNoWidth, EnviadoPor, TagContainer, HeaderContainer, AvatarDiv } from './ResourceCardFunction.js' import Rating from '@material-ui/lab/Rating'; import StarBorderIcon from '@material-ui/icons/StarBorder'; import FolderIcon from '@material-ui/icons/Folder'; @@ -38,45 +34,129 @@ import CheckIcon from '@material-ui/icons/Check'; import LockIcon from '@material-ui/icons/Lock'; import ColCardOwnerOptions from './ColCardOwnerOptions.js' import ColCardPublicOptions from './ColCardPublicOptions' - -export default function CollectionCardFunction (props) { - const {state} = useContext(Store) - - const [userAvatar, setUserAvatar] = useState(props.avatar ? (`${apiDomain}` + props.avatar) : noAvatar) +import { Link } from 'react-router-dom'; +import {putRequest} from '../Components/HelperFunctions/getAxiosConfig' +import { saveHeaders } from '../Components/HelperFunctions/saveTokens'; +import SignUpModal from './SignUpModal' +import LoginModal from './LoginModal.js' +import Snackbar from '@material-ui/core/Snackbar'; +import MuiAlert from '@material-ui/lab/Alert'; + +export default function CollectionCardFunction(props) { + // console.log(props); + const { state } = useContext(Store) + + // eslint-disable-next-line + const [userAvatar] = useState(props.avatar ? (`${apiDomain}` + props.avatar) : noAvatar) + const [userFollowingCol, toggleUserFollowingCol] = useState(props.followed ? props.followed : false) + const handleToggleUserFollowingCol = () => { toggleUserFollowingCol(!userFollowingCol) } + + const [likesCount, setLikesCount] = useState(props.likeCount) + const [liked, toggleLiked] = useState(props.liked) + + const [signUpOpen, setSignUp] = useState(false) + const [loginOpen, setLogin] = useState(false) + const [successfulLoginOpen, handleSuccessfulLogin] = useState(false) + + + function handleSuccessLike (data) { + toggleLiked(!liked) + setLikesCount(data.count) + } + const handleLike = () => { + putRequest(`/collections/${props.id}/like`, {}, handleSuccessLike, (error) => {console.log(error)}) + } const [followingHover, handleFollowingHover] = useState(false) - const toggleFollowingHover = (value) => {handleFollowingHover(value)} + const toggleFollowingHover = (value) => { handleFollowingHover(value) } const [slideIn, setSlide] = useState(false) - const controlSlide = () => {setSlide(!slideIn)} + const controlSlide = () => { setSlide(!slideIn) } + + function handleSuccessFollow (data) { + handleToggleUserFollowingCol() + } + const handleFollow = () => { + putRequest(`/collections/${props.id}/follow`, {}, handleSuccessFollow, (error) => {console.log(error)}) + } const RenderFollowButton = () => { return ( - <FollowButton onClick={() => {console.log("fazer")}}> - <AddIcon/><span>SEGUIR</span> + <FollowButton onClick={handleFollow}> + <AddIcon /><span>SEGUIR</span> </FollowButton> ) } + useEffect(() => { + // setTimeout(function () { + // if (state.currentUser.id) { + // const config = getAxiosConfig(); + // axios({ + // method: 'get', + // url: `${apiUrl}/users/${state.currentUser.id}/following/Collection`, + // headers: config.headers + // }).then( + // (response) => { + // const data = response.data + // for (let i = 0; i < data.length; i++) + // if (data[i].followable.id === props.id) + // toggleUserFollowingCol(true) + // saveHeaders(response) + // }) + // } + // else { + // toggleLiked(false); + // toggleUserFollowingCol(false); + // } + // }, 1000); + + // setTimeout(function () { + // if (state.currentUser.id) { + // const config = getAxiosConfig(); + // axios({ + // method: 'get', + // url: `${apiUrl}/users/${state.currentUser.id}/collections/liked`, + // headers: config.headers + // }).then( + // (response) => { + // const data = response.data + // for (let i = 0; i < data.length; i++) + // if (data[i].id === props.id) + // toggleLiked(true) + // saveHeaders(response) + // }) + // } + // else { + // toggleLiked(false); + // toggleUserFollowingCol(false); + // } + // }, 2000); + if (!state.currentUser.id) { + toggleLiked(false); + toggleUserFollowingCol(false); + } + }, [state.currentUser.id]) + const RenderFollowingButton = () => { return ( <FollowingButton onMouseOver={() => toggleFollowingHover(true)} - onMouseLeave={() => toggleFollowingHover(false)} onClick={() => {console.log('fazer')}}> + onMouseLeave={() => toggleFollowingHover(false)} onClick={handleFollow}> { followingHover ? - ( - [ - <span>DEIXAR DE SEGUIR</span> - ] - ) - : - ( - [ - <React.Fragment> - <CheckIcon/><span>SEGUINDO</span> - </React.Fragment> - ] - ) + ( + [ + <span>DEIXAR DE SEGUIR</span> + ] + ) + : + ( + [ + <React.Fragment> + <CheckIcon /><span>SEGUINDO</span> + </React.Fragment> + ] + ) } </FollowingButton> ) @@ -85,170 +165,182 @@ export default function CollectionCardFunction (props) { const SlideAnimationContent = () => { return ( <SlideContentDiv> - <div style={{display:"flex", flex:"1"}}>{/*marginBottom:10px*/} - <SlideAvatarDiv> - <img className="img" src={userAvatar} alt="user avatar"/> - </SlideAvatarDiv> - <EnviadoPor> + <HeaderContainer container="row" justify="flex-start" alignItems="center"> + <AvatarDiv item xs={2}> + <img className="img" src={userAvatar} alt="user avatar" /> + </AvatarDiv> + <EnviadoPor item xs={10}> Enviado por: - <br/> + <br /> <p>{props.author}</p> </EnviadoPor> - </div> - { - props.tags && - <TagContainer> - <Grid container spacing={1} justify='safe' style={{height : "inherit"}}> + </HeaderContainer> + <TagContainer container direction="row"> { - props.tags.map( (tag) => + props.tags.map((tag) => <Grid item key={tag.id}> - <span key={tag.id}>{tag.name}</span> + <span >{tag.name}</span> </Grid> ) } - </Grid> </TagContainer> - } </SlideContentDiv> ) } - return ( - <StyledCard> - <CardDiv> - <CardReaDiv> - <Header onMouseEnter={controlSlide} onMouseLeave={controlSlide}> - {/*slide animation and content*/} - <Slide direction="right" in={slideIn} timeout={300}> - <a href="" className="text"> - {SlideAnimationContent()} - </a> - </Slide> - <Slide direction="left" in={!slideIn} timeout={700}> - <a href=""> {/*add links to collection later*/} - - <UserInfo> - <AvatarDiv> - <img src={userAvatar} alt="user avatar"/> - </AvatarDiv> - <UserAndTitle> - <span>{props.author}</span> - <span className={"col-name"}>{props.name}</span> - </UserAndTitle> - </UserInfo> + const handleSignUp = () => { + setSignUp(!signUpOpen) + } + + const handleLogin = () => { + setLogin(!loginOpen) + } + function Alert(props) { + return <MuiAlert elevation={6} variant="filled" {...props} />; + } + + function toggleLoginSnackbar(reason) { + if (reason === 'clickaway') { + return; + } + handleSuccessfulLogin(false); + } + return ( + <> + <SignUpModal open={signUpOpen} handleClose={handleSignUp} openLogin={handleLogin} + /> + <LoginModal open={loginOpen} handleClose={() => setLogin(false)} openSignUp={handleSignUp} + openSnackbar={() => { handleSuccessfulLogin(true) }} + /> + <Snackbar open={successfulLoginOpen} autoHideDuration={1000} onClose={toggleLoginSnackbar} + anchorOrigin={{ vertical: 'top', horizontal: 'center' }} + > + <Alert severity="success" style={{ backgroundColor: "#00acc1" }}>Você está conectado(a)!</Alert> + </Snackbar> + <StyledCard> + <CardDiv> + <CardReaDiv> + <Header onMouseEnter={controlSlide} onMouseLeave={controlSlide}> + <Slide direction="left" in={slideIn} timeout={1000}> + <div className={`slideContentLinkAfterActive${slideIn}`} style={{ width: '100%', height: "100%" }}> + <Link to={"/colecao-do-usuario/" + props.id} className="text" style={{ textDecoration: "none" }} > + {SlideAnimationContent()} + </Link> + </div> + </Slide> + <div className={`slideContentLinkBeforeActive${slideIn}`} style={{ width: '100%', height: '100%' }}> + <UserInfo> + {/* I(Luis) dont know why, but if i use styled components, sometimes the avatar will be deconfigured */} + <img src={userAvatar} alt="user avatar" style={{ + height: "70px", width: "70px", borderRadius: "50%", + zIndex: 1, border: "2px solid white", + boxShadow: "0 1px 3px rgba(0,0,0,.45)" + + }} /> + <UserAndTitle> + <span>{props.author}</span> + <span className={"col-name"}>{props.name}</span> + </UserAndTitle> + </UserInfo> <StyledGrid container direction="row"> { - props.thumbnails.map( (thumb) => - <Grid item xs={props.thumbnails <= 4 && props.thumbnails > 0 ? 12/props.thumbnails.length : 6}> - <div style={{backgroundImage : `url(${ `${apiDomain}` + thumb})`, height : "100%", width : "100%", backgroundSize : "cover", backgroundPosition : "center"}}/> + props.thumbnails.map((thumb) => + <Grid item xs={props.thumbnails <= 4 && props.thumbnails > 0 ? 12 / props.thumbnails.length : 6}> + <div style={{ backgroundImage: `url(${`${apiDomain}` + thumb})`, height: "100%", width: "100%", backgroundSize: "cover", backgroundPosition: "center" }} /> </Grid> ) } </StyledGrid> - </a> - </Slide> - </Header> - - <Description> {/*renders rating, number of learning objects and likes count*/} - { - props.authorID !== state.currentUser.id && - <Rating - name="customized-empty" - value={props.rating*10} - precision={0.5} - style={{color:"#666"}} - emptyIcon={<StarBorderIcon fontSize="inherit" />} - /> - } - - <Footer> - <Type> - <FolderIcon /> - <span style={{fontWeight:"bold"}}>{props.thumbnails.length} </span> - <span>{props.thumbnails.length != 1 ? "Recursos" : "Recurso"}</span> - </Type> - <LikeCounter> - <span>{props.likeCount}</span> - <ButtonNoWidth> - <FavoriteIcon style={{color : props.liked ? "red" : "#666" }}/> - </ButtonNoWidth> - </LikeCounter> - </Footer> - </Description> - - </CardReaDiv> + </div> + </Header> + + <Description> {/*renders rating, number of learning objects and likes count*/} + { + props.authorID !== state.currentUser.id && + <Rating + name="customized-empty" + value={props.rating} + readOnly + style={{ color: "#666" }} + emptyIcon={<StarBorderIcon fontSize="inherit" />} + /> + } + + <Footer> + <Type> + <FolderIcon /> + <span style={{ fontWeight: "bold" }}>{props.collections.length} </span> + <span>{props.collections.length !== 1 ? "Recursos" : "Recurso"}</span> + </Type> + <LikeCounter> + <span>{likesCount}</span> + <ButtonNoWidth onClick={handleLike}> + <FavoriteIcon style={{ color: liked ? "red" : "#666" }} /> + </ButtonNoWidth> + </LikeCounter> + </Footer> + </Description> + + </CardReaDiv> - { - props.authorID === state.currentUser.id ? - ( - <CardReaFooter style={{justifyContent : "space-between"}}> {/*renders following/unfollow and follow button*/} - <Grid container> - <Grid item xs={6} style={{display : "flex", justifyContent : "center"}}> - { - props.privacy === 'private' && - <LockIcon style={{color : "#666"}}/> - } - </Grid> - <Grid item xs={6} style={{display : "flex", justifyContent : "flex-end"}}> - <ColCardOwnerOptions - id={props.id} - /> - </Grid> - </Grid> - </CardReaFooter> - ) - : - ( - <CardReaFooter> {/*renders following/unfollow and follow button*/} - { - props.followed ? + { + props.authorID === state.currentUser.id ? ( - [ - RenderFollowingButton() - ] + <CardReaFooter style={{ justifyContent: "space-between" }}> {/*renders following/unfollow and follow button*/} + <Grid container> + <Grid item xs={6} style={{ display: "flex", justifyContent: "center" }}> + { + props.privacy === 'private' && + <LockIcon style={{ color: "#666" }} /> + } + </Grid> + <Grid item xs={6} style={{ display: "flex", justifyContent: "flex-end" }}> + <ColCardOwnerOptions + id={props.id} + /> + </Grid> + </Grid> + </CardReaFooter> ) : ( - [ - RenderFollowButton() - ] + <CardReaFooter> {/*renders following/unfollow and follow button*/} + { + userFollowingCol ? + ( + [ + RenderFollowingButton() + ] + ) + : + ( + [ + RenderFollowButton() + ] + ) + } + <ColCardPublicOptions + id={props.id} + /> + </CardReaFooter> ) - } - <ColCardPublicOptions - id={props.id} - /> - </CardReaFooter> - ) - } + } - </CardDiv> - </StyledCard> + </CardDiv> + </StyledCard> + </> ) } -const SlideAvatarDiv = styled.div` - vertical-align : middle; - border : 0; - img { - height : 40px; - width : 40px; - border : 0; - vertical-align : middle; - border-radius : 50%; - } -` const SlideContentDiv = styled.div` background-color : #7e57c2; padding : 10px; width : 100%; height : 100%; - position : absolute; - display : flex; - flex-direction : column; ` const UserAndTitle = styled.div` @@ -279,19 +371,19 @@ const UserAndTitle = styled.div` } ` -const AvatarDiv = styled.div` - z-index : 5; - overflow : hidden; - - img { - border-radius : 50%; - height : 70px; - width : 70px; - border : 2px solid #fff; - background-color : #fff; - box-shadow : 0 1px 3px rgba(0,0,0,.45); - } -` +// const AvatarDiv = styled.div` +// z-index : 5; +// overflow : hidden; + +// img { +// border-radius : 50%; +// height : 70px; +// width : 70px; +// border : 2px solid #fff !important; +// background-color : #fff; +// box-shadow : 0 1px 3px rgba(0,0,0,.45); +// } +// ` const UserInfo = styled.div` position : absolute; diff --git a/src/Components/CollectionCommentSection.js b/src/Components/CollectionCommentSection.js new file mode 100644 index 0000000000000000000000000000000000000000..ccc7f079dae76494734addd6116bdaf6a331ae5d --- /dev/null +++ b/src/Components/CollectionCommentSection.js @@ -0,0 +1,166 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + +import React, { useRef, useState, useEffect } from 'react'; +import { Grid } from '@material-ui/core'; +import Card from '@material-ui/core/Card'; +import Button from '@material-ui/core/Button'; +import EditIcon from '@material-ui/icons/Edit'; +import styled from 'styled-components'; +import CommentForm from './ResourcePageComponents/CommentForm.js'; +import Comment from './Comment.js'; +import Snackbar from '@material-ui/core/Snackbar'; +import MuiAlert from '@material-ui/lab/Alert'; +import Comentario from '../img/comentarios.png'; +import {getRequest} from '../Components/HelperFunctions/getAxiosConfig' + +export default function CollectionCommentSection(props) { + const [post_snack_open, setPostSnackOpen] = useState(false); + const [delete_snack_open, setDeleteSnackOpen] = useState(false); + const [render_state, setRenderState] = useState(false); + const [reviews, setReviews] = useState([]); + const comment_ref = useRef(null); + + const forceUpdate = () => { setRenderState(!render_state); } + + const handlePostSnackbar = () => { + setPostSnackOpen(!post_snack_open); + } + + const handleDeleteSnackbar = () => { + setDeleteSnackOpen(!delete_snack_open); + } + + const handleScrollToCommentForm = () => { + window.scrollTo(0, comment_ref.current.offsetTop); + } + + function Alert(props) { + return <MuiAlert elevation={6} variant="filled" {...props} />; + } + + const NoCommentsMessage = () => { + const NoCommentsContainer=styled.div` + text-align: center; + margin-left: 9vw; + margin-right: 9vw; + ` + const BlueTitle=styled.h2` + color: #673ab7; + ` + const Secondary=styled.h3` + font-weight: 100; + ` + const ButtonText=styled.span` + font-weight: 900; + ` + const Image=styled.img` + ` + return ( + <NoCommentsContainer> + <Image src={Comentario} style={{width:"100%", maxWidth:234}}/> + <BlueTitle>Compartilhe sua opinião com a rede!</BlueTitle> + <Secondary>Gostou desta coleção? Comente e compartilhe com a rede sua opinião. Interagindo com a rede, você contribui para que mais coleções como esta sejam criadas.</Secondary> + <Button + variant="contained" + color="primary" + startIcon={<EditIcon />} + onClick={handleScrollToCommentForm} + > + <ButtonText>Relatar experiência</ButtonText> + </Button> + </NoCommentsContainer> + ); + } + const CollectionComments = () => { + return ( + <div> + <Title>{reviews.length} {reviews.length === 1 ? "Relato" : "Relatos"} sobre a Coleção</Title> + {reviews.map(r => { + return ( + <Comment + rerenderCallback={forceUpdate} + objectID={props.id} + reviewID={r.id} + reviewRatings={r.review_ratings} + authorID={r.user.id} + rating={r.rating_average} + authorName={r.user.name} + authorAvatar={r.user.avatar} + description={r.description} + createdAt={r.created_at} + handleSnackbar={handleDeleteSnackbar} + recurso={false} + /> + );})} + </div> + ); + } + + useEffect(() => { + getRequest(`/collections/${props.id}/reviews`, (data) => {setReviews(data)}, (error) => {console.log(error)}) + }, [render_state]); + + return ( + <CommentAreaContainer container xs={12} direction="row" justify="center" alignItems="center"> + <Grid item xs={12} ref={comment_ref}> + <CommentAreaCard> + <Title>Conte sua experiência com a coleção</Title> + <CommentForm colecao recursoId={props.id} + handleSnackbar={handlePostSnackbar} + rerenderCallback={forceUpdate} + /> + {reviews.length ? CollectionComments() : NoCommentsMessage()} + </CommentAreaCard> + </Grid> + <Snackbar + open={post_snack_open} + autoHideDuration={6000} + onClose={handlePostSnackbar} + anchorOrigin={{vertical: 'top', horizontal: 'right'}} + > + <Alert onClose={handlePostSnackbar} severity="info"> + Seu comentário foi publicado com sucesso! + </Alert> + </Snackbar> + <Snackbar + open={delete_snack_open} + autoHideDuration={6000} + onClose={handleDeleteSnackbar} + anchorOrigin={{vertical: 'top', horizontal: 'right'}} + > + <Alert onClose={handleDeleteSnackbar} severity="info"> + Comentário deletado com sucesso. + </Alert> + </Snackbar> + </CommentAreaContainer> + ); +} + + +const CommentAreaContainer=styled(Grid)` + margin-left: 10%; + margin-right: 10%; +` +const CommentAreaCard=styled(Card)` + padding: 45px; +` +const Title=styled.h1` + font-weight: 100; + color: #666; +` diff --git a/src/Components/CollectionDescription.js b/src/Components/CollectionDescription.js new file mode 100644 index 0000000000000000000000000000000000000000..aa35cb0df4909fa3205678aa145bc1e02f2802ad --- /dev/null +++ b/src/Components/CollectionDescription.js @@ -0,0 +1,92 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + +import React, { useState, useEffect } from 'react'; +import axios from 'axios'; +import { Grid } from '@material-ui/core'; +import styled from 'styled-components'; +import CollectionReview from './CollectionReview.js'; +import { apiUrl, apiDomain } from '../env'; + +export default function CollectionDescription(props) { + // eslint-disable-next-line + const [download_url, setDownloadUrl] = useState(''); + + useEffect(() => { + const body = { + "package": { + "object": [{"type": "Collection", "id": props.collection_id}] + }}; + axios + .post(apiUrl+'/package', body) + .catch(err => { + if (err.response && err.response.status === 302) { + setDownloadUrl(apiDomain+'/'+err.response.data.url); + } + });}, [props.collection_id]); + + return ( + <Grid container direction="column" justify="center" alignItems="center" spacing={5}> + <Grid + item + justify="center" + alignItems="center" + > + <Title>{props.title}</Title> + </Grid> + <Grid + item + direction="row" + justify="center" + alignItems="center" + > + <Grid item> + <CollectionReview + scrollToComment={props.scrollToComments} + id={props.collection_id}/> + </Grid> + {/* <Grid item container sm={8} + direction="column" justify="center" alignItems="flex-end" + > + <Grid item style={{marginBottom: 10}}> + <DownloadAnchor href={download_url} > + <DownloadButton + variant="outlined" + color="primary" + startIcon={<GetAppIcon fontSize="large"/>} + size="large" + > + <ButtonText>Baixar Coleção</ButtonText> + </DownloadButton> + </DownloadAnchor> + </Grid> + <Grid item> + <FollowCollectionButton user_id={state.currentUser.id} collection_id={props.collection_id}/> + </Grid> + </Grid> */} + </Grid> + + </Grid> + ); +} + +const Title=styled.h1` + font-size: 2.5em; + color: rgb(102, 102, 102); + text-align: center +` \ No newline at end of file diff --git a/src/Components/CollectionDowloadButton.js b/src/Components/CollectionDowloadButton.js new file mode 100644 index 0000000000000000000000000000000000000000..f36eed118e3771b92e2117883d5dd8977cefd91f --- /dev/null +++ b/src/Components/CollectionDowloadButton.js @@ -0,0 +1,55 @@ +import React, { useState, useEffect } from 'react'; +import axios from 'axios'; +import GetAppIcon from '@material-ui/icons/GetApp'; +import Button from '@material-ui/core/Button'; +import styled from 'styled-components'; +import { apiUrl, apiDomain } from '../env'; + + +const DowloadButton = (props) => { + const [download_url, setDownloadUrl] = useState(''); + + useEffect(() => { + const body = { + "package": { + "object": [{ "type": "Collection", "id": props.id }] + } + }; + axios + .post(apiUrl + '/package', body) + .catch(err => { + if (err.response && err.response.status === 302) { + setDownloadUrl(apiDomain + '/' + err.response.data.url); + } + }); + }, [props.id]); + return ( + <> + <DownloadAnchor href={download_url} > + <DownloadButton + variant="outlined" + color="primary" + startIcon={<GetAppIcon fontSize="large" />} + size="small" + > + <ButtonText>Baixar Coleção</ButtonText> + </DownloadButton> + </DownloadAnchor> + </> + ) +} + +const ButtonText = styled.span` + font-weight: bolder; + font-size: 1.2em; +` +const DownloadButton = styled(Button)` + padding-left: 10; + padding-right: 10; + width: 250px; +` +const DownloadAnchor = styled.a` + text-decoration: none !important; +` + +export default DowloadButton; diff --git a/src/Components/CollectionReview.js b/src/Components/CollectionReview.js new file mode 100644 index 0000000000000000000000000000000000000000..10cc202c3ff6f3908aeb09c7d0d4fb567505fddb --- /dev/null +++ b/src/Components/CollectionReview.js @@ -0,0 +1,124 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + +import React, { useContext, useState, useEffect } from 'react'; +import { Grid } from '@material-ui/core'; +import Rating from '@material-ui/lab/Rating'; +import IconButton from '@material-ui/core/IconButton'; +import StarBorderIcon from '@material-ui/icons/StarBorder'; +import FavoriteIcon from '@material-ui/icons/Favorite'; +import InfoIcon from '@material-ui/icons/Info'; +import { Store } from '../Store.js' +import ReportModal from './ReportModal.js'; +import SignUpModal from './SignUpModal.js'; +import LoginModal from './LoginModal.js'; +import {putRequest, getRequest} from './HelperFunctions/getAxiosConfig.js' + +export default function CollectionReview(props) { + const [likes, setLikes] = useState(0); + const [liked, setLiked] = useState(false); + const [stars, setStars] = useState(0); + const [reportOpen, setReportOpen] = useState(false); + const [sign_up_open, setSignUpOpen] = useState(false); + const [log_in_open, setLoginOpen] = useState(false); + const { state } = useContext(Store); + + function handleSuccessfulGet (data) { + setLikes(Number(data.likes_count)); + setLiked(data.liked); + } + + useEffect(() => { + const url = `/collections/${props.id}` + + getRequest(url, handleSuccessfulGet, (error) => {console.log(error)}) + + }, [props.id]); + + const handleClickReport = () => { + setReportOpen(true); + } + + function handleSuccess (data) { + setLiked(!liked) + setLikes(data.count) + } + + const handleLikeClick = () => { + if (state.currentUser.id) { + const url = `/collections/${props.id}/like` + putRequest(url, {}, handleSuccess, (error) => {console.log(error)}) + } else + setSignUpOpen(true); + } + + const handleSetStars = (value) => { + setStars(value); + props.scrollToComment(); + } + + const handleCloseModal = () => { + setReportOpen(false); + } + + return ( + <Grid container direction="column"> + <Grid sm={12} container direction="row" alignItems="center"> + <Grid item> + <Rating + name="customized-empty" + value={stars} + onChange={(e, value) => handleSetStars(value)} + precision={0.5} + style={{ color: "#666" }} + emptyIcon={<StarBorderIcon fontSize="inherit" />} + /> + </Grid> + <Grid item justify="center" alignItems="center"> + <IconButton aria-label="like" onClick={handleLikeClick}> + {likes}<FavoriteIcon style={{fill : liked ? "red" : null}} /> + </IconButton> + </Grid> + </Grid> + <Grid item sm={12}> + <IconButton + aria-label="report" + style={{ fontSize: 'small' }} + onClick={handleClickReport}> + <InfoIcon />Reportar erro ou abuso + </IconButton> + <ReportModal + open={reportOpen} + handleClose={handleCloseModal} + form="colecao" + complainableId={props.id} + complainableType="Collection" + /> + </Grid> + <SignUpModal + open={sign_up_open} + handleClose={() => setSignUpOpen(false)} + openLogin={() => setLoginOpen(true)} + /> + <LoginModal + open={log_in_open} + handleClose={() => setLoginOpen(false)} + /> + </Grid> + ); +} diff --git a/src/Components/Coment.js b/src/Components/Coment.js deleted file mode 100644 index f76cbf7fc21d321d7ce4155f57d4580f00190c75..0000000000000000000000000000000000000000 --- a/src/Components/Coment.js +++ /dev/null @@ -1,27 +0,0 @@ -import React, {Component} from 'react'; -import CardContent from '@material-ui/core/CardContent'; -import Typography from '@material-ui/core/Typography'; -import StarRatings from 'react-star-ratings'; - - -class Coment extends Component { - constructor(props) { - super(props); - - } -render(){ - return( - <CardContent> - <StarRatings - rating={2} - starRatedColor="ff7f00" - starDimension="20px" - starSpacing="2px" - /> - <Typography component="p" varitant="srOnly" style={{color: "orange"}}> {this.props.author}:{this.props.coment}</Typography> - </CardContent> - ); -} - -} -export default Coment; diff --git a/src/Components/Comment.js b/src/Components/Comment.js index 5c797282aeccccb928ede08e34d1c0e207830e3e..09b66d5ad2f83e4ad3f10994de899960ca4f1b49 100644 --- a/src/Components/Comment.js +++ b/src/Components/Comment.js @@ -16,7 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useState, useContext, useEffect} from 'react' +import React, {useState, useContext} from 'react' import {Store} from '../Store.js' import styled from 'styled-components' import Grid from '@material-ui/core/Grid'; @@ -28,11 +28,10 @@ import Rating from '@material-ui/lab/Rating'; import StarBorderIcon from '@material-ui/icons/StarBorder'; import EditIcon from '@material-ui/icons/Edit'; import TextField from "@material-ui/core/TextField"; -import axios from 'axios' -import {apiUrl} from '../env'; import Menu from '@material-ui/core/Menu'; import MenuItem from '@material-ui/core/MenuItem'; import ModalExcluir from './ModalExcluirComentario.js' +import {putRequest, deleteRequest} from './HelperFunctions/getAxiosConfig' export default function Comment (props) { @@ -75,18 +74,16 @@ export default function Comment (props) { setComment({...comment, error : flag, value : userInput}) } + function handleOnSuccessfulComment (data) { + setDisplayedComment(comment.value) + setEditando(false) + props.handleSnackbar(2) + } + const updateComment = () => { const finalComment = comment if (!finalComment.error) { - let config = { - headers : { - 'Accept': 'application/json', - 'Content-Type': 'application/json', - 'Access-Token': sessionStorage.getItem('@portalmec/accessToken'), - 'Client': sessionStorage.getItem('@portalmec/clientToken'), - 'Uid': sessionStorage.getItem('@portalmec/uid'), - } - } + let payload = { "review" : { "name":null, @@ -96,35 +93,19 @@ export default function Comment (props) { "review_ratings_attributes" : props.reviewRatings } } + putRequest(`/learning_objects/${props.objectID}/reviews/`, payload, handleOnSuccessfulComment, (error) => {console.log(error)}) - axios.put( (`${apiUrl}/learning_objects/` + props.objectID + '/reviews/' + props.reviewID),payload, config - ).then((response) => { - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - console.log(response) - setDisplayedComment(finalComment.value) - setEditando(false) - props.handleSnackbar(2) - }, (error) => {console.log(error)}) } } + function handleSuccessDeleteComment (data) { + props.rerenderCallback() + props.handleSnackbar(3) + } + const deleteComment = () => { - let config = { - headers : { - 'Accept': 'application/json', - 'Content-Type': 'application/json', - 'Access-Token': sessionStorage.getItem('@portalmec/accessToken'), - 'Client': sessionStorage.getItem('@portalmec/clientToken'), - 'Uid': sessionStorage.getItem('@portalmec/uid'), - } - } - axios.delete( (`${apiUrl}/learning_objects/` + props.objectID + '/reviews/' + props.reviewID), config).then((response) => { - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - props.rerenderCallback(); props.handleSnackbar(3)}, (error) => {console.log(error)}) + + deleteRequest(`/learning_objects/${props.objectID}/reviews/${props.reviewID}`, handleSuccessDeleteComment, (error) => {console.log(error)}) toggleModal(false) diff --git a/src/Components/ContactButtons/FollowButton.js b/src/Components/ContactButtons/FollowButton.js index 09362df143e866e793127eec5d6394c62acbdbf9..5594fa6619ba288e50f997c8f449039a0f0b828b 100644 --- a/src/Components/ContactButtons/FollowButton.js +++ b/src/Components/ContactButtons/FollowButton.js @@ -16,36 +16,23 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useState} from 'react' +import React from 'react' import PersonAddIcon from '@material-ui/icons/PersonAdd'; import styled from 'styled-components' import Button from '@material-ui/core/Button'; -import axios from 'axios' -import {apiUrl} from '../../env'; -import {getAxiosConfig} from '../HelperFunctions/getAxiosConfig' +import {putRequest} from '../HelperFunctions/getAxiosConfig' export default function FollowButton (props) { - const handleFollow = (followerID) => { - const id = followerID - console.log('id: ', id) - - let payload = {} - const header = getAxiosConfig() - - axios.put((`${apiUrl}/users/` + id + '/follow'), payload, header).then( - (response) => { - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - console.log(response) - props.toggleFollowed() - }, - (error) => { - console.log(error) - } - ) + function handleSuccess (data) { + props.toggleFollowed() + } + const handleFollow = (followerID) => { + if (followerID !== undefined) { + const url = `/users/${followerID}/follow/` + putRequest(url, {}, handleSuccess, (error) => {console.log(error)}) + } } return ( @@ -62,24 +49,9 @@ export default function FollowButton (props) { export function NoIcon (props) { const handleFollow = (followerID) => { - const id = followerID - console.log('id: ', id) - - if (id != undefined) { - let payload = {} - const header = getAxiosConfig() - - axios.put((`${apiUrl}/users/` + id + '/follow'), payload, header).then( - (response) => { - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - console.log(response) - }, - (error) => { - console.log(error) - } - ) + if (followerID !== undefined) { + const url = `/users/${followerID}/follow/` + putRequest(url, {}, (data) => {console.log(data)}, (error) => {console.log(error)}) } } diff --git a/src/Components/ContactButtons/FollowingButton.js b/src/Components/ContactButtons/FollowingButton.js index 6fa7464a760885e617f37a1028aafc496b2b2610..b2d22f248597fa5fd15f9289f7ea538ec2a8b2b5 100644 --- a/src/Components/ContactButtons/FollowingButton.js +++ b/src/Components/ContactButtons/FollowingButton.js @@ -21,9 +21,7 @@ import styled from 'styled-components' import Button from '@material-ui/core/Button'; import FollowingIcon from '../../img/how_to_reg-24px.png' import ModalConfirmarUnfollow from '../ModalConfirmarUnfollow.js' -import axios from 'axios' -import {apiUrl} from '../../env'; -import {getAxiosConfig} from '../HelperFunctions/getAxiosConfig' +import {putRequest} from '../HelperFunctions/getAxiosConfig' export default function FollowingButton (props) { @@ -38,26 +36,15 @@ export default function FollowingButton (props) { toggleModal(true) } - const handleUnfollowPartTwo = () => { - const id = unfollowID - console.log('id: ', id) - let payload = {} - const header = getAxiosConfig() + function handleSuccess (data) { + props.toggleFollowed() + toggleModal(false) + } + const handleUnfollowPartTwo = () => { + const url = `/users/${unfollowID}/follow/` - axios.put((`${apiUrl}/users/` + id + '/follow'), payload, header).then( - (response) => { - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - console.log(response) - props.toggleFollowed() - toggleModal(false) - }, - (error) => { - console.log(error) - } - ) + putRequest(url, {}, handleSuccess, (error) => {console.log(error)}) } return ( diff --git a/src/Components/ContactCard.js b/src/Components/ContactCard.js index 83ce16ab91084f1761c0395ba4a9d16f66b232b6..b5719d71e54a6eeb2ebaa30844b0a8e1ac6b10f3 100644 --- a/src/Components/ContactCard.js +++ b/src/Components/ContactCard.js @@ -16,38 +16,20 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useState, useEffect, useContext} from 'react'; -import {Container} from 'react-grid-system'; +import React, {useState} from 'react'; import Card from '@material-ui/core/Card'; import CardContent from '@material-ui/core/CardContent'; -import CardActionArea from '@material-ui/core/CardActionArea'; -import CardActions from '@material-ui/core/CardActions'; -import {apiDomain} from '../env'; -import { Store } from '../Store.js'; import noAvatar from "../img/default_profile.png"; -import { makeStyles } from '@material-ui/core/styles'; import CardMedia from '@material-ui/core/CardMedia'; -import Button from '@material-ui/core/Button'; -import Typography from '@material-ui/core/Typography'; import styled from 'styled-components' -import axios from 'axios' -import {apiUrl} from '../env'; import Options from './ContactCardOptions.js' import FollowButton from './ContactButtons/FollowButton.js' import FollowingButton from './ContactButtons/FollowingButton.js' import FollowersCountButton from './ContactButtons/FollowersCountButton.js' import {Link} from 'react-router-dom'; -const useStyles = makeStyles({ - root: { - maxWidth: 345, - borderRadius : 0 - }, -}); export default function ImgMediaCard(props) { - const classes = useStyles(); - const {state} = useContext(Store) const [followedBoolean, setFollowedBoolean] = useState(props.followed) const toggleFollowed = () => {setFollowedBoolean(!followedBoolean)} @@ -81,7 +63,7 @@ export default function ImgMediaCard(props) { <Link to={props.href}> <span style={{fontSize : "14px", fontWeight : "normal"}}> - <b>{props.numCollections}</b> {props.numCollections != 1? "Coleções" : "Coleção"} | <b>{props.numLearningObjects}</b> {props.numLearningObjects != 1? "Recursos" : "Recurso"} + <b>{props.numCollections}</b> {props.numCollections !== 1? "Coleções" : "Coleção"} | <b>{props.numLearningObjects}</b> {props.numLearningObjects !== 1? "Recursos" : "Recurso"} </span> </Link> @@ -89,18 +71,32 @@ export default function ImgMediaCard(props) { { followedBoolean ? ( - [ - <FollowingButton followedID={props.followerID} toggleFollowed={toggleFollowed}/> - ] + <React.Fragment> + <FollowingButton + followedID={props.followerID ? props.followerID : props.followedID} + toggleFollowed={toggleFollowed}/> + + <Options + followableID={props.followerID ? props.followerID : props.followedID} + followed={followedBoolean} + toggleFollowed={toggleFollowed}/> + </React.Fragment> ) : ( - [ - <FollowButton followerID={props.followerID} toggleFollowed={toggleFollowed}/> - ] + <React.Fragment> + <FollowButton + followerID={props.followedID ? props.followedID : props.followerID} + toggleFollowed={toggleFollowed}/> + + <Options + followableID={props.followedID ? props.followedID : props.followerID} + followed={followedBoolean} + toggleFollowed={toggleFollowed}/> + </React.Fragment> ) } - <Options followableID={props.followerID} followed={followedBoolean}/> + </div> </UserInfo> </CardContent> diff --git a/src/Components/ContactCardOptions.js b/src/Components/ContactCardOptions.js index 7cccf882fd8c034fd113d80dee2f2ecc7528b0e1..deb12ba4e7a9c4a68785e59986ed3b85d3a05065 100644 --- a/src/Components/ContactCardOptions.js +++ b/src/Components/ContactCardOptions.js @@ -16,8 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useContext, useState} from 'react'; -import {Store} from '../Store.js' +import React, {useState} from 'react'; import styled from 'styled-components' import Button from '@material-ui/core/Button'; import Menu from '@material-ui/core/Menu'; @@ -27,14 +26,12 @@ import MoreVertIcon from '@material-ui/icons/MoreVert'; import OpenIcon from '@material-ui/icons/OpenInNew'; import ReportIcon from '@material-ui/icons/Error'; import PersonAddIcon from '@material-ui/icons/PersonAdd'; -import axios from 'axios' -import {apiUrl} from '../env'; -import {getAxiosConfig} from './HelperFunctions/getAxiosConfig' +import {putRequest} from './HelperFunctions/getAxiosConfig' import ReportModal from './ReportModal.js' import {Link} from 'react-router-dom' export default function SimpleMenu(props) { - const {state} = useContext(Store) + // const {state} = useContext(Store) const [anchorEl, setAnchorEl] = React.useState(null); function handleClick(event) { @@ -44,34 +41,20 @@ export default function SimpleMenu(props) { function handleClose() { setAnchorEl(null); } + const handleFollow = (followerID) => { - const id = followerID - console.log('id: ', id) - - let payload = {} - const header = getAxiosConfig() - axios.put((`${apiUrl}/users/` + id + '/follow'), payload, header).then( - (response) => { - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - console.log(response) - }, - (error) => { - console.log(error) - } - ) + + putRequest(`/users/${followerID}/follow`, {}, (data) => { + console.log(data); + props.toggleFollowed() + }, (error) => {console.log(error)}) + + handleClose(); } const [reportModal, toggleReportModal] = useState(false) const handleModal = (value) => { toggleReportModal(value) - {/*if (state.currentUser.id) { - toggleReportModal(!reportModal) - } - else { - toggleLoginModal(true) - }*/} } return ( @@ -103,13 +86,13 @@ export default function SimpleMenu(props) { { props.followed ? ( - <StyledMenuItem onClick={() => {handleFollow(props.followableID);handleClose()}}> + <StyledMenuItem onClick={() => {handleFollow(props.followableID)}}> <ListItemIcon><ReportIcon /></ListItemIcon>Deixar de Seguir </StyledMenuItem> ) : ( - <StyledMenuItem onClick={() => {handleFollow(props.followableID);handleClose()}}> + <StyledMenuItem onClick={() => {handleFollow(props.followableID)}}> <ListItemIcon><PersonAddIcon /></ListItemIcon>Seguir </StyledMenuItem> ) diff --git a/src/Components/ContactForm.js b/src/Components/ContactForm.js index e5cc2981d7e31e78fc002e5bf9943672b0a1e15c..971001ebc2f52aad912ac0d9deb1791aafd68396 100644 --- a/src/Components/ContactForm.js +++ b/src/Components/ContactForm.js @@ -16,14 +16,10 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { Component, useState, useEffect } from 'react'; +import React, { useState } from 'react'; import styled from 'styled-components'; import FormInput from "../Components/FormInput.js" -import axios from 'axios' -import {apiUrl} from '../env'; - - - +import {postRequest} from './HelperFunctions/getAxiosConfig' const Button = styled.button` @@ -187,27 +183,16 @@ const Button = styled.button` console.log(!(nome.dict.key && email.dict.key && mensagem.dict.key )) // Se não houver erro em nunhum dos campos E nenhum dos campos for vazio: a página faz o contato com o backend e os campos ficam em branco no formulário if (!(nome.dict.key || email.dict.key || mensagem.dict.key )) { - - axios.post(`${apiUrl}/contacts`, - { + let payload = { contact : { - name: nome.dict.value, - email: email.dict.value, - message: mensagem.dict.value + name: nome.dict.value, + email: email.dict.value, + message: mensagem.dict.value } - - } - ).then() - - - - limpaTudo(); - - } - - - + } + postRequest(`/contacts`, payload, (data) => {limpaTudo()}, (error) => {console.log(error)}) } +} diff --git a/src/Components/CriarColecaoForm.js b/src/Components/CriarColecaoForm.js index 83560d9173fa7db7b68174553865c12e4fd6ae8c..ea8c05070f21519b8594a13c03897d69481b2556 100644 --- a/src/Components/CriarColecaoForm.js +++ b/src/Components/CriarColecaoForm.js @@ -16,7 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useState, useContext} from 'react' +import React, {useContext} from 'react' import {Store} from '../Store.js' import { Button } from '@material-ui/core'; import styled from 'styled-components' @@ -25,8 +25,7 @@ import RadioGroup from '@material-ui/core/RadioGroup'; import FormControlLabel from '@material-ui/core/FormControlLabel'; import FormControl from '@material-ui/core/FormControl'; import TextField from '@material-ui/core/TextField'; -import axios from 'axios' -import {apiUrl} from '../env'; +import {postRequest} from './HelperFunctions/getAxiosConfig' export default function CriarColecaoForm (props) { const {state} = useContext(Store) @@ -51,7 +50,7 @@ export default function CriarColecaoForm (props) { const handleColName = (e) => { const userInput = e.target.value - const flag = userInput.length == 0 ? true : false + const flag = userInput.length === 0 ? true : false setColName({...colName, key : flag, @@ -59,14 +58,16 @@ export default function CriarColecaoForm (props) { }) } + function handleSuccess (data) { + props.finalize(data.id) + } const formSubmit = (e) => { e.preventDefault() - {/*if user didn't select either one, default to privada*/} + // {/*if user didn't select either one, default to privada*/} const finalRadioValue = value === 'pública' ? 'public' : 'private' const finalColName = colName - console.log(finalRadioValue, finalColName.value) if(!(finalColName.key)) { let payload = { "collection" : { @@ -76,25 +77,8 @@ export default function CriarColecaoForm (props) { "privacy" : finalRadioValue } } - let config = { - headers : { - 'Accept': 'application/json', - 'Content-Type': 'application/json', - 'Access-Token': sessionStorage.getItem('@portalmec/accessToken'), - 'Client': sessionStorage.getItem('@portalmec/clientToken'), - 'Uid': sessionStorage.getItem('@portalmec/uid') - } - } + postRequest( `/collections/`, payload, handleSuccess, (error) =>{console.log(error)}) - axios.post( (`${apiUrl}/collections/`), payload, config - ).then( - (response) => { - console.log(response) - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - props.finalize(response.data.id) - }, (error) =>{console.log(error)}) } } diff --git a/src/Components/CriarColecaoModal.js b/src/Components/CriarColecaoModal.js index 9b04f2dd04da1c6e3a71a5cb26a0839da1470ce4..73e7384fc040f415e947113c26b9ff56544f3d7f 100644 --- a/src/Components/CriarColecaoModal.js +++ b/src/Components/CriarColecaoModal.js @@ -16,7 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useState} from 'react' +import React from 'react' import { Button } from '@material-ui/core'; import Modal from '@material-ui/core/Modal'; import Backdrop from '@material-ui/core/Backdrop'; diff --git a/src/Components/Cropper.js b/src/Components/Cropper.js index 28f09d420519098dec292a9818e7af032d595d80..ccccc4c2e57ca23d7b7de6500c630cf052a0a847 100644 --- a/src/Components/Cropper.js +++ b/src/Components/Cropper.js @@ -16,7 +16,6 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import ReactDOM from 'react-dom'; import React, { PureComponent } from 'react'; import ReactCrop from 'react-image-crop'; import 'react-image-crop/dist/ReactCrop.css'; @@ -46,6 +45,7 @@ export default class Cropper extends PureComponent { async makeClientCrop(crop) { if (this.imageRef && crop.width && crop.height) { + // eslint-disable-next-line const croppedImageUrl = await this.getCroppedImg( this.imageRef, crop, @@ -81,7 +81,7 @@ export default class Cropper extends PureComponent { canvas.toBlob(blob => { reader.readAsDataURL(blob) reader.onloadend = () => { - {/*this.dataURLtoFile(reader.result, 'cropped.jpg')*/} + // {/*this.dataURLtoFile(reader.result, 'cropped.jpg')*/} this.props.update(reader.result) } }) @@ -89,6 +89,7 @@ export default class Cropper extends PureComponent { } render() { + // eslint-disable-next-line const { crop, croppedImageUrl, src } = this.state; return ( diff --git a/src/Components/Dropdown.js b/src/Components/Dropdown.js index 60624e7f2d2c8cb5e5a55f80a00cacbcc48a67bc..31d7047d63cfd5d837734ebbf0cd057bfbc4430f 100644 --- a/src/Components/Dropdown.js +++ b/src/Components/Dropdown.js @@ -17,7 +17,7 @@ You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ import React, { useState, useRef, useEffect, useContext } from 'react' -import { Link } from 'react-router-dom' +import { HashLink as Link } from 'react-router-hash-link'; import { Button, Grow, Paper, Popper, MenuItem, MenuList } from '@material-ui/core'; import { withStyles } from '@material-ui/styles'; import styled from 'styled-components' @@ -85,17 +85,17 @@ function Dropdown(props) { <ExpandMoreIcon/> </Button> { open && - <Popper open={open} keepMounted transition disablePortal> + <Popper open={open} keepMounted transition disablePortal placement={'bottom'}> {({ TransitionProps, placement }) => ( <Grow {...TransitionProps} - style={{ transformOrigin: placement === 'bottom' ? 'center top' : 'center bottom' }} + style={{ transformOrigin: 'center top !important', anchorOrigin : "center bottom !important"}} > <Paper id="menu-list-grow"> <MenuList> { props.items.map((item)=> - <Link key={item.name} to={item.href} ><MenuItem>{item.name}</MenuItem></Link> + <Link key={`${item.name}_${new Date().toString()}` } to={item.href} ><MenuItem>{item.name}</MenuItem></Link> ) } </MenuList> diff --git a/src/Components/EcFooter.js b/src/Components/EcFooter.js index 29d075706fac3c7dd8716f149083e0297439ced1..9b5183ff5ab7b6d8145b65a083ed569659839cdd 100644 --- a/src/Components/EcFooter.js +++ b/src/Components/EcFooter.js @@ -19,6 +19,7 @@ along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/> import React, {Component} from 'react'; import {Row, Col, Container} from 'react-grid-system'; import eduConectada from '../img/educa-conectada.png'; +import styled from 'styled-components'; const blueFooter={ backgroundColor: "#00bcd4", @@ -26,7 +27,7 @@ const blueFooter={ display: "block", paddingTop: "2em", paddingBottom: "2em", - verticalAlign: "bottom" + verticalAlign: "bottom", } const listStyle={ listStyleType: "none", @@ -34,6 +35,10 @@ const listStyle={ padding: "0", lineHeight: "1.6", } +const WhiteLink = styled.a` + text-decoration: none; + color: white; +` class EcFooter extends Component{ render(){ @@ -44,20 +49,20 @@ class EcFooter extends Component{ <Col md={4} sm={5} xs={5}> <h4>Sobre</h4> <ul style={listStyle}> - <li> <a href="#sobre">Sobre a Plataforma</a> </li> - <li> <a href="#parceiros">Portais Parceiros</a> </li> - <li> <a href="#termos-de-uso">Termos de Uso</a> </li> - <li> <a href="#contato">Contato</a> </li> + <li> <WhiteLink href="sobre">Sobre a Plataforma</WhiteLink> </li> + <li> <WhiteLink href="sobre#portaisparceiros">Portais Parceiros</WhiteLink> </li> + <li> <WhiteLink href="termos">Termos de Uso</WhiteLink> </li> + <li> <WhiteLink href="contato">Contato</WhiteLink> </li> </ul> </Col> <Col md={4} sm={5} xs={5}> <h4>Ajuda</h4> <ul style={listStyle}> - <li> <a href="#ajuda">Central de Ajuda</a> </li> - <li> <a href="#publicar">Publicando Recursos</a> </li> - <li> <a href="#busca">Encontrando Recursos</a> </li> - <li> <a href="#rede">Participando da Rede</a> </li> - <li> <a href="#conta">Gerenciando a Conta</a> </li> + <li> <WhiteLink href="ajuda">Central de Ajuda</WhiteLink> </li> + <li> <WhiteLink href="publicando-recurso">Publicando Recursos</WhiteLink> </li> + <li> <WhiteLink href="encontrando-recurso">Encontrando Recursos</WhiteLink> </li> + <li> <WhiteLink href="participando-da-rede">Participando da Rede</WhiteLink> </li> + <li> <WhiteLink href="gerenciando-conta">Gerenciando a Conta</WhiteLink> </li> </ul> </Col> <Col md={4} sm={12} xs={12}> diff --git a/src/Components/EditarColecaoForm.js b/src/Components/EditarColecaoForm.js new file mode 100644 index 0000000000000000000000000000000000000000..9191ee7d51b329f0739e0b3d410baddf7437e7e4 --- /dev/null +++ b/src/Components/EditarColecaoForm.js @@ -0,0 +1,222 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + +import React, {useState, useContext, useEffect} from 'react' +import {Store} from '../Store.js' +import { Button } from '@material-ui/core'; +import styled from 'styled-components' +import Radio from '@material-ui/core/Radio'; +import RadioGroup from '@material-ui/core/RadioGroup'; +import FormControlLabel from '@material-ui/core/FormControlLabel'; +import FormControl from '@material-ui/core/FormControl'; +import TextField from '@material-ui/core/TextField'; +import {getRequest, putRequest} from './HelperFunctions/getAxiosConfig' + +export default function EditarColecaoForm (props) { + const {state} = useContext(Store) + + function handleSuccessfulGet (data) { + setColName({key : false, value : data.name}) + setValue( data.privacy === 'public' ? 'pública' : 'privada') + handleColDescription(data.description) + } + + useEffect(() => { + getRequest(`/collections/${props.id}`, handleSuccessfulGet, (error) => {console.log(error)}) + }, []) + + const [value, setValue] = useState(-1); + + /*values are set according to backend complaint id*/ + const [options] = [ + {value : "pública", text :'Pública (Sua coleção estará disponível para todos)'}, + {value : "privada", text : 'Privada (Somente você poderá visualizar esta coleção)'} + ] + + const handleChange = (event) => { + setValue(event.target.value); + }; + + const [colName, setColName] = useState({ + key : false, + value : "", + }) + + const handleColName = (e) => { + const userInput = e.target.value + + const flag = userInput.length === 0 ? true : false + + setColName({...colName, + key : flag, + value : userInput + }) + } + + function handleSuccessfulSubmit (data) { + props.finalize(data.id) + } + const formSubmit = (e) => { + e.preventDefault() + + // {/*if user didn't select either one, default to privada*/} + const finalRadioValue = value === 'pública' ? 'public' : 'private' + const finalColName = colName + + if(!(finalColName.key)) { + let payload = { + "collection" : { + "name" : finalColName.value, + "owner_id" : state.currentUser.id, + "owner_type" : "User", + "privacy" : finalRadioValue + } + } + + putRequest(`/collections/${props.id}/`, payload, handleSuccessfulSubmit, (error) =>{console.log(error)}) + } + } + + const [colDescription, handleColDescription] = useState("") + const setColDescription = (e) => {handleColDescription(e.target.value)} + + return ( + <form onSubmit={(e) => {formSubmit(e)}} style={{textAlign : "left"}}> + + <StyledTextField + id = {"col-name"} + label={"Nome"} + type = {"text"} + value = {colName.value} + onChange = {e => handleColName(e)} + error = {colName.key} + required = {true} + style={{width:"100%"}} + /> + + <StyledTextField + id = {"col-description"} + label={"Descrição"} + type = {"text"} + value = {colDescription} + multiline + rows={5} + onChange = {e => setColDescription(e)} + style={{width:"100%"}} + /> + + <span style={{fontSize : "12px", color : "#b3b3b3"}}>Esta coleção é:</span> + <StyledFormControl component="fieldset"> + <RadioGroup value={value} onChange={handleChange}> + { + options.map(option => + <FormControlLabel key={option.value} value={option.value} control={<Radio color="#673ab7"/>} label={option.text} /> + ) + } + </RadioGroup> + </StyledFormControl> + + + <ButtonsDiv> + <ButtonCancelar onClick={props.handleClose}>CANCELAR</ButtonCancelar> + <ButtonEnviar type="submit">SALVAR</ButtonEnviar> + </ButtonsDiv> + </form> + ); +} + +export const ButtonsDiv = styled.div` + display : flex; + flex-direction : row; + justify-content : center; + align-items : center; +` + +export const ButtonCancelar = styled(Button)` + &:hover { + background-color : rgba(158,158,158,0.2) !important; + } + height : 36px !important; + padding-left : 16px !important; + padding-right : 16px !important; + font-weight : 500 !important; + border-radius : 3px !important; + color :#666 !important; + background-color: transparent; + min-width : 88px !important; + height : 36px !important; +` + +export const ButtonEnviar = styled(Button)` + background-color : #673ab7 !important; + color : #fff !important; + font-size: 14px !important; + font-weight: 500 !important; + height: 36px !important; + border-radius: 3px !important; + padding-left: 16px !important; + padding-right: 16px !important; + box-shadow: 0 2px 5px 0 rgba(0,0,0,.26) !important; + outline : none !important; + min-width : 88px !important; + vertical-align : middle !important; + margin : 6px 8px !important; + text-decoration : none !important; + + .MuiButton-label { + padding-right : 16px; + padding-left : 16px; + } +` +export const StyledTextField = styled(TextField)` + margin : 18px 0 !important; + + .MuiFormHelperText-root { + text-align : right; + } + + label.Mui-focused { + color : #673ab7; + } + + label.Mui-focused.Mui-error { + color : red; + } + + .MuiInput-underline::after { + border-bottom: 2px solid #673ab7; + } +` + +export const StyledFormControl = styled(FormControl)` + display : block !important; + + .MuiFormControlLabel-root { + color : #666; + } + .MuiIconButton-label { + color : #666; + } + .PrivateRadioButtonIcon-checked { + color : orange; + } + + .MuiTypography-body1 { + font-size : 14px; + } +` diff --git a/src/Components/ExpandedMaterials.js b/src/Components/ExpandedMaterials.js new file mode 100644 index 0000000000000000000000000000000000000000..603ec4ed4f8053d3c72d8ed36527fec9cb221bc9 --- /dev/null +++ b/src/Components/ExpandedMaterials.js @@ -0,0 +1,129 @@ +import React from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import styled from 'styled-components'; +import Chip from '@material-ui/core/Chip'; +import Grid from '@material-ui/core/Grid'; +import Button from '@material-ui/core/Button'; +import TopicCard from './TopicCard'; +import Paper from '@material-ui/core/Paper'; +import Library from '@material-ui/icons/LibraryBooks'; +import { Link } from 'react-router-dom'; + +const useStyles = makeStyles((theme) => ({ + root: { + display: 'flex', + flexWrap: 'wrap', + '& > *': { + margin: theme.spacing(0.5), + }, + }, +})); + +const ExpandedMaterial = (props) => { + const material = { ...props.material }; + const classes = useStyles(); + + return ( + <Paper elevation={3} style={{ backgroundColor: "#444444", padding: "20px" }}> + <Grid container direction="row" spacing={2}> + <Grid item direction="column" xs={12} md={4}> + <Grid item> + <Title variant="body2"> + { + material.name + } + </Title> + </Grid> + <SizedHeightBox /> + <Grid item> + <ChipsDiv className={classes.root}> + { + material.tags.map((tag, index) => { + return ( + <Chip color="default" label={tag.name} key={index} style={{ padding: "0.5px" }} /> + ) + }) + } + </ChipsDiv> + </Grid> + <SizedHeightBox2 /> + <Grid item direction="column" style={{ color: '#E5E7E9', fontWeight: "500" }}> + <DevelopedByDiv> + { + `Desenvolvido por: ${material.developed}` + } + </DevelopedByDiv> + <SizedHeightBox3 /> + <StyledLink to={`/colecao?colecao=${material.id}`}> + <Button variant="contained" color="secondary"> + Ver todos + </Button> + </StyledLink> + </Grid> + </Grid> + <Grid item direction="column" xs={12} md={8}> + <Grid container direction="row"> + <Library style={{ color: "White" }} /> + <SizedWidthBox /> + <Title> + {material.topics.length} módulos + </Title> + </Grid> + <SizedHeightBox /> + <Grid container direction="row" justify="center" alignItems="center" spacing={3}> + <Grid item md={4}> + <TopicCard + topic={material.topics[0]} + colecao_id={material.id} + /> + </Grid> + <Grid item md={4}> + <TopicCard + topic={material.topics[1]} + colecao_id={material.id} + /> + </Grid> + <Grid item md={4}> + <TopicCard + topic={material.topics[2]} + colecao_id={material.id} + /> + </Grid> + </Grid> + </Grid> + </Grid> + </Paper> + ); +} + +const Title = styled.h3` + color: White; + font-weight: 500; + padding : 0; + margin : 0; +` +const DevelopedByDiv = styled.div` +` + +const ChipsDiv = styled.div` + margin-left : -5px; +` +const SizedHeightBox = styled.div` + height : 3em; +` +const SizedHeightBox2 = styled.div` + height : 2em; +` +const SizedHeightBox3 = styled.div` + height : 0.5em; +` +const SizedWidthBox = styled.div` + width : 5px; +` +const StyledLink = styled(Link)` + text-decoration: none !important; + color: inherit !important; +` + + +export default ExpandedMaterial; \ No newline at end of file diff --git a/src/Components/ExpansionPanels.js b/src/Components/ExpansionPanels.js index 0ebb3e702040cd66f89e51dcf01f40b62f81c848..9a242d21a3b8616c70c6ed7b419f24e133194aec 100644 --- a/src/Components/ExpansionPanels.js +++ b/src/Components/ExpansionPanels.js @@ -17,18 +17,14 @@ You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {Component} from 'react'; +import React from 'react'; import ExpansionPanel from '@material-ui/core/ExpansionPanel'; import ExpansionPanelSummary from '@material-ui/core/ExpansionPanelSummary'; import ExpansionPanelDetails from '@material-ui/core/ExpansionPanelDetails'; import Typography from '@material-ui/core/Typography'; -import { Link } from 'react-router-dom' import Grid from '@material-ui/core/Grid'; -import AddIcon from '@material-ui/icons/Add'; -import RemoveIcon from '@material-ui/icons/Remove'; import styled from 'styled-components'; -import { makeStyles } from '@material-ui/styles'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; @@ -458,7 +454,7 @@ export default function SimpleExpansionPanel() { <Grid item xs={12} md={4}> <div style={{color:"#00BCD4",fontSize:"18px"}}> <p>BASICAMENTE,</p> - <p>O usuário poderá reportar, utilizando a funcionalidade “Reportar” ou pelo formulário de “Contato”, qualquer tipo de conteúdo publicado na Plataforma MEC RED que viole os direitos dos usuários, de terceiros ou a legislação aplicável.</p> + <p>O usuário poderá reportar,utilizando a funcionalidade “Reportar” ou pelo formulário de “Contato”, qualquer tipo de conteúdo publicado na Plataforma MEC RED que viole os direitos dos usuários, de terceiros ou a legislação aplicável.</p> </div> </Grid> </Grid> diff --git a/src/Components/Firulas.js b/src/Components/Firulas.js index 526ff7abdc28b1de5666ba4e573060edb5413902..6a368a11cf553166280ec8d85dd9ede03562e781 100644 --- a/src/Components/Firulas.js +++ b/src/Components/Firulas.js @@ -1,29 +1,19 @@ import React, {useState} from 'react' -import axios from 'axios' -import {apiUrl} from '../env'; import styled from 'styled-components' import Rating from '@material-ui/lab/Rating'; import StarBorderIcon from '@material-ui/icons/StarBorder'; import {LikeCounter, ButtonNoWidth} from '../Components/ResourceCardFunction.js' import FavoriteIcon from '@material-ui/icons/Favorite'; +import {putRequest} from './HelperFunctions/getAxiosConfig' export default function Firulas (props) { const [liked, setLiked] = useState(props.liked) + function handleSuccess (data) { + setLiked(!liked) + } const handleLike = () => { - let payload = {} - let config = { - headers : { - 'Accept': 'application/json', - 'Content-Type': 'application/json', - 'Access-Token': sessionStorage.getItem('@portalmec/accessToken'), - 'Client': sessionStorage.getItem('@portalmec/clientToken'), - 'Uid': sessionStorage.getItem('@portalmec/uid'), - } - } - - axios.put( (`${apiUrl}/learning_objects/` + props.recursoId + '/like'),payload, config - ).then( (response) => {setLiked(!liked)}, (error) => {console.log(error)}) + putRequest(`/learning_objects/${props.recursoId}/like/`, {}, handleSuccess, (error) => {console.log(error)}) } return ( diff --git a/src/Components/FloatingDownloadButton.js b/src/Components/FloatingDownloadButton.js new file mode 100644 index 0000000000000000000000000000000000000000..96537210b046c1d0fc841ec4016e16c52e12c3c1 --- /dev/null +++ b/src/Components/FloatingDownloadButton.js @@ -0,0 +1,70 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + +import React, { useState } from 'react'; +import styled from 'styled-components'; +import GetAppIcon from '@material-ui/icons/GetApp'; +import Fab from '@material-ui/core/Fab'; +import Snackbar from '@material-ui/core/Snackbar'; +import MuiAlert from '@material-ui/lab/Alert'; + +function Alert(props) { + return <MuiAlert elevation={6} variant="filled" {...props} />; +} + +export default function FloatingDownloadButton (props) { + const [snackbar, setSnackbar] = useState(false); + + const handleClickDownload = () => { + if (props.empty_selection) + setSnackbar(true); + } + + const handleClose = () => { + setSnackbar(false); + } + + return ( + <div> + <DownloadAnchor href={props.url} alt="Baixar recursos selecionados"> + <FloatingDownload + color="primary" + aria-label="download" + onClick={handleClickDownload} + > + <GetAppIcon /> + </FloatingDownload> + </DownloadAnchor> + <Snackbar open={snackbar} autoHideDuration={6000} onClose={handleClose}> + <Alert onClose={handleClose} severity="alert"> + Selecione recursos para poder baixar + </Alert> + </Snackbar> + </div> + ); +} + +const DownloadAnchor=styled.a` + text-decoration: none !important; +` + +const FloatingDownload=styled(Fab)` + position: fixed !important; + right: 15px !important; + bottom: 25px !important; +` diff --git a/src/Components/FollowCollectionButton.js b/src/Components/FollowCollectionButton.js new file mode 100644 index 0000000000000000000000000000000000000000..be01ad44329cfe45b7ca167a4111d721cd8f7e7a --- /dev/null +++ b/src/Components/FollowCollectionButton.js @@ -0,0 +1,120 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + +import React, { useState, useEffect } from 'react'; +import Button from '@material-ui/core/Button'; +import CheckIcon from '@material-ui/icons/Check'; +import AddIcon from '@material-ui/icons/Add'; +import styled from 'styled-components'; +import SignUpModal from './SignUpModal.js'; +import {getRequest, putRequest} from './HelperFunctions/getAxiosConfig' + +export default function FollowCollectionButton(props) { + const [icon, setIcon] = useState(<AddIcon fontSize="large" />); + const [button_text, setButtonText] = useState("Seguir Coleção"); + const [variant, setVariant] = useState("outlined"); + const [sign_up_open, setSignUpOpen] = useState(false); + const [following, setFollowing] = useState(false); //user following collection + + function handleSuccessGet (data) { + if(data) + data.map((e) => { + if (e["followable"]["id"] === Number(props.collection_id)){ + setVariant("contained"); + setButtonText("Seguindo"); + setIcon(<CheckIcon fontSize="large" />) + setFollowing(true); + } + return undefined + }) + } + useEffect(() => { + const url = `/users/${props.user_id}/following/Collection` + getRequest(url, handleSuccessGet, (error) => console.log(error)) + }, []); + + //handleMouse{Enter, Leave} only do anything when user follows given collection: + const handleMouseEnter = () => { + if (following) { + setVariant("outlined"); + setButtonText("Deixar de seguir"); + setIcon(null); + } + } + + const handleMouseLeave = () => { + if (following) { + setVariant("contained"); + setButtonText("Seguindo"); + setIcon(<CheckIcon fontSize="large" />); + } + } + + function handleSuccessfulFollow (data) { + setVariant("contained"); + setButtonText("Seguindo"); + setIcon(<CheckIcon fontSize="large" />) + setFollowing(true); + } + function handleSuccessfulUnfollow (data) { + setVariant("outlined"); + setButtonText("Seguir Coleção"); + setIcon(<AddIcon fontSize="large" />); + setFollowing(false); + } + const handleClick = () => { + const url = `/collections/${props.collection_id}/follow` + + if (!props.user_id) + setSignUpOpen(true); + else if (!following) { + putRequest(url, {}, handleSuccessfulFollow, (error) => {console.log(error)}) + } else { + putRequest(url, {}, handleSuccessfulUnfollow, (error) => {console.log(error)}) + } + }; + + if (!props.user_is_owner) + return ( + <div> + <FollowButton + variant={variant} + color="primary" + startIcon={icon} + size="small" + onMouseEnter={handleMouseEnter} + onMouseLeave={handleMouseLeave} + onClick={handleClick} + > + <ButtonText>{button_text}</ButtonText> + </FollowButton> + <SignUpModal open={sign_up_open} handleClose={() => setSignUpOpen(false)} /> + </div> + ); + else return (<div></div>); +} + +const ButtonText = styled.span` + font-weight: bolder; + font-size: 1.2em; +` +const FollowButton = styled(Button)` + padding-left: 10; + padding-right: 10; + width: 250px; +` diff --git a/src/Components/FormInput.js b/src/Components/FormInput.js index c107ab51e881fe96da688cac2df8a6562a993c0f..813877ed5261daf1e1723771ab71b77b07d0696d 100644 --- a/src/Components/FormInput.js +++ b/src/Components/FormInput.js @@ -70,7 +70,6 @@ export default function FormInput(props) { type = {props.inputType} value = {props.value} onChange = {props.handleChange} - helperText = {props.help} rows = {props.rows} error = {props.error} rowsMax = {props.rowsMax} diff --git a/src/Components/FormationMaterialDescription.js b/src/Components/FormationMaterialDescription.js new file mode 100644 index 0000000000000000000000000000000000000000..5771aef3448785bc86fc45db7f65a3a10e353bdc --- /dev/null +++ b/src/Components/FormationMaterialDescription.js @@ -0,0 +1,205 @@ +import React from 'react'; +import styled from 'styled-components' + +import Grid from '@material-ui/core/Grid'; + +import Card from '@material-ui/core/Card'; + +import MoveToInboxIcon from '@material-ui/icons/MoveToInbox'; +import LibraryBooksIcon from '@material-ui/icons/LibraryBooks'; +import TranslateIcon from '@material-ui/icons/Translate'; + +export default function FormationMaterialDescription(props) { + /* props + * + * colecao: boolean + * colecao_obj: object + * topico_obj: object + * + */ + const colecao = props.colecao; + const colecao_obj = props.colecao_obj; + const topico_obj = props.topico_obj; + + return ( + <WrappingCard> + <Grid container + direction="row" + justify="flex-start" + alignItems="center" + > + <Grid item xs={12} md={8}> + <TextContainer> + <Title> + {colecao ? + "Sobre o Material" + : "Resumo do " + props.colecao_obj.topic_name.slice(0, -1) + } + </Title> + <Description> + {colecao ? + colecao_obj.description + : topico_obj.description + } + </Description> + {colecao ? + <SubTitle>Histórico do Curso</SubTitle> + : <Strong>Autoria (autores):</Strong> + } + <Description> + {colecao ? + colecao_obj.historic + : topico_obj.author + } + </Description> + </TextContainer> + </Grid> + <Grid item xs={12} md={3}> + <IconList> + <IconItem> + <LibraryBooksIcon /> + <Strong>Tipo de recurso: </Strong> + Material de Formação + <br /> + </IconItem> + + <IconItem> + <MoveToInboxIcon /> + <Strong>Ano de publicação: </Strong> + {colecao ? + colecao_obj.created_at.split('-')[0] + : topico_obj.created_at.split('-')[0] + } + <br /> + </IconItem> + + {[0, 1, 2].map(i => { + const content = colecao ? + (colecao_obj.language[i] ? + colecao_obj.language[i].name + : '') + : (topico_obj.language[i] ? + topico_obj.language[i].name + : '') + return ( + <IconItem> + <TranslateIcon /> + <Strong>Idioma: </Strong> + {content} + <br /> + </IconItem> + ); + })} + + <IconItem> + <Strong>{colecao ? "Criado" : "Enviado"} por:</Strong> + <br /> + <StyledAnchor href={colecao_obj.developedurl}> + { + colecao_obj.id === 3 ? <LongUserIcon src={require("../img/logo_parceiros/ic_peninsula.png")} /> + : <div> + <UserIcon src={require("../img/logo_parceiros/ic_nute.png")} /> + <Red> + {colecao_obj.developed} + </Red> + </div> + } + </StyledAnchor> + </IconItem> + </IconList> + </Grid> + </Grid> + </WrappingCard> + ); +} + +const Title = styled.h1` + font-weight: 100; + color: rgb(102, 102, 102); +` +const SubTitle = styled.h3` + font-weight: 900; + padding-top: 10px; + color: rgb(102, 102, 102); +` +const UserIcon = styled.img` + width: 50px; + height: 50px; + border-radius: 100px; + margin: 10px 5px 10px 10px; +` +const LongUserIcon = styled.img` + width: 90px; + margin: 10px; +` +const Description = styled.p` + color: #666; +` +const TextContainer = styled.div` + margin: 15px; + height: 100%; + @media screen and (max-width: 768px) { + border-bottom: solid 1px #e5e5e5; + padding : 0 0 10px 0 + } + @media screen and (max-width: 990px) { + border-bottom: solid 1px #e5e5e5; + padding : 0 0 10px 0 + } + @media screen and (min-width: 992px) { + border-right: solid 1px #e5e5e5; + padding : 0 15px 0 0 + + } + @media screen and (min-width: 1200px) { + border-right: solid 1px #e5e5e5; + padding : 0 15px 0 0 + } +` + +const WrappingCard = styled(Card)` + border-radius: 0; + margin-right : auto; + margin-left : auto; + margin-bottom: 30px; + + @media screen and (max-width: 768px) { + width : 100% !important; + } + @media screen and (min-width: 992px) { + width : 770px; + } + @media screen and (min-width: 1200px) { + width : 970px !important; + } +` +const IconList = styled.div` + margin: 15px; +` +const IconItem = styled.span` + width: 100%; + display: inline-block; + margin-bottom: 15px; + font-size : 14px; + + .MuiSvgIcon-root { + vertical-align : middle + color: #666; + } + + img { + vertical-align: middle + } + +` +const Strong = styled.span` + font-weight: bold; + color: #666; +` +const Red = styled.span` + color: #e81f4f; +` +const StyledAnchor = styled.a` + text-decoration: none !important; + color: inherit !important; +` diff --git a/src/Components/FormationMaterialHeader.js b/src/Components/FormationMaterialHeader.js new file mode 100644 index 0000000000000000000000000000000000000000..0c49772337828e81ec2ccfb9b045d3cb4f7ef2b9 --- /dev/null +++ b/src/Components/FormationMaterialHeader.js @@ -0,0 +1,151 @@ +import React from 'react'; +import { Link } from 'react-router-dom'; +import styled from 'styled-components' +import Grid from '@material-ui/core/Grid'; +import Card from '@material-ui/core/Card'; +import Button from '@material-ui/core/Button'; +import Chip from '@material-ui/core/Chip'; +import { makeStyles } from '@material-ui/core/styles'; + +const useStyles = makeStyles((theme) => ({ + root: { + display: 'flex', + flexWrap: 'wrap', + '& > *': { + margin: theme.spacing(0.5), + }, + }, +})); + + +export default function FormationMaterialHeader(props) { + const colecao = props.colecao; + const colecao_obj = props.colecao_obj; + const topico_obj = props.topico_obj; + + const classes = useStyles(); + + const get_title = () => { + return colecao ? + colecao_obj.name + : (topico_obj.pre_title + topico_obj.title); + } + + const get_subtitle = () => { + return colecao ? + colecao_obj.topics.length + ' ' + colecao_obj.topic_name + : colecao_obj.name; + } + + const getThumb = () => { + return colecao ? + require(`../../public/${colecao_obj.img}`) + : require(`../../public/${topico_obj.img}`) + } + + return ( + <WrappingCard> + <Grid container + direction="row" + justify="flex-start" + alignItems="stretch" + > + <Grid item xs={12} lg={5}> + <Img src={getThumb()} /> + </Grid> + <Grid item xs={12} lg={7} + direction="column" + justify="flex-start" + alignItems="stretch" + style={{ padding: "8px 10px" }} + > + <Grid item> + <Title>{get_title()}</Title> + </Grid> + <Grid item> + <SubTitle> + {colecao ? + get_subtitle() + : <StyledLink to={'/colecao?id=' + colecao_obj.id}>{get_subtitle()}</StyledLink>} + </SubTitle> + </Grid> + <Grid item> + <ChipsDiv className={classes.root}> + {colecao_obj.tags.map((t, index) => { + return (<Chip color="default" label={t.name} key={index} style={{ padding: "0.5px" }} />); + })} + </ChipsDiv> + </Grid> + <Grid item> + {colecao ? + <Button + variant="contained" + color="secondary" + style={{ marginLeft: '15px' }} + onClick={props.handleClick} + > + {props.colecao ? "Ver todos os módulos" : "Iniciar leitura"} + </Button> + : + <StyledLink to={'/iframe-colecao?colecao=' + colecao_obj.id + '&topico=' + topico_obj.id}> + <Button + variant="contained" + color="secondary" + style={{ marginLeft: '15px', marginTop: '10px' }} + onClick={props.handleClick} + > + {props.colecao ? "Ver todos os módulos" : "Iniciar leitura"} + </Button> + </StyledLink> + } + </Grid> + </Grid> + </Grid> + </WrappingCard> + ); +} + +const ChipsDiv = styled.div` + margin-bottom: 10px; + width: 100%; + margin-left: 10px; +` +const Img = styled.img` + width: 100%; + height: 100%; + display: block; /* remove extra space below image */ + background-color: #e5e5e5; +` +const Title = styled.h2` + font-weight: 100; + margin: 15px; + color: rgb(102, 102, 102); +` +const SubTitle = styled.h4` + font-weight: 50; + margin: 15px;; + margin-top: 0; + color: rgb(102, 102, 102); +` +export const WrappingCard = styled(Card)` + border-radius: 0; + margin-right : auto; + margin-left : auto; + margin-bottom: 30px; + margin-top: 30px; + + @media screen and (max-width: 768px) { + width : 100% !important; + } + @media screen and (min-width: 992px) { + width : 770px; + } + @media screen and (min-width: 1200px) { + width : 970px !important; + } +` + +const StyledLink = styled(Link)` + text-decoration: none !important; + color: #e81f4f !important; +` diff --git a/src/Components/FormationMaterialsResources/formationMaterials.js b/src/Components/FormationMaterialsResources/formationMaterials.js new file mode 100644 index 0000000000000000000000000000000000000000..7d26d169a48e18f4bc4083b6ef75df96ad7683b2 --- /dev/null +++ b/src/Components/FormationMaterialsResources/formationMaterials.js @@ -0,0 +1,1774 @@ +export default function colecoes_obj() { + var colecoes = []; + + //Curso de Especialização Educação Pobreza e Desigualdade Social// + + var tagnames = ["Desigualdade", "Desigualdade Social", 'Pobreza', 'Educação', 'Coleção', 'EPDS', 'Espaços Escolares', 'Currículo'] + var _tags = []; + for (let i = 0; i < tagnames.length; i++) { + _tags.push({ + name: tagnames[i] + }); + }; + + var topicos = []; + topicos.push({ + id: 0, + pre_title: 'Módulo Introdutório', + title: '', + author: 'Miguel Arroyo', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://sgmd.nute.ufsc.br/content/secadi-formacao-continuada-pbf/intro/index.html', + img: 'img/colecoes/pobreza0.jpg', + tags: _tags, + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `No módulo “Introdutório” do curso “Educação, Pobreza e Desigualdade Social” é explicitada a relação entre a pobreza, + as desigualdades sociais e a educação. São explicitados caminhos para a reflexão e ações problematizadoras sobre as + temáticas apresentadas no contexto da educação, a fim de expor a situação de exclusão social. + O módulo ainda propõe uma discussão que, de um lado, possibilita entender a pobreza para repensar os currículos e as práticas educacionais e, de outro, permita cultivar a + sensibilidade para ouvir e incorporar, no exercício docente, as questões que ecoam nas vivências da pobreza. O material foi elaborado para + este curso de Especialização, na modalidade de ensino a distância, tendo em vista seu papel na formação continuada de educadores e agentes + educacionais. O curso foi concluído em 2016, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 1, + pre_title: 'Módulo I: ', + title: 'Pobreza e cidadania', + author: 'Walquiria Leão Rego e Alessandro Pinzani', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/mod-1/index.html', + url: 'https://sgmd.nute.ufsc.br/content/secadi-formacao-continuada-pbf/mod-1/index.html', + img: 'img/colecoes/pobreza1.jpg', + tags: _tags, + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `O módulo “Pobreza e Cidadania” do curso “Educação, Pobreza e Desigualdade Social” pretende não só analisar as relações + entre pobreza e cidadania, mas também oferecer uma imagem da pobreza mais complexa e multifacetada do que aquela que normalmente as + pessoas de outras classes tendem a formar. Ademais, apresentam-se algumas considerações teóricas sobre a relação entre dinheiro, + processos de autonomia e de capacitação moral, bem como sobre a questão da opressão de gênero. Ao longo do texto também é proposta a + desconstrução de alguns dos preconceitos mais comuns sobre as pessoas em condição de pobreza e suas vidas. O material foi elaborado para + este curso de Especialização, na modalidade de ensino a distância, tendo em vista seu papel na formação continuada de educadores e agentes + educacionais. O curso foi concluído em 2016, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 2, + pre_title: 'Módulo II: ', + title: 'Pobreza, Direitos Humanos, Justiça e Educação', + author: 'Erasto Fortes Mendonça', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/mod-2/index.html', + url: 'https://sgmd.nute.ufsc.br/content/secadi-formacao-continuada-pbf/mod-2/index.html', + img: 'img/colecoes/pobreza2.jpg', + tags: _tags, + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `No módulo “Pobreza, Direitos Humanos, Justiça e Educação” do curso “Educação, Pobreza e Desigualdade Social” tem-se o objetivo de entender o papel estratégico da relação entre educação e direitos humanos no enfrentamento e na superação da pobreza e na construção de um sociedade justa, igualitária e fraterna. O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista seu papel na formação continuada de educadores e agentes educacionais. O curso foi concluído em 2016, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 3, + pre_title: 'Módulo III: ', + title: 'Escola: Espaços e tempo de reprodução e resistências da pobreza', + author: 'Lúcia Helena Alvarez Leite', + // url: 'http://especializacao-pobreza.mec.gov.br/modulos/mod-3/index.html', + url: 'https://sgmd.nute.ufsc.br/content/secadi-formacao-continuada-pbf/mod-3/index.html', + img: 'img/colecoes/pobreza3.jpg', + tags: _tags, + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `No módulo “Escola: Espaços e tempo de reprodução e resistências da pobreza” do curso “Educação, Pobreza e Desigualdade Social” pretende-se discutir as relações entre cultura escolar e desigualdade social, buscando analisar as representações sociais sobre as infâncias, adolescência, juventudes e vivências de pobreza no brasil, e o papel do Bolsa Família na garantia do direito ao acesso e à permanência na escola pública. Ainda é proposta a discussão do papel da escola no processo de reprodução das desigualdades sociais e a luta dos movimentos sociais pelo direito à educação e a uma escola para as camadas populares. O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista seu papel na formação continuada de educadores e agentes educacionais. O curso foi concluído em 2016, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 4, + pre_title: 'Módulo IV: ', + title: 'Pobreza e Currículo: uma complexa articulação', + author: 'Miguel Gonzalez Arroyo', + // url: 'http://especializacao-pobreza.mec.gov.br/modulos/mod-4/index.html', + url: 'https://sgmd.nute.ufsc.br/content/secadi-formacao-continuada-pbf/mod-4/index.html', + img: 'img/colecoes/pobreza4.jpg', + tags: _tags, + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `No módulo “Pobreza e Currículo: uma complexa articulação” do curso “Educação, Pobreza e Desigualdade Social” busca-se resgatar a concepção de currículo, explicitando o seu reflexo nas práticas pedagógicas docentes. Neste núcleo o currículo é retratado como fator que exprime a ideologia, as relações de poder e a cultura de cada unidade escolar. Cabe ao docente, por exemplo, reproduzir as desigualdades e injustiças sociais ou contribuir para a construção de uma sociedade efetivamente democrática. Existem três tipos de currículos: um formal, um real e um oculto. Essa compreensão inicial é fundamental para a discussão neste módulo sobre currículo e pobreza. O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista seu papel na formação continuada de educadores e agentes educacionais. O curso foi concluído em 2016, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + + var colecao = { + id: 0, + name: 'Educação, Pobreza e Desigualdade Social', + tags: _tags, + developed: 'Nute UFSC', + developedurl: 'http://lantec.ufsc.br', + topic_name: 'Módulos', + topics: topicos, + score: 100, + img: 'img/colecoes/pobreza.png', + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: 'A relação entre educação, escola, políticas educacionais, formação docente, currículos, teorias pedagógicas e o primeiro direito do ser humano a um digno e justo viver tem estado, em certa medida, ausente no pensamento educacional e nas suas políticas, bem como na formação de profissionais da educação básica e de outros(as) profissionais que estabelecem relações com a educação em contextos empobrecidos. O material busca abrir caminhos reflexivos para a contextualização, reflexão e problematização da situação de pobreza e desigualdade social, além de propor a atividade de repensar os currículos e práticas educacionais para incluir tal tema e cultivar a sensibilidade para ouvir e incorporar, no exercício docente, as questões que ecoam nas vivências da pobreza.', + historic: `O curso foi criado numa parceria entre a Secretaria de Educação Continuada, Alfabetização, Diversidade e Inclusão do Ministério da Educação – SECADI/MEC e a Universidade Federal de Santa Catarina com objetivo de propiciar a coordenadores, gestores, agentes educacionais e professores de todo o Brasil a reflexão sobre a realidade que envolve a pobreza e a desigualdade social e as possibilidades postas pela educação para que essa realidade seja problematizada e transformada. O curso foi concluído em 2016, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3, + }; + + colecoes.push(colecao); + + //Educação na Cultura Digital// + + tagnames = ['Educação', 'Cultura', "Digital", 'Coleção', 'ECD', 'Espaços Escolares'] + _tags = []; + for (let i = 0; i < tagnames.length; i++) { + _tags.push({ + name: tagnames[i] + }); + }; + + topicos = []; + topicos.push({ + id: 0, + pre_title: '', + title: 'Formação de Educadores na Cultura Digital', + author: 'Edla Maria Faust Ramos - (UFSC), Lia Cristina Barata Cavellucci e Célia Reichert Engelmann', + // url: 'http://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/formadores/apresentacao.html', + url: 'https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/formadores/cenario.html', + img: 'img/colecoes/ecd1.jpg', + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `No Módulo “Formação de Educadores na Cultura Digital” do curso “Educação na Cultura Digital”, tem-se como propósito geral de estudos contextualizar e problematizar os processos de formação de docentes e aportar elementos que contribuam para a construção de novas propostas de intervenção para a formação continuada de professores(as) com foco na integração das Tecnologias de Informação e Comunicação nas escolas e seus diversos usos. + +O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 1, + pre_title: '', + title: 'Gestão para Integração das TDIC ao Currículo', + author: 'Maria Elizabeth Bianconcini Trindade Morato Pinto de Almeida, Maria Elisabete Brisola Brito Prado, Lia Cristina Barata Cavellucci e Odete Sidericoudes', + // url: 'http://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/gestao/apresentacao.html', + url: 'https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/gestao/menu-topicos.html', + img: 'img/colecoes/ecd2.jpg', + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `No módulo “Gestão para a Integração das TDIC ao Currículo” do curso “Educação na Cultura Digital” procura-se focalizar temas relacionados à prática da gestão escolar, considerando alguns aspectos deste contexto e tendo como fio condutor o tempo tal como o vivenciamos hoje. Em seguida, analisam-se as repercussões da cultura digital nas práticas de gestão escolar e, por fim, busca-se o desafio de o exercitar o olhar para o futuro. O objetivo é criar um espaço de problematização, discussão e de busca de respostas, e esboçar caminhos para a gestão escolar situada na cultura digital, sempre tendo como meta principal a qualidade da formação dos alunos oferecida pela escola. +O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 2, + pre_title: '', + title: 'Tecnologias Assistivas', + author: 'Liliana Maria Passerino (FACED/UFRGS) e Patrícia Maria Vargas de Lima (Sec. Mun. de Educação de Florianópolis)', + // url: 'http://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/tecnologias-assistivas-2/apresentacao.html', + url: 'https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/tecnologias-assistivas-2/pagina-16.html', + img: 'img/colecoes/ecd3.jpg', + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `No Módulo de “Tecnologias Assistivas” do curso “Educação na Cultura Digital” propõe-se que vocês desafiem-se, permitam-se, encantem-se e reencantem-se com a temática e com o universo chamado inclusão. O núcleo ainda tem como norte apresentar recursos de acessibilidade que facilitarão a navegação na hipermídia e analisar as possibilidades de uso, adaptação e criação de artefatos, estratégias e serviços em Tecnologia Assistiva sob a perspectiva da Educação Inclusiva. +O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 3, + pre_title: '', + title: 'A Prática Docente na Educação Infantil e TDIC', + author: 'Patrícia de Moraes Lima e Ivana Martins da Rosa', + // url: 'http://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/educacao-infantil/apresentacao.html', + url: 'https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/educacao-infantil/pagina.html', + img: 'img/colecoes/ecd4.jpg', + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `No Módulo “A Prática Docente na Educação InfantIl e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” é proposto um novo percurso de aprendizagem que busca estabelecer conexões entre os seus conhecimentos prévios e os aqui propostos, no intuito de integrar o uso das TDIC às práticas pedagógicas na Educação Infantil. Ainda são propostas discussões sobre experiências pedagógicas e análises dos Núcleos de Ação Pedagógica (NAPs), entre outras problematizações do âmbito da Educação Infantil. Busca-se, com este núcleo, contribuir para a construção de conhecimentos e reflexões sobre o saber/fazer nas práticas pedagógicas no contexto abordado. +O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 4, + pre_title: '', + title: 'Educação Física e TDIC', + author: 'Giovani De Lorenzi Pires (UFSC), Juliano Silveira (UFSC), Rodrigo Ferrari (UFSC), Lyana Thédiga de Miranda (UFSC), Gilson Cruz Junior (UFSC) e André Quaranta (UFSC)', + // url: 'http://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/educacao-fisica/apresentacao.html', + url: 'https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/educacao-fisica/menu-topicos.html', + img: 'img/colecoes/ecd5.jpg', + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `No módulo “Educação Física e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” apresentam-se as especificidades da Educação Física escolar e suas relações com as Tecnologias Digitais de Informação e Comunicação (TDIC). Busca-se um caminho interdisciplinar com os demais componentes curriculares, dialogando teoricamente com a ideia de mídia-educação, referindo-se tanto à metodologia e à crítica como ao contexto produtivo-expressivo (FANTIN, 2006). Portanto, este material foi pensado como um meio pelo qual podem-se explorar essas necessidades e questões. Ler, refletir, produzir e intervir em sala de aula serão alguns dos caminhos sugeridos nesta empreitada. +O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 5, + pre_title: '', + title: 'Aprendizagem de Artes Visuais e TDIC', + author: 'Maria Cristina da Rosa Fonseca da Silva, Patrícia Maria Macedo Alves e Jaymini Pravinchandra Shah', + // url: 'http://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/artes/folha-de-rosto.html', + url: 'https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/artes/pagina.html', + img: 'img/colecoes/ecd6.jpg', + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `No Módulo “Aprendizagem de Artes Visuais e TDIC” do curso “Educação na Cultura Digital” propõe-se apresentar alguns aspectos relevantes ao mundo artístico que têm se transformado com o desenvolvimento tecnológico no mundo das Artes Visuais e suas perspectivas, de modo que você possa rever suas práticas pedagógicas através de novos conhecimentos e proporcione aos(às) seus(suas) alunos(as) novos saberes artísticos, por meio de um diálogo entre distintos gêneros artísticos e sua transformação ao longo dos séculos. +O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 6, + pre_title: '', + title: 'Aprendizagem de Língua Estrangeira e TDIC', + author: 'Celso Henrique Soufen Tumolo, Fabíola Teixeira Ferreira, Juliana Cristina Faggion Bergmann e Nadia Karina Ruhmke Ramos', + // url: 'http://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/lingua-estrangeira/apresentacao.html', + url: 'https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/lingua-estrangeira/pagina-9.html', + img: 'img/colecoes/ecd7.jpg', + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `No módulo “Ensino-Aprendizagem de Línguas Estrangeiras e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” é priorizado o emprego das tecnologias em sua área específica de trabalho na escola e também reflete-se sobre as possibilidades oferecidas pela tecnologia para auxiliá-lo(a) a criar práticas pedagógica e soluções para as questões que surgem em sala de aula, além de oferecer subsídios para o desenvolvimento de atividades de ensino e aprendizagem. O objetivo principal é demonstrar como a tecnologia pode ser uma grande aliada na resolução dos desafios pedagógicos que se apresentam no contexto escolar. +O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 7, + pre_title: '', + title: 'Aprendizagem de Matemática no Ensino Fundamental e TDIC', + author: 'Marcus Vinicius de Azevedo Basso (UFRGS), Crediné Silva de Menezes (UFRGS), Márcia Rodrigues Notare Meneghetti (UFRGS), Fabiana Fattore Serres (Colégio de Aplicação/UFRGS) e Elisa Friedrich Martins (EMEF Dep. Marcírio Goulart Loureiro/POA-RS)', + // url: 'http://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/matematica-ef/apresentacao.html', + url: 'https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/matematica-ef/apresentacao.html', + img: 'img/colecoes/ecd8.jpg', + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `No módulo de “Aprendizagem Matemática no Ensino Fundamental e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” pretende-se ajudá-lo(a) a compreender como a incorporação do computador e da internet nas práticas pedagógicas podem apoiar o trabalho de docentes e discentes em aprender a matemática de uma maneira aprofundada, com menos esforço “braçal” e com mais satisfação. Acredita-se que a utilização de ferramentas digitais e algumas formas diferenciadas de trabalhar possam modificar e melhor qualificar as aprendizagens. Espera-se que todos e todas tenham a oportunidade de experimentar, dialogar, debater, refletir e, por fim, construir conhecimento sobre uma nova forma de ensinar e aprender Matemática. +O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 8, + pre_title: '', + title: 'Aprendizagem de Língua Portuguesa no Ensino Fundamental e TDIC', + author: 'Jacqueline Peixoto Barbosa (PUCSP), Eduardo de Moura Almeida (Co-autor pesquisador), Nayara Moreira Santos (Co-autor pesquisador) e Amanda Lacerda de Lacerda (Co-autor escola)', + // url: 'http://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/portugues-ef2/apresentacao.html', + url: 'https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/portugues-ef2/apresentacao.html', + img: 'img/colecoes/ecd9.jpg', + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `No módulo “Aprendizagem de Língua Portuguesa no Ensino Fundamental e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” é possível explorar os conhecimentos da esfera digital no uso da linguagem a partir de quatro perspectivas: a tecnológica, a científica, a literária e a jornalística. A organização deste núcleo é feita a partir da escolha de diferentes gêneros multimodais, articulada com a vivência e/ou análise de práticas, processos e ações típicos da Web 2.0, e do domínio básico do manuseio de editores de imagem, áudio e vídeo, e de ferramentas de editoração eletrônica. Pretende-se que, com a formação desenvolvida, você seja capaz de usar e identificar os textos multimodais e multissemióticos presentes no dia a dia e que possa, também, incorporar tal aprendizado à sua prática docente. +O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 9, + pre_title: '', + title: 'Aprendizagem de História no Ensino Fundamental e TDIC', + author: 'Carla Ferretti Santiago (PUC Minas), Eucidio Pimenta Arruda (UFMG) e Fernanda Dinardo do Nascimento (Escola Municipal Adelina Gonçalves Campos - Betim/MG)', + // url: 'http://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/historia-ef/apresentacao.html', + url: 'https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/historia-ef/apresentacao.html', + img: 'img/colecoes/ecd10.jpg', + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `No módulo “Aprendizagem de História no Ensino Fundamental e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” o que propõe-se é a problematização dos diferentes significados e usos dos materiais e ambientes digitais por meio da reflexão de suas implicações para o ensino e aprendizagem de história. Considera-se importante revelar as mudanças e permanências que as tecnologias de comunicação e informação digitais possibilitam na compreensão e incorporação de categorias fundamentais do campo do saber histórico escolar, como: tempo/temporalidades, memória/registros, entre outros. Em síntese, a proposta parte dos materiais, recursos e meios digitais para, então, refletir as suas implicações na compreensão de conceitos fundantes do conhecimento histórico. Defende-se que uma postura crítica e ativa diante dos meios digitais pode contribuir para que docentes e alunos(as) (re)afirmem seu protagonismo no mundo contemporâneo marcado pela cultura digital. +O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 10, + pre_title: '', + title: 'Aprendizagem de Geografia no Ensino Fundamental e TDIC', + author: 'Rosa Elisabete Militz Wypyczynski Martins e Roberto Souza Ribeiro', + // url: 'http://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/geografia-ef/apresentacao.html', + url: 'https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/geografia-ef/apresentacao.html', + img: 'img/colecoes/ecd11.jpg', + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `No módulo “Aprendizagem de Geografia no Ensino Fundamental e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” tem-se como objetivo refletir sobre práticas de ensino e aprendizagem de Geografia com o uso das TDIC. É desenvolvida a problematização de conceitos geográficos e as utilizações no TDIC no âmbito da aprendizagem, articulando e analisando a realidade em que vivemos na intenção de favorecer o ensino-aprendizagem. +O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 11, + pre_title: '', + title: 'Aprendizagem de Ciências no Ensino Fundamental e TDIC', + author: 'Marina Bazzo de Espíndola, Gabriela de Leon Nóbrega Reses, Patrícia Barbosa Pereira e Ivan Tavares Scotelari de Souza', + // url: 'http://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/ciencias-ef/apresentacao.html', + url: 'https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/ciencias-ef/menu-topicos.html', + img: 'img/colecoes/ecd12.jpg', + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `No módulo “Aprendizagem de Ciências no Ensino Fundamental e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” tem-se como objetivos proporcionar a compreensão do como as TDIC podem ser inseridas no processo de ensino e aprendizagem de conhecimentos científicos, estimular o(a) cursista a ter uma postura ativa e investigadora no decorrer dos estudos e, também, contribuir, por meio de fundamentação teórica e atividades práticas, para a ampliação de conhecimentos do(a) professor sobre essas tecnologias. Almeja-se que, ao final dos estudos do núcleo, você possa propor iniciativas de integração de TDIC na educação em Ciências Naturais, a partir das suas necessidades de ensino e das necessidades específicas desta área de conhecimento. +O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 12, + pre_title: '', + title: 'Aprendizagem de Matemática no Ensino Médio e TDIC', + author: 'Marcus Vinicius de Azevedo Basso (UFRGS), Crediné Silva de Menezes (UFRGS), Márcia Rodrigues Notare Meneghetti (UFRGS), Fabiana Fattore Serres (Colégio de Aplicação/UFRGS) e Elisa Friedrich Martins (EMEF Dep. Marcírio Goulart Loureiro/POA-RS)', + // url: 'http://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/matematica-em/apresentacao.html', + url: 'https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/matematica-em/menu-topicos.html', + img: 'img/colecoes/ecd13.jpg', + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `No módulo “Aprendizagem de Matemática no Ensino Médio e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” propõe-se uma imersão na cultura digital pelos caminhos da Matemática. A intenção é ajudá-lo(a) a compreender como a incorporação do computador e da internet em nossas práticas pedagógicas podem apoiar o trabalho dos(as) professores(as) e propiciar aos(as) alunos(as) o aprendizado de Matemática de uma maneira mais profunda, com menos esforço “braçal” e mais satisfação. Acredita-se que a utilização de ferramentas digitais e algumas formas diferenciadas de trabalhar Matemática possam modificar e qualificar as aprendizagens, e espera-se que todos tenham a oportunidade de experimentar, dialogar, debater, refletir e, por fim, construir conhecimentos sobre uma nova forma de ensinar e aprender Matemática. +O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 13, + pre_title: '', + title: 'Aprendizagem de Língua Portuguesa no Ensino Médio e TDIC', + author: 'Roxane Rojo (IEL-UNICAMP), Saulo da Silva Oliveira (ETEC Parque da Juventude, Centro Paula Sousa/SEE-SP), Jezreel Gabriel Lopes (IEL-UNICAMP, mestrado), João Reynaldo Pires Jr. (IEL-UNICAMP, mestrado) e Kátia Sayuri Fujisawa (IEL-UNICAMP, mestrado)', + // url: 'http://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/portugues-em2/apresentacao.html', + url: 'https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/portugues-em2/menu-topicos.html', + img: 'img/colecoes/ecd14.jpg', + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `No módulo “Aprendizagem de Língua Portuguesa no Ensino Médio e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” são explorados os conhecimentos da esfera digital no uso da linguagem a partir de quatro perspectivas: a tecnológica, a científica, a literária e a jornalística. Pretende-se que, com a formação desenvolvida, você seja capaz de usar e identificar os textos multimodais e multissemióticos presentes no dia a dia e que também possa incorporar tal aprendizado à sua prática docente. Vale ressaltar que, em muitos momentos, você será convidado(a) a refletir, por meio de questionamentos, acerca de diversos assuntos relacionados com o conteúdo. +O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 14, + pre_title: '', + title: 'Aprendizagem de Química no Ensino Médio e TDIC', + author: 'Edson Luiz Lindner - (CA/UFRGS), Victor João da Rocha Maia Santos e Gabriela da Fontoura Rodrigues Selmi', + //url: 'http://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/quimica-em/apresentacao.html', + url: 'https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/quimica-em/pagina-15.html', + img: 'img/colecoes/ecd15.jpg', + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `No módulo “Aprendizagem de Química no Ensino Médio e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” são organizados três momentos, que contemplam: a) a construção de olhares e reflexões sobre o papel das TDIC no processo de ensino-aprendizagem em Química; b) a utilização de vídeos na experimentação química; e c) a inserção e utilização de sistemas interativos, com destaque nos ambientes de autoria, como possibilidade de construir e representar o conhecimento químico. A dinâmica de estudo irá ocorrer tanto por meio de atividades de estudos teóricos quanto de desenvolvimento de atividades práticas. +O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 15, + pre_title: '', + title: 'Aprendizagem de Física no Ensino Médio e TDIC', + author: 'Henrique César da Silva, Patrick de Souza Girelli, Rafaela Rejane Samagaia e Fernando da Silva Calsavara', + // url: 'http://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/fisica-em/apresentacao.html', + url: 'https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/fisica-em/pagina.html', + img: 'img/colecoes/ecd16.jpg', + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `No módulo “Aprendizagem de Física no Ensino Médio e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” serão apresentados e sugeridos modos de utilização de alguns conceitos e tecnologias digitais da informação e comunicação (TDIC) como forma de subsidiar a constituição de propostas didáticas no âmbito do ensino de Física. Para isso, nesse caso, a temática "Nanociência & Nanotecnologias" (N&N) foi escolhida como eixo deste núcleo. Assim, em um primeiro momento, a ideia é que se possa navegar e aprofundar melhor o entendimento dessa temática e sua relação com as TDIC. Em seguida, será importante lançar um olhar para a nossa realidade, com o intuito de perceber as potencialidades didáticas fomentadas pelas TDIC que emergem como possibilidades para o contexto em foco. +O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 16, + pre_title: '', + title: 'Aprendizagem de Biologia no Ensino Médio e TDIC', + author: 'Simão Pedro Pinto Marinho e Alessandra Marinho', + // url: 'http://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/biologia-em2/apresentacao.html', + url: 'https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/biologia-em2/menu-topicos.html', + img: 'img/colecoes/ecd17.jpg', + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `No módulo “Aprendizagem de Biologia no Ensino Médio e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” você será convidado(a) a refletir sobre a interface TDIC e Ensino de Biologia, (re)pensando sobre sua prática pedagógica e entrando em contato com novos recursos e ferramentas que apresentam as mais diversas potencialidades no contexto escolar. Serão explorados o uso das tecnologias digitais na sala de aula, a execução das atividades com ações de reflexão, levantamento de questões, elaboração de planos, organização, registro e socialização das narrativas sobre as atividades desenvolvidas a partir da integração das TDIC ao currículo de Biologia. +O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 17, + pre_title: '', + title: 'Aprendizagem de Sociologia no Ensino Médio e TDIC', + author: 'Alexandro Dantas Trindade(Departamento de Ciência Política e Sociologia - UFPR/PR), Luciana Paula da Silva de Oliveira (Colégio Estadual Professor Algacyr Munhoz Maeder / Curitiba-PR) e Neli Gomes da Rocha (Programa de Pós-Graduação em Sociologia - UFPR/PR)', + // url: 'http://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/sociologia-em/apresentacao.html', + url: 'https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/sociologia-em/menu-topicos.html', + img: 'img/colecoes/ecd18.jpg', + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `O módulo “Aprendizagem de Sociologia no Ensino Médio e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” é pensado como um meio de explorar questões sociológicas, bem como as relações sociais construídas temporal e historicamente que as contextualizam. Ademais, o núcleo ainda propõe reflexões sociológicas acerca do papel das tecnologias de informação e comunicação como base das relações sociais atuais, além de desenvolver atividades que proporcionem a reflexão crítica e a autonomia na criação e elaboração de conteúdos. Ler, refletir, produzir e intervir em sala de aula serão alguns dos caminhos sugeridos nessa empreitada. +O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 18, + pre_title: '', + title: 'Aprendizagem de História no Ensino Médio e TDIC', + author: 'José Alves de Freitas Neto e José Antônio Ferreira da Silva Junior', + // url: 'http://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/historia-em/apresentacao.html', + url: 'https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/historia-em/pagina_2.html', + img: 'img/colecoes/ecd19.jpg', + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `No módulo de “Aprendizagem de História no Ensino Médio e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” é proposta uma reflexão acerca dos conceitos tempo, memória e narrativa no âmbito do ensino de história. São discutidas questões gerais de história e sua relação com a cultura digital, bem como seus usos e possibilidades como fator favorecedor do ensino, a partir da interação e da aprendizagem colaborativa. +O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 19, + pre_title: '', + title: 'Aprendizagem de Geografia no Ensino Médio e TDIC', + author: 'Cláudio Benito Oliveira Ferraz (UNESP - Pres.Prudente)', + // url: 'http://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/geografia-em/apresentacao.html', + url: 'https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/geografia-em/pagina-54.html', + img: 'img/colecoes/ecd20.jpg', + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `No módulo “Aprendizagem de Geografia no Ensino Médio e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” é apresentada a proposta de estimulá-lo(a) a criar novos pensamentos espaciais, articular e dominar conceitos e outros sentidos da linguagem geográfica, de maneira a entendê-la não como algo já estabelecido por especialistas, mas como um campo do pensamento que agencia as linguagens artísticas. +O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 20, + pre_title: '', + title: 'Aprendizagem de Filosofia e TDIC', + author: 'Sérgio Paulino Abranches, Junot Cornélio Matos, Willamis Aprígio de Araújo, Eugênio Pacelle da Costa Cavalcante, Guilherme Jordão Macêdo Dias, Karla Epiphania Lins de Gois e Luis Lucas Dantas da Silva e Nilton Guimarães da Silva', + //url: 'http://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/filosofia/apresentacao.html', + url: 'https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/filosofia/menu-topicos.html', + img: 'img/colecoes/ecd21.jpg', + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `No módulo “Aprendizagem de Filosofia e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” a Filosofia é apresentada como fator que não pode furtar-se a pensar a cultura digital e suas implicações. Em especial para o caso de professores de Filosofia: como trabalhar essa discussão contemporânea na sala de aula? Qual a sua relevância? Através da abordagem de alguns conceitos-chave, como identidade, juventude, cidadania e democracia, este material trata de oferecer algumas possibilidades de discussão em torno dessas questões. +O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 21, + pre_title: '', + title: 'Linguagens do Nosso Tempo', + author: 'Maria Lucia Santaella Braga e Alexandre Santaella Braga', + // url: 'http://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/linguagens/apresentacao.html', + url: 'https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/linguagens/pagina-22.html', + img: 'img/colecoes/ecd22.jpg', + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `No módulo “Linguagens do Nosso Tempo” do curso “Educação na Cultura Digital” tem-se o objetivo de refletir sobre práticas de ensino e aprendizagem de Linguagens do Nosso Tempo com o uso das TDIC. O núcleo apresenta os conceitos caracterizadores das linguagens atuais, a hipermídia e a transmídia com a finalidade de evidenciar que novas linguagens não se esgotam em si mesmas. Levantar e problematizar as implicações que a hipermídia, como a complexa linguagem que é própria das redes digitais e discutir os desafios que essas formas de aprendizagem estão trazendo para a educação, especialmente para aquela que ainda continua nostálgica e exclusivamente presa ao mundo do texto impresso. +O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 22, + pre_title: '', + title: 'Tecnologias Digitais no Letramento Estatístico', + author: 'Ruy César Pietropaolo (UNIBAN), Nielce Meneguello Lobo da Costa (UNIBAN) e Rosangela de Souza Jorge Ando ', + // url: 'http://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/letramento-estatistico/apresentacao.html', + url: 'https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/letramento-estatistico/menu-topicos.html', + img: 'img/colecoes/ecd23.jpg', + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `O módulo “Tecnologias Digitais no Letramento Estatístico” do curso “Educação na Cultura Digital” propõe atividades e experiências visando favorecer a construção de competências referentes ao letramento estatístico, o qual inclui: o domínio de conhecimentos básicos que permitam o desenvolvimento de competências estatísticas; o exercício do pensamento crítico acerca das informações de uma pesquisa para a tomada de decisões; e a utilização das tecnologias digitais para a coleta e a organização dos dados de uma pesquisa, visando a compreensão e intervenção na realidade da escola, bem como a obtenção de medidas e comunicação dos resultados. +O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 23, + pre_title: '', + title: 'Jogos Digitais e Aprendizagem', + author: 'Isa Beatriz da Cruz Neves, Patrícia Rocha Rodrigues, Isa de Jesus Coutinho e Andersen Caribé de Oliveira', + // url: 'http://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/jogos/apresentacao.html', + url: 'https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/jogos/cenario.html', + img: 'img/colecoes/ecd24.jpg', + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `No módulo “Jogos Digitais e Aprendizagem” do curso “Educação na Cultura Digital” os jogos são vistos como formas de diversão interativa que proporcionam aprendizagem. Os jogos digitais podem simular ações como correr, dançar, jogar basquete, tênis, futebol, etc. Em geral, eles apresentam conflitos e competições que exigem cumprimento de regras, raciocínio lógico e uma boa dose de estratégia. Esses desafios contribuem para o desenvolvimento da visão periférica, concentração em diferentes atividades e desenvolvimento de habilidades para resolução de problemas. O objetivo do núcleo é pensar os jogos digitais em articulação com o ensino, bem como refletir sobre seus limites e possibilidades. +O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 24, + pre_title: '', + title: 'Ética na Cultura Digital', + author: 'Sérgio Paulino Abranches, Junot Cornélio Matos, Karla Epiphania Lins de Gois, Luis Lucas Dantas da Silva, Nilton Guimarães da Silva, Willamis Aprígio de Araújo, Eugênio Pacelle da Costa Cavalcante e Guilherme Jordão Macêdo Dias', + // url: 'http://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/etica/apresentacao.html', + url: 'https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/etica/menu-topicos.html', + img: 'img/colecoes/ecd25.jpg', + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `O módulo “Ética na Cultura Digital” do curso “Educação na Cultura Digital” parte da seguinte constatação: dentre uma série de questões contemporâneas relevantes envolvendo a cultura digital, discutidas em outros núcleos deste curso, inclui-se também um questionamento sobre ética. Este núcleo, então, discute algumas dessas questões, sem pretender esgotá-las. É proposta a reflexão sobre a relação entre Ética e Cultura Digital, discutindo os valores subjacentes ao uso das TDIC nas relações sociais e na educação e buscando analisar, de maneira vertical e interdisciplinar, as implicações éticas das diferentes possibilidades tecnológicas para a vida do ser humano. +O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 25, + pre_title: '', + title: 'A Prática Docente no Ensino Fundamental e TDIC', + author: 'Darli Collares (UFRGS) e Nina Rosa Ventimiglia Xavier (Educação Básica)', + // url: 'http://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/fundamental/apresentacao.html', + url: 'https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/fundamental/pagina-2.html', + img: 'img/colecoes/ecd26.jpg', + score: 100, + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `O módulo “A Prática Docente no Ensino Fundamental e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” busca refletir sobre questões inerentes às especificidades da docência nos Anos Iniciais e, também, sobre as possibilidades e implicações do uso de TDIC nessa fase de escolarização, aprofundar os conhecimentos sobre o processo de aprendizagem e propor um novo olhar sobre as práticas pedagógicas baseando-se em Piaget. +O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + + colecao = { + id: 1, + name: 'Educação na Cultura Digital', + tags: _tags, + developed: 'Nute UFSC', + developedurl: 'http://lantec.ufsc.br', + topic_name: 'Módulos', + topics: topicos, + score: 100, + img: 'img/colecoes/ecd.png', + duration: 50, + created_at: '2015-06-13T00:31:24.484Z', + updated_at: '2015-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `O material oferece subsídios para uma formação apoiada nos diversos âmbitos das Tecnologias Digitais de Informação e Comunicação (TDIC) em currículos escolares, além de explorar, demonstrar e analisar as possibilidades criativas e elementos que contribuam para a construção de novas dinâmicas para a formação de professores(as) com foco na integração das Tecnologias de Informação e Comunicação nas escolas e seus diversos usos.`, + historic: `O curso foi criado numa parceria entre Ministério da Educação e Universidade Federal de Santa Catarina, tendo como público alvo professores, coordenadores, gestores pedagógicos e outros membros da equipe gestora que fossem responsáveis pelo processo de formação da escola, além de multiplicadores dos Núcleos de Tecnologia Educacional (NTE) e Núcleos de Tecnologia Municipal (NTM). O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3, + }; + + colecoes.push(colecao); + + //PNAIC// + + // tagnames = ['Alfabetização', 'Educação', 'Coleção', 'PNAIC', "Alfabetização na Idade Certa"] + // _tags = []; + // for (let i = 0; i < tagnames.length; i++) { + // _tags.push({ + // name: tagnames[i] + // }); + // }; + + // topicos = []; + // topicos.push({ + // id: 0, + // pre_title: '', + // title: `Currículo na perspectiva da inclusão e da diversidade: as Diretrizes Curriculares Nacionais da Educação Básica e o Ciclo de Alfabetização`, + // author: 'Secretaria de Educação Básica.', + // url: 'http://sgmd.nute.ufsc.br/content/pnaic-sgmd/caderno-1/home.html', + // img: 'img/colecoes/pnaic1.jpg', + // tags: _tags, + // score: 100, + // duration: 50, + // created_at: '2016-06-13T00:31:24.484Z', + // updated_at: '2016-06-16T12:41:22.885Z', + // language: { + // id: 1, + // name: 'Português', + // code: 'pt' + // }, + // license: null, + // description: `No Caderno 01 de Pedagogia e Diretrizes Curriculares do Pacto Nacional pela Alfabetização na Idade Certa (PNAIC-2015) são apresentados os modelos de organização escolar em seus âmbitos legal e social, evidenciando as práticas escolares e a relação que desempenham na organização do currículo, na análise do cotidiano escolar, na problematização de dinâmicas docentes, na inclusão e diversidade, além de ser aberta uma discussão sobre currículo, avaliação, educação do campo, educação inclusiva e diversidade linguística como tópicos de relevância. O material foi desenvolvido para a formação continuada de professores, pedagogos e alfabetizadores de todo Brasil.`, + // likes_count: 3 + // }); + // topicos.push({ + // id: 1, + // pre_title: '', + // title: 'A criança no Ciclo de Alfabetização', + // author: 'Secretaria de Educação Básica.', + // url: 'http://sgmd.nute.ufsc.br/content/pnaic-sgmd/caderno-2/home.html', + // img: 'img/colecoes/pnaic2.jpg', + // tags: _tags, + // score: 100, + // duration: 50, + // created_at: '2016-06-13T00:31:24.484Z', + // updated_at: '2016-06-16T12:41:22.885Z', + // language: { + // id: 1, + // name: 'Português', + // code: 'pt' + // }, + // license: null, + // description: `O Caderno 02 do Ciclo de Alfabetização do Pacto Nacional pela Alfabetização na Idade Certa (PNAIC-2015) mostra a indispensabilidade de práticas que garantam os direitos das crianças, tais como a infância, trazendo à tona a importância do lúdico para uma melhor aprendizagem. Aponta, também, a necessidade de afeto nas salas de aula, a relação criança, escrita e infância, a educação inclusiva e a educação do campo junto com suas individualidades como temática para reflexão. O texto apresenta relatos com base nas experiências de professores envolvidos com as temáticas anteriormente descritas. O material foi desenvolvido para a formação continuada de professores e alfabetizadores de todo Brasil.`, + // likes_count: 3 + // }); + // topicos.push({ + // id: 2, + // pre_title: '', + // title: 'Interdisciplinaridade no ciclo de alfabetização', + // author: 'Secretaria de Educação Básica.', + // url: 'http://sgmd.nute.ufsc.br/content/pnaic-sgmd/caderno-3/home.html', + // img: 'img/colecoes/pnaic3.jpg', + // tags: _tags, + // score: 100, + // duration: 50, + // created_at: '2016-06-13T00:31:24.484Z', + // updated_at: '2016-06-16T12:41:22.885Z', + // language: { + // id: 1, + // name: 'Português', + // code: 'pt' + // }, + // license: null, + // description: `No Caderno 03 de Ciclo de Alfabetização do Pacto Nacional pela Alfabetização na Idade Certa (PNAIC-2015) é iniciada uma discussão sobre interdisciplinaridade e a dificuldade docente de incorporar essa perspectiva a sua prática pedagógica. É apresentada a interdisciplinaridade como possibilidade de o favorecer o processo de alfabetizar e novas perspectivas para uma melhor organização de projetos, sequências didáticas e aulas interdisciplinares, a importância do conhecimento não fracionado, isto é, de valorizar os conteúdos integradamente e também da leitura como prática que pode unir conteúdos no meio escolar. Incorporar a interdisciplinaridade às práticas pedagógicas significa pensar o currículo da escola. O material foi desenvolvido para a formação continuada de professores e alfabetizadores de todo Brasil.`, + // likes_count: 3 + // }); + // topicos.push({ + // id: 3, + // pre_title: '', + // title: 'A organização do trabalho escolar e os recursos didáticos na alfabetização', + // author: 'Secretaria de Educação Básica.', + // url: 'http://sgmd.nute.ufsc.br/content/pnaic-sgmd/caderno-4/home.html', + // img: 'img/colecoes/pnaic4.jpg', + // tags: _tags, + // score: 100, + // duration: 50, + // created_at: '2016-06-13T00:31:24.484Z', + // updated_at: '2016-06-16T12:41:22.885Z', + // language: { + // id: 1, + // name: 'Português', + // code: 'pt' + // }, + // license: null, + // description: `No Caderno 04 de Organização do Trabalho Escolar do Pacto Nacional pela Alfabetização na Idade Certa (PNAIC-2015) são tematizados quais fundamentos são considerados essenciais no processo educativo e em especial na alfabetização. Tais fundamentos são necessários para se pensar a organização da prática pedagógica, as atividades que norteiam as práticas docentes, que sujeitos queremos formar, quais recursos são possíveis de se utilizar e como utilizá-los. Também é apresentada a relevância que existe no uso de novas tecnologias em atividades de alfabetização, o uso de dinâmicas e jogos confeccionados pelas crianças em sala de aula e o uso de obras literárias como auxiliares no processo de alfabetização. O material foi desenvolvido para a formação continuada de professores e alfabetizadores de todo Brasil.`, + // likes_count: 3 + // }); + // topicos.push({ + // id: 4, + // pre_title: '', + // title: 'Ciências da Natureza no Ciclo de Alfabetização', + // author: 'Secretaria de Educação Básica.', + // url: 'http://sgmd.nute.ufsc.br/content/pnaic-sgmd/caderno-8/home.html', + // img: 'img/colecoes/pnaic8.jpg', + // tags: _tags, + // score: 100, + // duration: 50, + // created_at: '2016-06-13T00:31:24.484Z', + // updated_at: '2016-06-16T12:41:22.885Z', + // language: { + // id: 1, + // name: 'Português', + // code: 'pt' + // }, + // license: null, + // description: `No Caderno 08 de Ciências da Natureza do Pacto Nacional pela Alfabetização na Idade Certa (PNAIC-2015) são apresentadas discussões sobre as relações das ciências da natureza com a alfabetização. A alfabetização científica é apresentada como um direito de aprendizagem das crianças. É focalizada a relação entre a ciência, tecnologia e sociedade. Também são mostradas novas possibilidades e sugestões de métodos para ensino de ciências, como a importância do “fazer Ciência” e de se aprender ciência nos diversos espaços de educação, da experimentação e do despertar da curiosidade dos alunos. Ainda é dado destaque ao uso de livros didáticos e paradidáticos na sala de aula, apontando o lúdico e uma relação contextualizada com o cotidiano das crianças como temáticas fundamentais para se aprender Ciências. O material foi desenvolvido para a formação continuada de professores e alfabetizadores de todo Brasil.`, + // likes_count: 3 + // }); + + // colecao = { + // id: 2, + // name: 'Pacto Nacional pela Alfabetização na Idade Certa', + // tags: _tags, + // developed: 'MEC', + // topic_name: 'Cadernos', + // topics: topicos, + // score: 100, + // img: 'img/colecoes/pnaic.png', + // duration: 50, + // created_at: '2016-06-13T00:31:24.484Z', + // updated_at: '2016-06-16T12:41:22.885Z', + // language: { + // id: 1, + // name: 'Português', + // code: 'pt' + // }, + // license: null, + // description: `Pacto Nacional pela Alfabetização na Idade Certa é um compromisso formal assumido pelos governos federal, do Distrito Federal, dos estados e municípios de assegurar que todas as crianças estejam alfabetizadas até os oito anos de idade, ao final do 3º ano do ensino fundamental.`, + // likes_count: 3, + // }; + + // colecoes.push(colecao); + + //SENAD// + + tagnames = ['Drogas', 'Prevenção', 'Conselheiros', 'SENAD', "Contextos"] + _tags = []; + for (let i = 0; i < tagnames.length; i++) { + _tags.push({ + name: tagnames[i] + }); + }; + + topicos = []; + topicos.push({ + id: 0, + pre_title: 'Iniciando a Trilha', + title: '', + author: 'Nute UFSC', + // url: 'http://conselheiros6.nute.ufsc.br/ebook/iniciando-a-trilha.html', + url: 'https://sgmd.nute.ufsc.br/content/sgmd-resources-conselheiros/ebook/iniciando-a-trilha.html', + img: 'img/colecoes/senad1.jpg', + tags: _tags, + score: 100, + duration: 50, + created_at: '2014-06-13T00:31:24.484Z', + updated_at: '2014-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `O módulo “Iniciando a trilha” do curso “Prevenção dos Problemas Relacionados ao Uso de Drogas” tem como objetivo contextualizar a história do consumo de drogas, com o intuito de problematizar o tema. Busca introduzir material do curso, que almeja desconstruir visões reducionistas, trabalhando a partir de três dimensões: sujeito, contexto, e drogas. O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de conselheiros e agentes comunitários envolvidos na prevenção do uso de drogas no país. O curso foi concluído em 2014, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 1, + pre_title: 'Módulo 1: ', + title: 'Sujeitos, contextos e drogas', + author: 'Nute UFSC', + // url: 'http://conselheiros6.nute.ufsc.br/ebook/modulo-1.html', + url: 'https://sgmd.nute.ufsc.br/content/sgmd-resources-conselheiros/ebook/modulo-1.html', + img: 'img/colecoes/senad2.jpg', + tags: _tags, + score: 100, + duration: 50, + created_at: '2014-06-13T00:31:24.484Z', + updated_at: '2014-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `O módulo “Sujeitos, contextos e drogas” do curso “Prevenção dos Problemas Relacionados ao Uso de Drogas” expõe o contexto histórico, social e cultural de usuários de drogas, bem como seus padrões e tendências, buscando mostrar ao leitor os diferentes cenários existentes neste âmbito. São levantadas questões acerca dos sujeitos usuários, as substâncias individualmente e seus respectivos efeitos. O módulo ainda apresenta pesquisas e entrevistas com professores de diversas áreas do conhecimento relacionadas ao estudo de substâncias psicoativas e seus dependentes. O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de conselheiros e agentes comunitários envolvidos na prevenção do uso de drogas no país. O curso foi concluído em 2014, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 2, + pre_title: 'Módulo 2: ', + title: 'Redes para promoção, prevenção, redução de danos e tratamento', + author: 'Nute UFSC', + // url: 'http://conselheiros6.nute.ufsc.br/ebook/modulo-2.html', + url: 'https://sgmd.nute.ufsc.br/content/sgmd-resources-conselheiros/ebook/modulo-2.html', + img: 'img/colecoes/senad3.jpg', + tags: _tags, + score: 100, + duration: 50, + created_at: '2014-06-13T00:31:24.484Z', + updated_at: '2014-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `O módulo “Redes para promoção, prevenção, redução de danos e tratamento” do curso “Prevenção dos Problemas Relacionados ao Uso de Drogas” apresenta o histórico recente da bioética, os conceitos e riscos de vulnerabilidade, fatores de proteção e prevenção do uso de drogas, além de entrevistas com profissionais que atuam no campo de programas preventivos,visam trazer à tona a importância de informar a população acerca da dependência e de desenvolver políticas multidisciplinares e intersetoriais. O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de conselheiros e agentes comunitários envolvidos na prevenção do uso de drogas no país. O curso foi concluído em 2014, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + topicos.push({ + id: 3, + pre_title: 'Módulo 3: ', + title: 'Políticas Públicas e Legislação sobre Drogas', + author: 'Nute UFSC', + // url: 'http://conselheiros6.nute.ufsc.br/ebook/modulo-3.html', + url: 'https://sgmd.nute.ufsc.br/content/sgmd-resources-conselheiros/ebook/modulo-3.html', + img: 'img/colecoes/senad4.jpg', + tags: _tags, + score: 100, + duration: 50, + created_at: '2014-06-13T00:31:24.484Z', + updated_at: '2014-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `O módulo “Políticas Públicas e Legislação sobre Drogas” do curso “Prevenção dos Problemas Relacionados ao Uso de Drogas” evidencia a relevância das medidas intersetoriais tomadas publicamente e o compromisso de cada um para o melhor cumprimento destas. Ainda é apresentada a relação entre os conselhos e movimentos sociais na atuação com fatores protetores e a importância das políticas de saúde mental e psicossociais presentes no SUS. O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de conselheiros e agentes comunitários envolvidos na prevenção do uso de drogas no país. O curso foi concluído em 2014, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3 + }); + + colecao = { + id: 2, + name: 'Prevenção dos Problemas Relacionados ao Uso de Drogas', + tags: _tags, + developed: 'Nute UFSC', + developedurl: 'http://lantec.ufsc.br', + topic_name: 'Módulos', + topics: topicos, + score: 100, + img: 'img/colecoes/senad.png', + duration: 50, + created_at: '2014-06-13T00:31:24.484Z', + updated_at: '2014-06-16T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `Visa propiciar aos leitores a compreensão da conjuntura social dos usuários e dependentes de substâncias psicoativas, bem como problematizar as dimensões trabalhadas: sujeito, contexto e drogas. Tem como objetivo possibilitar uma formação crítica, que respeite a multiplicidade dos conhecimentos neste campo e que consolide o compromisso com práticas comprometidas com a transformação da realidade social. O material ainda traz pesquisas, entrevistas com profissionais da área e projetos de intervenção elaborados pelos próprios cursistas.`, + historic: `A 6ª edição do Curso de Prevenção dos Problemas Relacionados ao Uso de Drogas – Capacitação para Conselheiros e Lideranças Comunitárias foi promovido pela Secretaria Nacional de Políticas Sobre Drogas do Ministério da Justiça – SENAD/MJ em parceria com Universidade Federal de Santa Catarina. Foram oferecidas 40 mil vagas para conselheiros e lideranças comunitárias de todo o Brasil que receberam capacitação para atuar na prevenção de crack, álcool e outras drogas. O curso foi concluído em 2014, e agora o material está disponível para leitura a todos que tiverem interesse na temática.`, + likes_count: 3, + }; + + colecoes.push(colecao); + + + + // ------------------------------------------------------------------------ + //Banco de Práticas Inspiradoras// + + tagnames = ['Práticas', 'Casos', 'Competências gerais', 'Base Nacional Comum Curricular', 'BNCC'] + _tags = []; + for (let i = 0; i < tagnames.length; i++) { + _tags.push({ + name: tagnames[i] + }); + }; + + topicos = []; + topicos.push({ + id: 0, + pre_title: 'Caso 1: Cara de Brasil (Competência 1)', + title: '', + author: 'Beatriz Souza Duarte e Bruna Lúcia Frigo', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso01.html', + img: 'img/colecoes/boas1.jpg', + tags: ['Educação por projetos', 'Relações étnico-raciais', 'Cultura afro', 'Cultura indígena', 'Identidade'], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `O projeto “Brasil, cara de quê?”, das professoras Beatriz Duarte e Bruna Frigo, da Escola Municipal de Educação Infantil Parque das Nações I, em São Paulo, ajudou alunos da educação infantil a identificarem as principais etnias que formam a população brasileira – negra, indígena e europeia. Por meio das memórias da infância de seus pais, histórias de migração e miscigenação e de vivências lúdicas com representantes de cada cultura, as crianças conscientizaram-se a respeito de quem são e de onde vêm seus costumes. Os resultados mais relevantes foram a desconstrução de estereótipos e preconceitos e a autoaceitação dos alunos da etnia a qual pertencem. Os assuntos abordados no projeto foram inspirados no tema do projeto político-pedagógico da escola de 2016: as relações étnico-raciais.`, + likes_count: 3 + }); + + topicos.push({ + id: 1, + pre_title: 'Caso 2: Educação aplicada à vida no sertão (Competência 2)', + title: '', + author: 'José Hélio Pereira', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso02.html', + img: 'img/colecoes/boas2.jpg', + tags: ['Educação por projetos', 'Investigação', 'Meio ambiente', 'Água', 'Decantação', 'Resolução de problemas'], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `"Uma solução alternativa para o tratamento simplificado da água” é o nome do projeto do professor José Helio Pereira, desenvolvido na escola Casimira Leite Montenegro, em Desterro (PB), em 2017. Com clima semiárido, a região enfrentou problemas de abastecimento de água, o que deixou a população preocupada. Visando melhorar as condições da água barrenta fornecida por caminhões-pipa à comunidade, o professor do 4º ano propôs a seus alunos que pesquisassem formas de filtrar a água. Após leituras e investigações científicas, os alunos descobriram uma grande aliada encontrada na zona em que vivem: a acácia branca (Moringa oleífera) e comprovaram, na prática, a efetividade do processo de decantação estimulado pela semente da planta, que separa o barro da água. `, + likes_count: 3 + }); + topicos.push({ + id: 2, + pre_title: 'Caso 3: Pertencer para preservar (Competência 3)', + title: '', + author: 'Laçanã Costa Simões', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso03.html', + img: 'img/colecoes/boas3.jpg', + tags: ['Educação por projetos', 'Artes', 'Patrimônio', 'Preservação', 'Pertencimento', 'Diálogo', 'Cooperação'], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `Na Escola Municipal Governador Roberto Santos, em Salvador, a professora de artes Iaçanã Simões desenvolveu, em 2017, o projeto “Seja bem-vindo e volte sempre! Um olhar para a conservação do patrimônio público escolar através da arte”. As duas mensagens contidas no título do projeto foram desenhadas, inicialmente, nas portas das turmas do ensino fundamental. A ideia da intervenção era conservar o patrimônio escolar e educar sobre a preservação do espaço público em geral, pois a professora observou que os estudantes não degradavam os ambientes nos quais tinham realizado algum projeto artístico. Além das mensagens, as portas ganharam ilustrações escolhidas por cada turma. Os alunos gostaram tanto da atividade que pintaram, também, outros ambientes da escola.`, + likes_count: 3 + }); + /*topicos.push({ + id: 3, + pre_title: 'Caso 4: Encantamento musical (Competência 4)', + title: '', + author: 'Diogo Silas de Ajala Lobo', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso04.html', + img: 'img/colecoes/boas4.jpg', + tags: ['Educação por projetos', 'Musicalização', 'Instrumentos', 'Sons', 'Cantigas', 'Brincar'], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `O professor de artes Diogo Lobo, do Centro de Educação Infantil do Parque dos Poderes, em Campo Grande, implementou o projeto “Musicalização na educação infantil: cantando e encantando” em 2016. Com ele, mais de 400 crianças do berçário e da educação infantil puderam contar com a música para desenvolver diversas competências e habilidades pedagógicas, uma vez que o projeto foi além do uso das canções apenas como passatempo. Ao escutar melodias e manipular instrumentos, as crianças melhoraram a coordenação motora, a fala, a criatividade e a sociabilidade, além de ampliarem seu repertório cultural e desenvolverem apreço pela música.`, + likes_count: 3 + });*/ + topicos.push({ + id: 4, + pre_title: 'Caso 5: Curiosidade científica (Competência 5) ', + title: '', + author: 'Maria Cristina Fachin Liberalesso', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso05.html', + img: 'img/colecoes/boas5.jpg', + tags: ['Educação por projetos', 'Investigação', 'Pesquisa na internet', 'Raciocínio lógico', 'Insetos'], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `Na cidade de Pinhal Grande (RS), fica a Escola Municipal de Educação Fundamental São Thomaz de Aquino, que, em 2016, teve um de seus banheiros infestado por insetos. A visita inesperada dos animais e a curiosidade dos alunos em saber que bichos eram aqueles, se eram venenosos, e, principalmente, porque havia tantos deles ali, levou a professora do 4º ano, Maria Cristina Fachin, a explorar a pesquisa científica com seus alunos. Ela recolheu uma amostra do inseto e incitou os estudantes a procurarem informações em fontes confiáveis, dando origem ao projeto “Pequeno Cientista”. Com isso, as crianças puderam aprender noções de metodologia de pesquisa e testaram hipóteses práticas para entender o que causou a infestação no banheiro da escola.`, + likes_count: 3 + }); + topicos.push({ + id: 5, + pre_title: 'Caso 6: O Haiti é aqui (Competência 1)', + title: '', + author: 'Diana Aparecida Feuser Ribeiro', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso06.html', + img: 'img/colecoes/boas6.jpg', + tags: ['Educação por projetos', 'Berçário', 'Adaptação', 'Diversidade de saberes', 'Intercâmbio de culturas', 'Identidade'], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `Em 2017, havia um bebê haitiano na turma do berçário 1 do Centro de Educação Infantil Castelo Branco, em Joinville (SC), e a pedagoga responsável, Diana Ribeiro, preocupou-se com a inclusão da família nas atividades escolares, o que é crucial para essa faixa-etária. Como os pais do bebê se comunicavam mal em português, a professora decidiu aprender expressões na língua nativa deles. Uma dessas expressões, “Sali, koman ouye?” (Olá, como vai?), nomeou o projeto de integração entre as culturas haitiana e brasileira. Ao ensinar os costumes locais, o trabalho beneficiou não somente a família estrangeira, mas também as famílias brasileiras procedentes de outros estados. O incentivo a essa descoberta cultural se materializou na decoração e em outras atividades, e trouxe para o berçário um pouco do lar de cada bebê.`, + likes_count: 3 + }); + topicos.push({ + id: 6, + pre_title: 'Caso 7: Mensagens para um mundo sustentável (Competência 7)', + title: '', + author: 'Martamiria Delmiro dos Santos', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso07.html', + img: 'img/colecoes/boas7.jpg', + tags: ['Educação por projetos', 'Consciência socioambiental', 'Consumo responsável', 'Mineralogia', 'Coleta seletiva'], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `Trabalhar a sustentabilidade com foco na mineralogia foi o diferencial do projeto da Escola Municipal Dr. Luiz Gonzaga Maranhão, em Jaboatão dos Guararapes (PE), que recebeu o nome “Educação ambiental: uso consciente dos recursos minerais”. Estimulada pelo tema do projeto político-pedagógico da escola em 2016, a professora Martamiria dos Santos, do 3º ano, decidiu mostrar aos alunos de onde vêm os materiais usados para construir objetos cotidianos, como cadeiras, paredes, portas, etc. Os alunos entenderam como as matérias-primas minerais são formadas na natureza, o valor comercial que possuem e a importância de usá-las de forma consciente, o que os estimulou a praticar a reciclagem e a preservação ambiental.`, + likes_count: 3 + }); + topicos.push({ + id: 7, + pre_title: 'Caso 8: A África me representa (Competência 8)', + title: '', + author: ' Márcia Theodorico Mezzomo', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso08.html', + img: 'img/colecoes/boas8.jpg', + tags: ['Educação por projetos', 'Relações étnico-raciais', 'Cultura afro', 'Preconceito', 'Identidade', 'Representatividade', 'Diálogo'], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `No entorno da Creche Morro da Queimada, em Florianópolis, há forte presença da cultura afro-brasileira. Na turma de educação infantil, por exemplo, metade dos alunos são negros, e isso fez com que a professora Marcia Mezzomo decidisse estimular a representatividade dessas crianças desde cedo. Para tanto, em consonância com a lei federal 10.639/03, sobre ensino da história da cultura afro-brasileira, ela trouxe para o imaginário infantil figuras como heróis, príncipes e princesas africanos, e pode explorar a diversidade cultural e as relações étnico-culturais a partir do tema “Do rei do fogo ao rei do samba: rainha e rei da África eu sou”. A população local, como familiares e representantes de grupos artísticos, contribuiu para mostrar às crianças as influências mais marcantes da cultura africana na cultura nacional.`, + likes_count: 3 + }); + topicos.push({ + id: 8, + pre_title: 'Caso 9: Antídoto contra o preconceito (Competência 9)', + title: '', + author: 'Lorena Bárbara Santos Costa', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso09.html', + img: 'img/colecoes/boas9.jpg', + tags: ['Educação por projetos', 'Relações étnico-raciais', 'Cultura afro', 'Samba', 'Identidade', 'Representatividade', 'Bullying', 'Preconceito', 'Empatia', 'Respeito', 'Diversidade'], score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `A cultura afro-brasileira tem grande expressividade em Salvador, onde as salas de aulas costumam ser compostas, principalmente, por alunos negros, como no 5º ano da Escola Municipal Deputado Gersino Coelho. Ao perceber que seus alunos tinham dificuldade em aceitar-se como negros, e que tratavam uns ao outros de forma preconceituosa, a professora Lorena Costa usou a temática “Vem sambar e aprender: o samba como instrumento de resistência e representação da cultura afro-brasileira” para abordar a descendência africana no país. O resgate do samba da Bahia, ao longo das atividades, foi todo permeado por aspectos da história e da cultura afro, como a trajetória de resistência das comunidades quilombolas. Como resultado, a familiarização com essa cultura despertou a empatia, o respeito e o diálogo entre os alunos.`, + likes_count: 3 + }); + topicos.push({ + id: 9, + pre_title: 'Caso 10: Um olhar de esperança (Competência 10)', + title: '', + author: 'João Paulo Vicente da Silva', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso10.html', + img: 'img/colecoes/boas10.jpg', + tags: ['Educação por projetos; Inclusão; Esporte; Adaptação curricular; Empatia'], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `Em 2017, o aluno cadeirante Renner Luís entrou no 5o ano do Centro Infantil Estrela do Mar, em Extremoz (RN), e ninguém imaginava que alcançaria o 3º lugar estadual, e 5º nacional, em campeonatos paralímpicos de bocha. As conquistas do garoto foram possíveis graças ao empenho do professor de educação física João Paulo da Silva, que pesquisou maneiras de incluí-lo na disciplina e em outras atividades escolares, criando o projeto “Contribuições da educação física na inclusão das pessoas com paralisia cerebral no ensino regular”. A participação de Renner nas aulas e campeonatos ajudaram a melhorar a sociabilidade dos colegas com ele, além de ter contribuído positivamente para sua autoestima.`, + likes_count: 3 + }); + topicos.push({ + id: 10, + pre_title: 'Caso 11: Fábulas favorecem alfabetização de crianças (Competência 4)', + title: '', + author: 'Erika Silva do Carmo', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso11.html', + img: 'img/colecoes/boas11.jpg', + tags: ['Educação por projetos', 'Narração de histórias', 'Fábulas', 'Alfabetização', 'Cooperação'], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `Desde 2016 existe o projeto “Minha escola lê e multiplica saberes: viajando no mundo das fábulas” na Escola Estadual Coronel Cruz, em Itacoatiara (AM). Idealizado pela professora do 1º ano Erika do Carmo o projeto começou com fábulas clássicas, como a da galinha dos ovos de ouros, evoluiu para lendas da região amazônica, como a do boto-cor-de-rosa, até trabalhar a autoria própria das crianças. As principais atividades que estimularam os pequenos foram: assistir animações, ler fábulas e reinterpretá-las com desenhos, oralmente e textualmente, além de acompanhar narrativas com teatro de fantoches. O uso das diferentes linguagens melhorou o processo de alfabetização da turma, explorando tópicos como vocabulário e separação de sílabas.`, + likes_count: 3 + }); + topicos.push({ + id: 11, + pre_title: 'Caso 12: Horta conecta famílias à escola (Competência 2)', + title: '', + author: 'Cleide Maria de Souza', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso12.html', + img: 'img/colecoes/boas12.jpg', + tags: ["Educação por projetos", "Oralidade", "Ciências", "Controle biológico", "Horta", "Consciência socioambiental", "Cooperação", "Participação dos pais"], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `A participação familiar foi crucial para o desenvolvimento do projeto “Horta Vertical: Ajudantes da Natureza” na Centro de Ensino Fundamental Cerâmicas Reunidas Dom Bosco, em Brasília (DF). Comandada pela professora Cleide de Souza, a educação infantil pode entender como a natureza trabalha de forma harmônica e a importância de cada ser vivo para manter a estabilidade ambiental. A relação entre insetos e plantas foi focalizada e, com a ajuda das famílias, hortaliças foram plantadas verticalmente em um muro ao lado da sala de aula. A partir de observação contínua da horta da escola, além de visita a uma horta orgânica de uma das mães da turma, as crianças aprenderam que os insetos são verdadeiros “ajudantes da natureza”, como elas mesmas definiram.`, + likes_count: 3 + }); + topicos.push({ + id: 12, + pre_title: 'Caso 13: Meu espelho negro (Competência 8)', + title: '', + author: 'Cristiane Santos de Melo', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso13.html', + img: 'img/colecoes/boas13.jpg', + tags: ["Educação por projetos", "Identidade", "Representatividade", "Mulher negra", "Empoderamento feminino", "Cabelo crespo", "Ganhadeiras de Itapuã"], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `Em 2015, a professora Cristiane de Melo, do Centro Municipal de Educação Infantil Dr. Djalma Ramos, em Lauro de Freitas (BA), valorizou as raízes africanas com o empoderamento do público feminino. O âmbito social, especialmente a mídia, poucas vezes apresenta mulheres negras como referencial de beleza, e as crianças da turma não consideravam bonita uma mulher sem pele clara e cabelos lisos. Ao convidar a cantora negra Mariene de Castro como personalidade de referência, esse cenário mudou. Foi aí que surgiu o projeto “Mariene: A flor que desabrochou nossa gente”. Por meio de sambas da cantora em parceria com um grupo de ganhadeiras, as meninas vivenciaram a representatividade e aprenderam a valorizar seus traços, como o cabelo crespo. O projeto também ajudou a elevar a autoestima de mães e funcionárias da escola.`, + likes_count: 3 + }); + topicos.push({ + id: 13, + pre_title: 'Caso 14: Vestígios do tempo (Competência 1)', + title: '', + author: 'Lilian Mara Bonette Bianchini', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso14.html', + img: 'img/colecoes/boas14.jpg', + tags: ["Educação por projetos", "Estudo do meio", "Arqueologia", "Cultura indígena", "Caminho de Peabiru", "Vestígios líticos"], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `Na cidade de Engenheiro Beltrão (PR) há vestígios do Caminho de Peabiru, rota aberta por civilizações pré-coloniais que percorriam territórios entre os Oceanos Pacífico e Atlântico. A professora de história Lilian Bianchini, da Escola Municipal de Ensino Fundamental Maria Aparecida Medeiros, criou o projeto “Viajando pelos caminhos da nossa história” para mostrar aos alunos do ensino fundamental as marcas dos povos indígenas, habitantes do território nacional muito antes da chegada dos europeus. A turma ganhou uma “mala de exploração”, onde guardavam o caderno com o registro de suas descobertas a respeito da história e cultura desses povos. A visita a museus da região dedicados ao tema, além da realização de um percurso da rota histórica, deram insumos práticos para a pesquisa dos alunos.`, + likes_count: 3 + }); + + + topicos.push({ + id: 14, + pre_title: 'Caso 15: Além da imaginação (Competência 7) ', + title: '', + author: 'Francisca Deusineide dos Santos Nasário', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso15.html', + img: 'img/colecoes/boas15.jpg', + tags: ['Educação por projetos', 'Pesquisa de campo', 'Lenda urbana','Tradição oral', 'Conto', 'Leitura', 'Reescrita', 'Rosa dos ventos'], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `No projeto “A escola onde eu estudo e uma lenda tenebrosa”, da professora Francisca Nasário, os curiosos alunos do 4º ano investigaram se era verdadeira a lenda de que a escola teria sido construída no terreno de um antigo cemitério. Após entrevistas com antigos moradores, a turma relacionou as histórias da construção da escola às da formação de Pau dos Ferros (RN), e elaborou de uma linha do tempo. Para apresentar o gênero terror e suspense, a professora pediu aos alunos que produzissem as próprias lendas sobre a escola, inspiradas no que leram ou ouviram, aprendendo com a escrita noções de gênero, ortografia e paragrafação. Os contos reescritos foram lidos em sala de aula e integraram a exposição do Dia do Folclore da Escola Estadual Ubiratan Pereira Galvão.`, + likes_count: 3 + }); + + topicos.push({ + id: 15, + pre_title: 'Caso 16: Redescoberta indígena (Competência 3)', + title: '', + author: 'Flávia Roberta Alves Costa', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso16.html', + img: 'img/colecoes/boas16.jpg', + tags: ['Educação por projetos', 'Arte indígena', 'Cultura indígena', 'Identidade', 'Representatividade'], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `O projeto “Inspirações indígenas” foi criado pela professora de artes Flávia Costa para quebrar estereótipos sobre o que é ser indígena nos dias de hoje. Em 2017, a Escola Municipal Divino Espírito Santo, no Recife, recebeu a visita de quatro índios fulni-ôs, que conversaram com os alunos. Como os estudantes ficaram interessados na pintura corporal dos índios, Flávia explicou conceitos de produções artísticas originais, criações inspiradas nelas e cópias, depois, relacionou a pintura corporal com a body art. Os alunos pintaram o próprio corpo com as palavras força, fé, luta, cultura e resistência. A professora também levou fotos das expressões artísticas de quatro etnias presentes em Pernambuco e deu uma oficina de tramas, reciclando sobras de papéis.`, + likes_count: 3 + }); + + topicos.push({ + id: 16, + pre_title: 'Caso 17: Além das fronteiras (Competência 1)', + title: '', + author: 'Patrícia dos Santos Lima', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso17.html', + img: 'img/colecoes/boas17.jpg', + tags: ['Educação por projetos', 'Pesquisa na internet', 'Oralidade', 'Cultura', 'Gamificação'], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `Criado pela professora de inglês Patrícia Lima da Escola Estadual de Ensino Fundamental e Médio Marcelo Candia Subsede I, de Porto Velho (RO), o projeto “Viagem inglesa” pede ao ensino médico que “explore” um país de língua inglesa. Cada turma escolhe um país anglófono e tem de buscar informações históricas, geográficas, econômicas e culturais para apresentar aquela realidade numa feira multicultural aberta à comunidade. Os grupos ficam responsáveis por apresentações de dança, teatro, descrições de pratos típicos, entre outras, com parte dessas vivências faladas em inglês. Em paralelo, a professora faz um trabalho de tutoria, ajudando, por exemplo, a apurar os critérios de pesquisa na web para encontrar informações de fontes confiáveis.`, + likes_count: 3 + }); + + topicos.push({ + id: 17, + pre_title: 'Caso 18: Relaxar e dialogar para aprender (Competência 8)', + title: '', + author: 'Carolina Corado da Silva Oliveira', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso18.html', + img: 'img/colecoes/boas18.jpg', + tags: ['Educação por projetos', 'Ansiedade','Relaxamento', 'Diálogo','Protagonismo', 'Autonomia', 'Paulo Freire'], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `O projeto “Aprender a relaxar e relaxar para aprender: metodologias ativas de ensino em biologia” desenvolvido pela professora Carolina Oliveira com os 1º e 3º anos do Instituto Federal do Rio Grande do Norte, propunha que os alunos se conhecessem melhor, reconhecessem estados de ansiedade para poder cuidar da própriab saúde física e emocional. Carolina aproximou-se de técnicas comuns à meditação e ao mindfulness para priorizar estratégias de diálogo e facilitar os quatro módulos criados para o ensino de biologia: os alunos conheceram conceitos de metodologia, discutiram bioquímica e nutrição ao andarem pelo jardim, responderam perguntas sobre os grupos alimentares e debateram metabolismo em um jogo, e trabalharam citologia ao vivenciarem experiências em sala, comparando as reações de infusão do chá em água quente e em água fria.`, + likes_count: 3 + }); + + topicos.push({ + id: 18, + pre_title: 'Caso 19: Os cordéis da minha terra (Competência 1)', + title: '', + author: 'José Souza dos Santos', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso19.html', + img: 'img/colecoes/boas19.jpg', + tags: ['Educação por projetos', 'Cultura nordestina', 'Folclore', 'Produção artística', 'Cordel', 'Lampião'], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `O professor de português José dos Santos pediu aos alunos do 8º ano da Escola Municipal de Paripiranga (BA) que se inspirassem na tradição oral de familiares mais velhos, muitos analfabetos, para ir às ruas colher narrativas fantásticas. Após gravar ou anotar as histórias, os textos passariam da prosa ao verso, mais especificamente, ao cordel. Surgia o projeto “Cordelize a vida! Valorize a sua cultura!”. Os 24 cordéis escritos pelos alunos foram apresentados à comunidade escolar em uma “tarde de autógrafos”, e os entrevistados que deram origem a eles ganharam um livreto correspondente à história que contaram. Além disso, foram produzidos 40 audiolivros para distribuir gratuitamente os cordéis aos estudantes com deficiência visual.`, + likes_count: 3 + }); + + topicos.push({ + id: 19, + pre_title: 'Caso 20: Experimentação robótica (Competência 2)', + title: '', + author: 'Diogo Tiago dos Santos', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso20.html', + img: 'img/colecoes/boas20.jpg', + tags: ['Educação por projetos', 'Tecnologia', 'Robótica', 'Soluções de problemas', 'Autonomia'], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `O projeto “A criação do grupo de física e robótica da Escola Estadual Ana Lins”, em São Miguel dos Campos (AL), começou com um kit de robótica encontrado no almoxarifado da escola em 2015. Desde então, o professor de física Diogo dos Santos coordena fundamentos da robótica no contraturno escolar para criar soluções que podem ser úteis à sociedade, como o reaproveitamento da água do ar condicionado para irrigação, uma lixeira “inteligente” que ajuda a separar materiais para reciclagem e um dispositivo para pacientes acamados pedirem ajuda com mais facilidade. Além disso, Diogo pediu que os alunos produzissem artigos científicos para apresentar à comunidade acadêmica o protótipo desenvolvido, trabalhando não apenas física, como também leitura e escrita.`, + likes_count: 3 + }); + //------------------------------------------------------- + topicos.push({ + id: 20, + pre_title: 'Caso 21: Vivências como fundamento da aprendizagem (Competência 7)', + title: '', + author: 'Maria do Socorro Braga Reis', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso21.html', + img: 'img/colecoes/boas21.jpg', + tags: ['Educação por projetos', 'Crônica', 'Etnografia', 'Vivências', 'Fotografia', 'Reescrita', 'Autoestima'], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `A professora de português Maria Reis elaborou o projeto “Histórias qu’eu vi-vi: crônicas etnográficas” para os jovens desenvolver habilidades mais apuradas de escrita, retratando atividades e hábitos cotidianos da comunidade paraense de Bragança. Maria apresentou o gênero crônica, explicou o conceito de etnografia e mostrou vídeos que abordavam o fazer etnográfico. Os alunos foram a campo, registraram suas descobertas com fotos e montaram na escola um mural com as imagens. Depois, levaram-no para uma praça perto da escola, onde expuseram as fotos à comunidade. Para a escrita da crônica, cada estudante produziu um texto sobre a prática desenvolvida. As 20 crônicas etnográficas produzidas pelo 2º ano do ensino médio da Escola Estadual Yolanda Chaves foram reunidas em um aplicativo e no site do governo do Estado.`, + likes_count: 3 + }); + + topicos.push({ + id: 21, + pre_title: 'Caso 22: A força da tradição pesqueira está com eles (Competência 6)', + title: '', + author: 'Josiane Mendes Bezerra', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso22.html', + img: 'img/colecoes/boas22.jpg', + tags: ['Educação por projetos', 'Pesca artesanal', 'Educação profissionalizante', 'Turismo', 'Alunos multiplicadores', 'Patrimônio cultural', 'Respeito', 'Empatia', 'Cultura caiçara'], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `O projeto “Fazendo e acontecendo: pesca artesanal da tainha” foi estruturado pela professora Josiane Bezerra para mobilizar da população sobre o resgate histórico-cultural dessa pesca. Os 150 alunos do ensino médio integrado da Escola de Educação Básica Maria Rita Flor, voltado à educação profissionalizante, assistiram a uma aula com pescadores. Daí, buscaram estudos científicos para aprofundar os conhecimentos, criando 12 pôsteres técnico-científicos com enfoques que variaram da história da pesca e do ciclo da tainha a receitas de pratos típicos da região. Baseados em um documentário sobre os pescadores de Bombinhas (SC), os jovens fizeram uma encenação, que mobilizou os professores de geografia, história, matemática e música. Além disso, atuaram como “guias de turismo” ao explicar a pesca artesanal e apresentar a cultura dos pescadores a comunidades locais e visitantes.`, + likes_count: 3 + }); + + topicos.push({ + id: 22, + pre_title: 'Caso 23: Protagonismo na tela do cinema (Competência 5)', + title: '', + author: 'Jayse Antonio da Silva Ferreira', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso23.html', + img: 'img/colecoes/boas23.jpg', + tags: ['Educação por projetos', 'Cinema', 'Protagonismo', 'Autonomia', 'Participação dos pais', 'Preconceito', 'Inclusão'], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `Criado pelo professor de arte Jayse Ferreira, o projeto “Vamos enCURTAr essa história?” nasceu com a proposta de os alunos produzirem curtas-metragens a partir dos próprios referenciais. Os dois primeiros curtas eram releituras de outras obras, mas para o terceiro o professor sugeriu um trabalho autoral: os alunos teriam que escrever histórias referentes à escola e a um tema social. Para tal, pediu ajuda de egressos da escola em oficinas de dinâmica corporal e de um escritor da cidade para aulas de roteiro. O argumento do suspense “Entre dois lados”, de 17 minutos, surgiu do depoimento de um morador que perdeu a perna após um acidente em que dirigia alcoolizado. Os curtas dos alunos da Escola de Referência em Ensino Médio Frei Orlando foram exibidos na praça central de Itambé (PE).`, + likes_count: 3 + }); + + topicos.push({ + id: 23, + pre_title: 'Caso 24: O celular como ferramenta pedagógica (Competência 5)', + title: '', + author: 'Erizaldo Cavalcanti Borges Pimentel', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso24.html', + img: 'img/colecoes/boas24.jpg', + tags: ['Educação por projetos', 'Cinema', 'Celulares', 'Cultura digital', 'Pensamento crítico', 'Cooperação', 'Responsabilidade'], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `Contrariando a norma, que proibia o uso do celular em horário de aula, o professor Erizaldo Pimentel criou o projeto “Cine com ciência: luz, câmera... Educação!”. Nele, alunos 6º ao 9º ano do Centro de Ensino Fundamental 01 do Cruzeiro, na região administrativa de Brasília (DF), têm que produzir vídeos com seus smartphones. O professor ensina conceitos da linguagem cinematográfica, e detalha as etapas de pré-produção, em que os alunos devem elaborar a narrativa e o roteiro técnico, estimulando os estudantes à leitura, também analisa cenas de filmes e discute enquadramento e posicionamento de câmera. Os temas estão relacionados ao mundo dos estudantes, com forte traço social e desestimulando a violência. Em três anos de projeto, são cerca de 50 curtas finalizados.`, + likes_count: 3 + }); + + topicos.push({ + id: 24, + pre_title: 'Caso 25: Aplicativo para a saúde do jovem (Competência 2)', + title: '', + author: 'Elmara Pereira de Souza', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso25.html', + img: 'img/colecoes/boas25.jpg', + tags: ['Educação por projetos', 'Programação', 'Jogo digital', 'Alimentação', 'Atividade física', 'Investigação', 'Autonomia'], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `Na “Incubadora de projetos: a experiência de construção do jogo digital Choices sobre a importância da alimentação saudável e da prática de atividade física na adolescência”, a professora Elmara Souza, do Centro Juvenil de Ciência e Cultura de Vitória da Conquista, exercitou a curiosidade de estudantes interessados em programação para criar um game que ajudasse os jovens a refletir sobre a saúde. O jogo digital tornou-se a história de um adolescente que pode voltar no tempo para fazer escolhas cotidianas mais saudáveis. Os jovens contaram com o apoio de um aluno de ciências da computação e de uma nutricionista para registrar parâmetros de colesterol e triglicérides no sangue. Premiado em um edital da Fundação de Amparo à Pesquisa do Estado da Bahia, o projeto rendeu um artigo, escrito pelos jovens com a ajuda da professora, para um congresso da Sociedade Brasileira para o Progresso da Ciência.`, + likes_count: 3 + }); + + topicos.push({ + id: 25, + pre_title: 'Caso 26: Tabuleiro de respeito (Competência 9)', + title: '', + author: 'Raquel de Oliveira Campos', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso26.html', + img: 'img/colecoes/boas26.jpg', + tags: ['Educação por projetos', 'Gamificação', 'Biomas', 'Cooperação', 'Diálogo', 'Responsabilidade', 'Autoestima'], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `O projeto “Tabuleiro humano: uma viagem de descobertas pelos biomas brasileiros em defesa da vida”, desenvolvido no Colégio Estadual Pedro Álvares Cabral de São João de Meriti (RJ), foi criado pela professora de biologia Raquel Campos, com sua turma do 1º ano do ensino médio. Os alunos construíram um tabuleiro de seis metros quadrados com o mapa brasileiro dividido nos seis biomas do país: Pampa, Mata Atlântica, Caatinga, Cerrado, Pantanal e Amazônia. Em sala, seis grupos pesquisaram os biomas e aspectos culturais, históricos e linguísticos dessas áreas. Em casa, os jovens elaboraram perguntas lidas no jogo, em formato de quiz. No dia da competição, os estudantes venceram com facilidade a turma adversária, que não havia se engajado no trabalho pedagógico. Além disso, a dinâmica do jogo favoreceu o exercício da cooperação e o diálogo na turma.`, + likes_count: 3 + }); + + topicos.push({ + id: 26, + pre_title: 'Caso 27: Matemática para todos (Competência 4)', + title: '', + author: 'Adalgísio Gonçalves Soares', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso27.html', + img: 'img/colecoes/boas27.jpg', + tags: ['Educação por projetos', 'Curta-metragem', 'Malba Tahan', 'Resolução de problemas', 'Cultura digital', 'Cooperação', 'Responsabilidade'], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `O projeto “Festival de curtas, uma viagem às mil e uma noites de Malba Tahan” apresentou contos do escritor aos alunos dos 8 e 9º anos da Escola Estadual Presidente Costa e Silva. Os estudantes se dividiram em grupos, resolveram coletivamente um desafio matemático presente na obra escolhida e, a partir daí, pensarem em uma narrativa para um filme. Além de apoiar as soluções dos problemas, o professor de matemática Adalgísio Soares alinhou as histórias ao conteúdo da disciplina, usando os contos para explicar equações do primeiro grau, operações com números racionais, entre outros. O professor trabalhou também o estudo do gênero textual e habilidades de leitura e escrita. Os moradores de Minas Novas (MG) ajudaram a viabilizar o festival de curtas-metragens, que exibiu 20 filmes em praça pública.`, + likes_count: 3 + }); + + topicos.push({ + id: 27, + pre_title: 'Caso 28: O segredo dos seus olhos (Competência 10)', + title: '', + author: 'Elisangela Marina de Freitas e Silva', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso28.html', + img: 'img/colecoes/boas28.jpg', + tags: ['Educação por projetos', 'Pré-história', 'Arqueologia', 'Acessibilidade', 'Inclusão', 'Braile',' Desenho universal para a aprendizagem'], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `A professora substituta de história Elisangela Silva encarou um desafio na Escola Básica Municipal Intendente Aricomedes da Silva, em Florianópolis: um aluno do 6º ano era cego. Visando sua inclusão, a professora recorreu à expertise das docentes Rosângela Kittel e Ruth dos Santos para trabalhar os conteúdos sobre pré-história, dando origem ao projeto “História nas pontas dos dedos: a acessibilidade ao conteúdo de pré-história”. A partir de elementos táteis, como materiais em braile e confecção de objetos em relevo, o aluno conseguiu vivenciar a aprendizagem plenamente. Para além de adaptar os conteúdos somente a ele, as docentes programaram atividades que permitissem que qualquer estudante pudesse agir com autonomia, democratizando, assim, o acesso ao conhecimento. `, + likes_count: 3 + }); + + topicos.push({ + id: 28, + pre_title: 'Caso 29: Esta escola lhes pertence (Competência 3)', + title: '', + author: 'Paulo Augusto Nedel', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso29.html', + img: 'img/colecoes/boas29.jpg', + tags: ['Educação por projetos', 'Cultura artística', 'Pintura', 'Autonomia', 'Pertencimento', 'Patrimônio escolar'], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `Idealizado pelo professor Paulo Nedel, o “Ateliê do GV” foi implantado em 2015 na Escola Municipal Presidente Getúlio Vargas, em Viamão (RS). O ateliê funciona no contraturno e os alunos do 5º ao 9º ano podem reproduzir pinturas de diferentes artistas sob a orientação de Paulo, que explica o processo de reprodução da imagem, como a mistura de cores e a maneira de pintar. O tempo de finalização varia de acordo com a complexidade do quadro e os estudantes, em geral, fazem duas assinaturas nos trabalhos, a dos autores originais e as deles. Em 2016, com a escola reformada e repintada, foi o momento de distribuir os quadros dos alunos pelas paredes. Os “corredores artísticos” fortaleceram o respeito pelo espaço escolar e os laços com a comunidade. No início de 2018, o ateliê contava com 110 reproduções.`, + likes_count: 3 + }); + + topicos.push({ + id: 29, + pre_title: 'Caso 30: O autocuidado como necessidade (Competência 8)', + title: '', + author: 'Alessandra Aparecida Neves', + //url: 'http://especializacao-pobreza.mec.gov.br/modulos/intro/index.html', + url: 'https://chapa2-ced-com-br.umbler.net/casos/caso30.html', + img: 'img/colecoes/boas30.jpg', + tags: ['Educação por projetos', 'Leitura', 'Interpretação de texto', 'Literatura', 'Miniconto', 'Pesquisa na internet', 'Saúde emocional', 'Psicologia', 'Teoria da recepção'], + score: 100, + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: `Tendo como mote “o desafio da baleia azul”, a professora de português Alessandra Neves, em Dourados (MS), elaborou o projeto “Sem tristezas constantes, sem cortes, sem mortes precoces, entender para compreender-se”, envolvendo leitura, compreensão, interpretação e produção textual. Trabalhou com a música “Bring me to life”, com as obras “Amor de Perdição” e “Romeu e Julieta” e o filme “Inocência”. Então solicitou aos alunos pesquisas sobre depressão e suicídio. Para apresentá-las, a sala virou um “café-viagem”: cada grupo tinha um “anfitrião” que compartilhava os conhecimentos com os colegas. As atividades resultaram em microcontos sobre a temática. O projeto terminou com um papo com uma psicóloga, que orientou os jovens sobre os riscos das interações pela internet e os deixou à vontade para expor os próprios sentimentos.`, + likes_count: 3 + }); + //------------------------------------------------------- + + colecao = { + id: 3, + name: 'Banco de Práticas Inspiradoras', + tags: _tags, + developed: 'Instituto Península', + developedurl: 'http://www.institutopeninsula.org.br', + topic_name: 'Casos', + topics: topicos, + score: 100, + img: 'img/ipen_capa.jpg', + duration: 50, + created_at: '2018-03-26T00:31:24.484Z', + updated_at: '2018-03-26T12:41:22.885Z', + language: { + id: 1, + name: 'Português', + code: 'pt' + }, + license: null, + description: 'É um acervo de práticas inspiradoras realizadas por professores da rede pública de ensino e que estão vinculadas às dez competências gerais da Base Nacional Comum Curricular (BNCC). O objetivo é promover uma reflexão mais ampla sobre o papel dos professores, inspirar os docentes a desenvolverem práticas inovadoras e ajudá-los na implementação da Base em suas realidades, bem como valorizar o trabalho destes e tantos outros professores extraordinários pelo Brasil. As práticas, relatadas em formato de artigo e vídeo, foram desenvolvidas por professores de todo o Brasil, finalistas do Prêmio Professores do Brasil 2017. Conheça mais sobre o projeto aqui: https://www.youtube.com/watch?v=ceJywQbZSM8', + historic: `O Banco de Práticas inspiradoras é uma iniciativa realizada pelo Instituto Península e Ministério da Educação. `, + likes_count: 3, + }; + + colecoes.push(colecao); + // ------------------------------------------------------------------ + + // var epd = Object.assign({}, colecoes[0]); + // epd.id = 3; + // + // colecoes.push(epd); + + ///// + + //console.log(colecoes); + //console.dir(colecoes, { depth: null }); + //console.log(JSON.stringify(colecoes, null, 4)); + + return colecoes; +} diff --git a/src/Components/FormationMaterialsResources/formationMaterials.json b/src/Components/FormationMaterialsResources/formationMaterials.json new file mode 100644 index 0000000000000000000000000000000000000000..977441590578b4d4b3cf58b031f26479f91fc87a --- /dev/null +++ b/src/Components/FormationMaterialsResources/formationMaterials.json @@ -0,0 +1,1898 @@ +[ + { + "id": 0, + "name": "Educação, Pobreza e Desigualdade Social", + "tags": [ + { + "name": "Desigualdade" + }, + { + "name": "Desigualdade Social" + }, + { + "name": "Pobreza" + }, + { + "name": "Educação" + }, + { + "name": "Coleção" + }, + { + "name": "EPDS" + }, + { + "name": "Espaços Escolares" + }, + { + "name": "Currículo" + } + ], + "developed": "Nute UFSC", + "developedurl": "http://lantec.ufsc.br", + "topic_name": "Módulos", + "topics": [ + { + "id": 0, + "pre_title": "Módulo Introdutório", + "title": "", + "author": "Miguel Arroyo", + "url": "https://sgmd.nute.ufsc.br/content/secadi-formacao-continuada-pbf/intro/index.html", + "img": "img/colecoes/pobreza0.jpg", + "tags": [ + { + "name": "Desigualdade" + }, + { + "name": "Desigualdade Social" + }, + { + "name": "Pobreza" + }, + { + "name": "Educação" + }, + { + "name": "Coleção" + }, + { + "name": "EPDS" + }, + { + "name": "Espaços Escolares" + }, + { + "name": "Currículo" + } + ], + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "No módulo “Introdutório” do curso “Educação, Pobreza e Desigualdade Social” é explicitada a relação entre a pobreza,\n as desigualdades sociais e a educação. São explicitados caminhos para a reflexão e ações problematizadoras sobre as\n temáticas apresentadas no contexto da educação, a fim de expor a situação de exclusão social.\n O módulo ainda propõe uma discussão que, de um lado, possibilita entender a pobreza para repensar os currículos e as práticas educacionais e, de outro, permita cultivar a\n sensibilidade para ouvir e incorporar, no exercício docente, as questões que ecoam nas vivências da pobreza. O material foi elaborado para\n este curso de Especialização, na modalidade de ensino a distância, tendo em vista seu papel na formação continuada de educadores e agentes\n educacionais. O curso foi concluído em 2016, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 1, + "pre_title": "Módulo I: ", + "title": "Pobreza e cidadania", + "author": "Walquiria Leão Rego e Alessandro Pinzani", + "url": "https://sgmd.nute.ufsc.br/content/secadi-formacao-continuada-pbf/mod-1/index.html", + "img": "img/colecoes/pobreza1.jpg", + "tags": [ + { + "name": "Desigualdade" + }, + { + "name": "Desigualdade Social" + }, + { + "name": "Pobreza" + }, + { + "name": "Educação" + }, + { + "name": "Coleção" + }, + { + "name": "EPDS" + }, + { + "name": "Espaços Escolares" + }, + { + "name": "Currículo" + } + ], + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "O módulo “Pobreza e Cidadania” do curso “Educação, Pobreza e Desigualdade Social” pretende não só analisar as relações\n entre pobreza e cidadania, mas também oferecer uma imagem da pobreza mais complexa e multifacetada do que aquela que normalmente as\n pessoas de outras classes tendem a formar. Ademais, apresentam-se algumas considerações teóricas sobre a relação entre dinheiro,\n processos de autonomia e de capacitação moral, bem como sobre a questão da opressão de gênero. Ao longo do texto também é proposta a\n desconstrução de alguns dos preconceitos mais comuns sobre as pessoas em condição de pobreza e suas vidas. O material foi elaborado para\n este curso de Especialização, na modalidade de ensino a distância, tendo em vista seu papel na formação continuada de educadores e agentes\n educacionais. O curso foi concluído em 2016, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 2, + "pre_title": "Módulo II: ", + "title": "Pobreza, Direitos Humanos, Justiça e Educação", + "author": "Erasto Fortes Mendonça", + "url": "https://sgmd.nute.ufsc.br/content/secadi-formacao-continuada-pbf/mod-2/index.html", + "img": "img/colecoes/pobreza2.jpg", + "tags": [ + { + "name": "Desigualdade" + }, + { + "name": "Desigualdade Social" + }, + { + "name": "Pobreza" + }, + { + "name": "Educação" + }, + { + "name": "Coleção" + }, + { + "name": "EPDS" + }, + { + "name": "Espaços Escolares" + }, + { + "name": "Currículo" + } + ], + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "No módulo “Pobreza, Direitos Humanos, Justiça e Educação” do curso “Educação, Pobreza e Desigualdade Social” tem-se o objetivo de entender o papel estratégico da relação entre educação e direitos humanos no enfrentamento e na superação da pobreza e na construção de um sociedade justa, igualitária e fraterna. O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista seu papel na formação continuada de educadores e agentes educacionais. O curso foi concluído em 2016, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 3, + "pre_title": "Módulo III: ", + "title": "Escola: Espaços e tempo de reprodução e resistências da pobreza", + "author": "Lúcia Helena Alvarez Leite", + "url": "https://sgmd.nute.ufsc.br/content/secadi-formacao-continuada-pbf/mod-3/index.html", + "img": "img/colecoes/pobreza3.jpg", + "tags": [ + { + "name": "Desigualdade" + }, + { + "name": "Desigualdade Social" + }, + { + "name": "Pobreza" + }, + { + "name": "Educação" + }, + { + "name": "Coleção" + }, + { + "name": "EPDS" + }, + { + "name": "Espaços Escolares" + }, + { + "name": "Currículo" + } + ], + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "No módulo “Escola: Espaços e tempo de reprodução e resistências da pobreza” do curso “Educação, Pobreza e Desigualdade Social” pretende-se discutir as relações entre cultura escolar e desigualdade social, buscando analisar as representações sociais sobre as infâncias, adolescência, juventudes e vivências de pobreza no brasil, e o papel do Bolsa Família na garantia do direito ao acesso e à permanência na escola pública. Ainda é proposta a discussão do papel da escola no processo de reprodução das desigualdades sociais e a luta dos movimentos sociais pelo direito à educação e a uma escola para as camadas populares. O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista seu papel na formação continuada de educadores e agentes educacionais. O curso foi concluído em 2016, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 4, + "pre_title": "Módulo IV: ", + "title": "Pobreza e Currículo: uma complexa articulação", + "author": "Miguel Gonzalez Arroyo", + "url": "https://sgmd.nute.ufsc.br/content/secadi-formacao-continuada-pbf/mod-4/index.html", + "img": "img/colecoes/pobreza4.jpg", + "tags": [ + { + "name": "Desigualdade" + }, + { + "name": "Desigualdade Social" + }, + { + "name": "Pobreza" + }, + { + "name": "Educação" + }, + { + "name": "Coleção" + }, + { + "name": "EPDS" + }, + { + "name": "Espaços Escolares" + }, + { + "name": "Currículo" + } + ], + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "No módulo “Pobreza e Currículo: uma complexa articulação” do curso “Educação, Pobreza e Desigualdade Social” busca-se resgatar a concepção de currículo, explicitando o seu reflexo nas práticas pedagógicas docentes. Neste núcleo o currículo é retratado como fator que exprime a ideologia, as relações de poder e a cultura de cada unidade escolar. Cabe ao docente, por exemplo, reproduzir as desigualdades e injustiças sociais ou contribuir para a construção de uma sociedade efetivamente democrática. Existem três tipos de currículos: um formal, um real e um oculto. Essa compreensão inicial é fundamental para a discussão neste módulo sobre currículo e pobreza. O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista seu papel na formação continuada de educadores e agentes educacionais. O curso foi concluído em 2016, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + } + ], + "score": 100, + "img": "img/colecoes/pobreza.png", + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "A relação entre educação, escola, políticas educacionais, formação docente, currículos, teorias pedagógicas e o primeiro direito do ser humano a um digno e justo viver tem estado, em certa medida, ausente no pensamento educacional e nas suas políticas, bem como na formação de profissionais da educação básica e de outros(as) profissionais que estabelecem relações com a educação em contextos empobrecidos. O material busca abrir caminhos reflexivos para a contextualização, reflexão e problematização da situação de pobreza e desigualdade social, além de propor a atividade de repensar os currículos e práticas educacionais para incluir tal tema e cultivar a sensibilidade para ouvir e incorporar, no exercício docente, as questões que ecoam nas vivências da pobreza.", + "historic": "O curso foi criado numa parceria entre a Secretaria de Educação Continuada, Alfabetização, Diversidade e Inclusão do Ministério da Educação – SECADI/MEC e a Universidade Federal de Santa Catarina com objetivo de propiciar a coordenadores, gestores, agentes educacionais e professores de todo o Brasil a reflexão sobre a realidade que envolve a pobreza e a desigualdade social e as possibilidades postas pela educação para que essa realidade seja problematizada e transformada. O curso foi concluído em 2016, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 1, + "name": "Educação na Cultura Digital", + "tags": [ + { + "name": "Educação" + }, + { + "name": "Cultura" + }, + { + "name": "Digital" + }, + { + "name": "Coleção" + }, + { + "name": "ECD" + }, + { + "name": "Espaços Escolares" + } + ], + "developed": "Nute UFSC", + "developedurl": "http://lantec.ufsc.br", + "topic_name": "Módulos", + "topics": [ + { + "id": 0, + "pre_title": "", + "title": "Formação de Educadores na Cultura Digital", + "author": "Edla Maria Faust Ramos - (UFSC), Lia Cristina Barata Cavellucci e Célia Reichert Engelmann", + "url": "https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/formadores/cenario.html", + "img": "img/colecoes/ecd1.jpg", + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "No Módulo “Formação de Educadores na Cultura Digital” do curso “Educação na Cultura Digital”, tem-se como propósito geral de estudos contextualizar e problematizar os processos de formação de docentes e aportar elementos que contribuam para a construção de novas propostas de intervenção para a formação continuada de professores(as) com foco na integração das Tecnologias de Informação e Comunicação nas escolas e seus diversos usos.\n\nO material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 1, + "pre_title": "", + "title": "Gestão para Integração das TDIC ao Currículo", + "author": "Maria Elizabeth Bianconcini Trindade Morato Pinto de Almeida, Maria Elisabete Brisola Brito Prado, Lia Cristina Barata Cavellucci e Odete Sidericoudes", + "url": "https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/gestao/menu-topicos.html", + "img": "img/colecoes/ecd2.jpg", + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "No módulo “Gestão para a Integração das TDIC ao Currículo” do curso “Educação na Cultura Digital” procura-se focalizar temas relacionados à prática da gestão escolar, considerando alguns aspectos deste contexto e tendo como fio condutor o tempo tal como o vivenciamos hoje. Em seguida, analisam-se as repercussões da cultura digital nas práticas de gestão escolar e, por fim, busca-se o desafio de o exercitar o olhar para o futuro. O objetivo é criar um espaço de problematização, discussão e de busca de respostas, e esboçar caminhos para a gestão escolar situada na cultura digital, sempre tendo como meta principal a qualidade da formação dos alunos oferecida pela escola.\nO material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 2, + "pre_title": "", + "title": "Tecnologias Assistivas", + "author": "Liliana Maria Passerino (FACED/UFRGS) e Patrícia Maria Vargas de Lima (Sec. Mun. de Educação de Florianópolis)", + "url": "https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/tecnologias-assistivas-2/pagina-16.html", + "img": "img/colecoes/ecd3.jpg", + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "No Módulo de “Tecnologias Assistivas” do curso “Educação na Cultura Digital” propõe-se que vocês desafiem-se, permitam-se, encantem-se e reencantem-se com a temática e com o universo chamado inclusão. O núcleo ainda tem como norte apresentar recursos de acessibilidade que facilitarão a navegação na hipermídia e analisar as possibilidades de uso, adaptação e criação de artefatos, estratégias e serviços em Tecnologia Assistiva sob a perspectiva da Educação Inclusiva.\nO material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 3, + "pre_title": "", + "title": "A Prática Docente na Educação Infantil e TDIC", + "author": "Patrícia de Moraes Lima e Ivana Martins da Rosa", + "url": "https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/educacao-infantil/pagina.html", + "img": "img/colecoes/ecd4.jpg", + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "No Módulo “A Prática Docente na Educação InfantIl e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” é proposto um novo percurso de aprendizagem que busca estabelecer conexões entre os seus conhecimentos prévios e os aqui propostos, no intuito de integrar o uso das TDIC às práticas pedagógicas na Educação Infantil. Ainda são propostas discussões sobre experiências pedagógicas e análises dos Núcleos de Ação Pedagógica (NAPs), entre outras problematizações do âmbito da Educação Infantil. Busca-se, com este núcleo, contribuir para a construção de conhecimentos e reflexões sobre o saber/fazer nas práticas pedagógicas no contexto abordado.\nO material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 4, + "pre_title": "", + "title": "Educação Física e TDIC", + "author": "Giovani De Lorenzi Pires (UFSC), Juliano Silveira (UFSC), Rodrigo Ferrari (UFSC), Lyana Thédiga de Miranda (UFSC), Gilson Cruz Junior (UFSC) e André Quaranta (UFSC)", + "url": "https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/educacao-fisica/menu-topicos.html", + "img": "img/colecoes/ecd5.jpg", + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "No módulo “Educação Física e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” apresentam-se as especificidades da Educação Física escolar e suas relações com as Tecnologias Digitais de Informação e Comunicação (TDIC). Busca-se um caminho interdisciplinar com os demais componentes curriculares, dialogando teoricamente com a ideia de mídia-educação, referindo-se tanto à metodologia e à crítica como ao contexto produtivo-expressivo (FANTIN, 2006). Portanto, este material foi pensado como um meio pelo qual podem-se explorar essas necessidades e questões. Ler, refletir, produzir e intervir em sala de aula serão alguns dos caminhos sugeridos nesta empreitada.\nO material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 5, + "pre_title": "", + "title": "Aprendizagem de Artes Visuais e TDIC", + "author": "Maria Cristina da Rosa Fonseca da Silva, Patrícia Maria Macedo Alves e Jaymini Pravinchandra Shah", + "url": "https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/artes/pagina.html", + "img": "img/colecoes/ecd6.jpg", + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "No Módulo “Aprendizagem de Artes Visuais e TDIC” do curso “Educação na Cultura Digital” propõe-se apresentar alguns aspectos relevantes ao mundo artístico que têm se transformado com o desenvolvimento tecnológico no mundo das Artes Visuais e suas perspectivas, de modo que você possa rever suas práticas pedagógicas através de novos conhecimentos e proporcione aos(às) seus(suas) alunos(as) novos saberes artísticos, por meio de um diálogo entre distintos gêneros artísticos e sua transformação ao longo dos séculos.\nO material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 6, + "pre_title": "", + "title": "Aprendizagem de Língua Estrangeira e TDIC", + "author": "Celso Henrique Soufen Tumolo, Fabíola Teixeira Ferreira, Juliana Cristina Faggion Bergmann e Nadia Karina Ruhmke Ramos", + "url": "https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/lingua-estrangeira/pagina-9.html", + "img": "img/colecoes/ecd7.jpg", + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "No módulo “Ensino-Aprendizagem de Línguas Estrangeiras e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” é priorizado o emprego das tecnologias em sua área específica de trabalho na escola e também reflete-se sobre as possibilidades oferecidas pela tecnologia para auxiliá-lo(a) a criar práticas pedagógica e soluções para as questões que surgem em sala de aula, além de oferecer subsídios para o desenvolvimento de atividades de ensino e aprendizagem. O objetivo principal é demonstrar como a tecnologia pode ser uma grande aliada na resolução dos desafios pedagógicos que se apresentam no contexto escolar.\nO material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 7, + "pre_title": "", + "title": "Aprendizagem de Matemática no Ensino Fundamental e TDIC", + "author": "Marcus Vinicius de Azevedo Basso (UFRGS), Crediné Silva de Menezes (UFRGS), Márcia Rodrigues Notare Meneghetti (UFRGS), Fabiana Fattore Serres (Colégio de Aplicação/UFRGS) e Elisa Friedrich Martins (EMEF Dep. Marcírio Goulart Loureiro/POA-RS)", + "url": "https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/matematica-ef/apresentacao.html", + "img": "img/colecoes/ecd8.jpg", + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "No módulo de “Aprendizagem Matemática no Ensino Fundamental e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” pretende-se ajudá-lo(a) a compreender como a incorporação do computador e da internet nas práticas pedagógicas podem apoiar o trabalho de docentes e discentes em aprender a matemática de uma maneira aprofundada, com menos esforço “braçal” e com mais satisfação. Acredita-se que a utilização de ferramentas digitais e algumas formas diferenciadas de trabalhar possam modificar e melhor qualificar as aprendizagens. Espera-se que todos e todas tenham a oportunidade de experimentar, dialogar, debater, refletir e, por fim, construir conhecimento sobre uma nova forma de ensinar e aprender Matemática.\nO material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 8, + "pre_title": "", + "title": "Aprendizagem de Língua Portuguesa no Ensino Fundamental e TDIC", + "author": "Jacqueline Peixoto Barbosa (PUCSP), Eduardo de Moura Almeida (Co-autor pesquisador), Nayara Moreira Santos (Co-autor pesquisador) e Amanda Lacerda de Lacerda (Co-autor escola)", + "url": "https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/portugues-ef2/apresentacao.html", + "img": "img/colecoes/ecd9.jpg", + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "No módulo “Aprendizagem de Língua Portuguesa no Ensino Fundamental e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” é possível explorar os conhecimentos da esfera digital no uso da linguagem a partir de quatro perspectivas: a tecnológica, a científica, a literária e a jornalística. A organização deste núcleo é feita a partir da escolha de diferentes gêneros multimodais, articulada com a vivência e/ou análise de práticas, processos e ações típicos da Web 2.0, e do domínio básico do manuseio de editores de imagem, áudio e vídeo, e de ferramentas de editoração eletrônica. Pretende-se que, com a formação desenvolvida, você seja capaz de usar e identificar os textos multimodais e multissemióticos presentes no dia a dia e que possa, também, incorporar tal aprendizado à sua prática docente.\nO material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 9, + "pre_title": "", + "title": "Aprendizagem de História no Ensino Fundamental e TDIC", + "author": "Carla Ferretti Santiago (PUC Minas), Eucidio Pimenta Arruda (UFMG) e Fernanda Dinardo do Nascimento (Escola Municipal Adelina Gonçalves Campos - Betim/MG)", + "url": "https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/historia-ef/apresentacao.html", + "img": "img/colecoes/ecd10.jpg", + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "No módulo “Aprendizagem de História no Ensino Fundamental e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” o que propõe-se é a problematização dos diferentes significados e usos dos materiais e ambientes digitais por meio da reflexão de suas implicações para o ensino e aprendizagem de história. Considera-se importante revelar as mudanças e permanências que as tecnologias de comunicação e informação digitais possibilitam na compreensão e incorporação de categorias fundamentais do campo do saber histórico escolar, como: tempo/temporalidades, memória/registros, entre outros. Em síntese, a proposta parte dos materiais, recursos e meios digitais para, então, refletir as suas implicações na compreensão de conceitos fundantes do conhecimento histórico. Defende-se que uma postura crítica e ativa diante dos meios digitais pode contribuir para que docentes e alunos(as) (re)afirmem seu protagonismo no mundo contemporâneo marcado pela cultura digital.\nO material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 10, + "pre_title": "", + "title": "Aprendizagem de Geografia no Ensino Fundamental e TDIC", + "author": "Rosa Elisabete Militz Wypyczynski Martins e Roberto Souza Ribeiro", + "url": "https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/geografia-ef/apresentacao.html", + "img": "img/colecoes/ecd11.jpg", + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "No módulo “Aprendizagem de Geografia no Ensino Fundamental e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” tem-se como objetivo refletir sobre práticas de ensino e aprendizagem de Geografia com o uso das TDIC. É desenvolvida a problematização de conceitos geográficos e as utilizações no TDIC no âmbito da aprendizagem, articulando e analisando a realidade em que vivemos na intenção de favorecer o ensino-aprendizagem.\nO material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 11, + "pre_title": "", + "title": "Aprendizagem de Ciências no Ensino Fundamental e TDIC", + "author": "Marina Bazzo de Espíndola, Gabriela de Leon Nóbrega Reses, Patrícia Barbosa Pereira e Ivan Tavares Scotelari de Souza", + "url": "https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/ciencias-ef/menu-topicos.html", + "img": "img/colecoes/ecd12.jpg", + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "No módulo “Aprendizagem de Ciências no Ensino Fundamental e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” tem-se como objetivos proporcionar a compreensão do como as TDIC podem ser inseridas no processo de ensino e aprendizagem de conhecimentos científicos, estimular o(a) cursista a ter uma postura ativa e investigadora no decorrer dos estudos e, também, contribuir, por meio de fundamentação teórica e atividades práticas, para a ampliação de conhecimentos do(a) professor sobre essas tecnologias. Almeja-se que, ao final dos estudos do núcleo, você possa propor iniciativas de integração de TDIC na educação em Ciências Naturais, a partir das suas necessidades de ensino e das necessidades específicas desta área de conhecimento.\nO material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 12, + "pre_title": "", + "title": "Aprendizagem de Matemática no Ensino Médio e TDIC", + "author": "Marcus Vinicius de Azevedo Basso (UFRGS), Crediné Silva de Menezes (UFRGS), Márcia Rodrigues Notare Meneghetti (UFRGS), Fabiana Fattore Serres (Colégio de Aplicação/UFRGS) e Elisa Friedrich Martins (EMEF Dep. Marcírio Goulart Loureiro/POA-RS)", + "url": "https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/matematica-em/menu-topicos.html", + "img": "img/colecoes/ecd13.jpg", + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "No módulo “Aprendizagem de Matemática no Ensino Médio e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” propõe-se uma imersão na cultura digital pelos caminhos da Matemática. A intenção é ajudá-lo(a) a compreender como a incorporação do computador e da internet em nossas práticas pedagógicas podem apoiar o trabalho dos(as) professores(as) e propiciar aos(as) alunos(as) o aprendizado de Matemática de uma maneira mais profunda, com menos esforço “braçal” e mais satisfação. Acredita-se que a utilização de ferramentas digitais e algumas formas diferenciadas de trabalhar Matemática possam modificar e qualificar as aprendizagens, e espera-se que todos tenham a oportunidade de experimentar, dialogar, debater, refletir e, por fim, construir conhecimentos sobre uma nova forma de ensinar e aprender Matemática.\nO material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 13, + "pre_title": "", + "title": "Aprendizagem de Língua Portuguesa no Ensino Médio e TDIC", + "author": "Roxane Rojo (IEL-UNICAMP), Saulo da Silva Oliveira (ETEC Parque da Juventude, Centro Paula Sousa/SEE-SP), Jezreel Gabriel Lopes (IEL-UNICAMP, mestrado), João Reynaldo Pires Jr. (IEL-UNICAMP, mestrado) e Kátia Sayuri Fujisawa (IEL-UNICAMP, mestrado)", + "url": "https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/portugues-em2/menu-topicos.html", + "img": "img/colecoes/ecd14.jpg", + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "No módulo “Aprendizagem de Língua Portuguesa no Ensino Médio e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” são explorados os conhecimentos da esfera digital no uso da linguagem a partir de quatro perspectivas: a tecnológica, a científica, a literária e a jornalística. Pretende-se que, com a formação desenvolvida, você seja capaz de usar e identificar os textos multimodais e multissemióticos presentes no dia a dia e que também possa incorporar tal aprendizado à sua prática docente. Vale ressaltar que, em muitos momentos, você será convidado(a) a refletir, por meio de questionamentos, acerca de diversos assuntos relacionados com o conteúdo.\nO material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 14, + "pre_title": "", + "title": "Aprendizagem de Química no Ensino Médio e TDIC", + "author": "Edson Luiz Lindner - (CA/UFRGS), Victor João da Rocha Maia Santos e Gabriela da Fontoura Rodrigues Selmi", + "url": "https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/quimica-em/pagina-15.html", + "img": "img/colecoes/ecd15.jpg", + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "No módulo “Aprendizagem de Química no Ensino Médio e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” são organizados três momentos, que contemplam: a) a construção de olhares e reflexões sobre o papel das TDIC no processo de ensino-aprendizagem em Química; b) a utilização de vídeos na experimentação química; e c) a inserção e utilização de sistemas interativos, com destaque nos ambientes de autoria, como possibilidade de construir e representar o conhecimento químico. A dinâmica de estudo irá ocorrer tanto por meio de atividades de estudos teóricos quanto de desenvolvimento de atividades práticas.\nO material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 15, + "pre_title": "", + "title": "Aprendizagem de Física no Ensino Médio e TDIC", + "author": "Henrique César da Silva, Patrick de Souza Girelli, Rafaela Rejane Samagaia e Fernando da Silva Calsavara", + "url": "https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/fisica-em/pagina.html", + "img": "img/colecoes/ecd16.jpg", + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "No módulo “Aprendizagem de Física no Ensino Médio e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” serão apresentados e sugeridos modos de utilização de alguns conceitos e tecnologias digitais da informação e comunicação (TDIC) como forma de subsidiar a constituição de propostas didáticas no âmbito do ensino de Física. Para isso, nesse caso, a temática \"Nanociência & Nanotecnologias\" (N&N) foi escolhida como eixo deste núcleo. Assim, em um primeiro momento, a ideia é que se possa navegar e aprofundar melhor o entendimento dessa temática e sua relação com as TDIC. Em seguida, será importante lançar um olhar para a nossa realidade, com o intuito de perceber as potencialidades didáticas fomentadas pelas TDIC que emergem como possibilidades para o contexto em foco.\nO material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 16, + "pre_title": "", + "title": "Aprendizagem de Biologia no Ensino Médio e TDIC", + "author": "Simão Pedro Pinto Marinho e Alessandra Marinho", + "url": "https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/biologia-em2/menu-topicos.html", + "img": "img/colecoes/ecd17.jpg", + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "No módulo “Aprendizagem de Biologia no Ensino Médio e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” você será convidado(a) a refletir sobre a interface TDIC e Ensino de Biologia, (re)pensando sobre sua prática pedagógica e entrando em contato com novos recursos e ferramentas que apresentam as mais diversas potencialidades no contexto escolar. Serão explorados o uso das tecnologias digitais na sala de aula, a execução das atividades com ações de reflexão, levantamento de questões, elaboração de planos, organização, registro e socialização das narrativas sobre as atividades desenvolvidas a partir da integração das TDIC ao currículo de Biologia.\nO material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 17, + "pre_title": "", + "title": "Aprendizagem de Sociologia no Ensino Médio e TDIC", + "author": "Alexandro Dantas Trindade(Departamento de Ciência Política e Sociologia - UFPR/PR), Luciana Paula da Silva de Oliveira (Colégio Estadual Professor Algacyr Munhoz Maeder / Curitiba-PR) e Neli Gomes da Rocha (Programa de Pós-Graduação em Sociologia - UFPR/PR)", + "url": "https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/sociologia-em/menu-topicos.html", + "img": "img/colecoes/ecd18.jpg", + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "O módulo “Aprendizagem de Sociologia no Ensino Médio e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” é pensado como um meio de explorar questões sociológicas, bem como as relações sociais construídas temporal e historicamente que as contextualizam. Ademais, o núcleo ainda propõe reflexões sociológicas acerca do papel das tecnologias de informação e comunicação como base das relações sociais atuais, além de desenvolver atividades que proporcionem a reflexão crítica e a autonomia na criação e elaboração de conteúdos. Ler, refletir, produzir e intervir em sala de aula serão alguns dos caminhos sugeridos nessa empreitada.\nO material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 18, + "pre_title": "", + "title": "Aprendizagem de História no Ensino Médio e TDIC", + "author": "José Alves de Freitas Neto e José Antônio Ferreira da Silva Junior", + "url": "https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/historia-em/pagina_2.html", + "img": "img/colecoes/ecd19.jpg", + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "No módulo de “Aprendizagem de História no Ensino Médio e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” é proposta uma reflexão acerca dos conceitos tempo, memória e narrativa no âmbito do ensino de história. São discutidas questões gerais de história e sua relação com a cultura digital, bem como seus usos e possibilidades como fator favorecedor do ensino, a partir da interação e da aprendizagem colaborativa.\nO material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 19, + "pre_title": "", + "title": "Aprendizagem de Geografia no Ensino Médio e TDIC", + "author": "Cláudio Benito Oliveira Ferraz (UNESP - Pres.Prudente)", + "url": "https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/geografia-em/pagina-54.html", + "img": "img/colecoes/ecd20.jpg", + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "No módulo “Aprendizagem de Geografia no Ensino Médio e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” é apresentada a proposta de estimulá-lo(a) a criar novos pensamentos espaciais, articular e dominar conceitos e outros sentidos da linguagem geográfica, de maneira a entendê-la não como algo já estabelecido por especialistas, mas como um campo do pensamento que agencia as linguagens artísticas.\nO material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 20, + "pre_title": "", + "title": "Aprendizagem de Filosofia e TDIC", + "author": "Sérgio Paulino Abranches, Junot Cornélio Matos, Willamis Aprígio de Araújo, Eugênio Pacelle da Costa Cavalcante, Guilherme Jordão Macêdo Dias, Karla Epiphania Lins de Gois e Luis Lucas Dantas da Silva e Nilton Guimarães da Silva", + "url": "https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/filosofia/menu-topicos.html", + "img": "img/colecoes/ecd21.jpg", + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "No módulo “Aprendizagem de Filosofia e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” a Filosofia é apresentada como fator que não pode furtar-se a pensar a cultura digital e suas implicações. Em especial para o caso de professores de Filosofia: como trabalhar essa discussão contemporânea na sala de aula? Qual a sua relevância? Através da abordagem de alguns conceitos-chave, como identidade, juventude, cidadania e democracia, este material trata de oferecer algumas possibilidades de discussão em torno dessas questões.\nO material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 21, + "pre_title": "", + "title": "Linguagens do Nosso Tempo", + "author": "Maria Lucia Santaella Braga e Alexandre Santaella Braga", + "url": "https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/linguagens/pagina-22.html", + "img": "img/colecoes/ecd22.jpg", + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "No módulo “Linguagens do Nosso Tempo” do curso “Educação na Cultura Digital” tem-se o objetivo de refletir sobre práticas de ensino e aprendizagem de Linguagens do Nosso Tempo com o uso das TDIC. O núcleo apresenta os conceitos caracterizadores das linguagens atuais, a hipermídia e a transmídia com a finalidade de evidenciar que novas linguagens não se esgotam em si mesmas. Levantar e problematizar as implicações que a hipermídia, como a complexa linguagem que é própria das redes digitais e discutir os desafios que essas formas de aprendizagem estão trazendo para a educação, especialmente para aquela que ainda continua nostálgica e exclusivamente presa ao mundo do texto impresso.\nO material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 22, + "pre_title": "", + "title": "Tecnologias Digitais no Letramento Estatístico", + "author": "Ruy César Pietropaolo (UNIBAN), Nielce Meneguello Lobo da Costa (UNIBAN) e Rosangela de Souza Jorge Ando ", + "url": "https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/letramento-estatistico/menu-topicos.html", + "img": "img/colecoes/ecd23.jpg", + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "O módulo “Tecnologias Digitais no Letramento Estatístico” do curso “Educação na Cultura Digital” propõe atividades e experiências visando favorecer a construção de competências referentes ao letramento estatístico, o qual inclui: o domínio de conhecimentos básicos que permitam o desenvolvimento de competências estatísticas; o exercício do pensamento crítico acerca das informações de uma pesquisa para a tomada de decisões; e a utilização das tecnologias digitais para a coleta e a organização dos dados de uma pesquisa, visando a compreensão e intervenção na realidade da escola, bem como a obtenção de medidas e comunicação dos resultados.\nO material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 23, + "pre_title": "", + "title": "Jogos Digitais e Aprendizagem", + "author": "Isa Beatriz da Cruz Neves, Patrícia Rocha Rodrigues, Isa de Jesus Coutinho e Andersen Caribé de Oliveira", + "url": "https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/jogos/cenario.html", + "img": "img/colecoes/ecd24.jpg", + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "No módulo “Jogos Digitais e Aprendizagem” do curso “Educação na Cultura Digital” os jogos são vistos como formas de diversão interativa que proporcionam aprendizagem. Os jogos digitais podem simular ações como correr, dançar, jogar basquete, tênis, futebol, etc. Em geral, eles apresentam conflitos e competições que exigem cumprimento de regras, raciocínio lógico e uma boa dose de estratégia. Esses desafios contribuem para o desenvolvimento da visão periférica, concentração em diferentes atividades e desenvolvimento de habilidades para resolução de problemas. O objetivo do núcleo é pensar os jogos digitais em articulação com o ensino, bem como refletir sobre seus limites e possibilidades.\nO material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 24, + "pre_title": "", + "title": "Ética na Cultura Digital", + "author": "Sérgio Paulino Abranches, Junot Cornélio Matos, Karla Epiphania Lins de Gois, Luis Lucas Dantas da Silva, Nilton Guimarães da Silva, Willamis Aprígio de Araújo, Eugênio Pacelle da Costa Cavalcante e Guilherme Jordão Macêdo Dias", + "url": "https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/etica/menu-topicos.html", + "img": "img/colecoes/ecd25.jpg", + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "O módulo “Ética na Cultura Digital” do curso “Educação na Cultura Digital” parte da seguinte constatação: dentre uma série de questões contemporâneas relevantes envolvendo a cultura digital, discutidas em outros núcleos deste curso, inclui-se também um questionamento sobre ética. Este núcleo, então, discute algumas dessas questões, sem pretender esgotá-las. É proposta a reflexão sobre a relação entre Ética e Cultura Digital, discutindo os valores subjacentes ao uso das TDIC nas relações sociais e na educação e buscando analisar, de maneira vertical e interdisciplinar, as implicações éticas das diferentes possibilidades tecnológicas para a vida do ser humano.\nO material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 25, + "pre_title": "", + "title": "A Prática Docente no Ensino Fundamental e TDIC", + "author": "Darli Collares (UFRGS) e Nina Rosa Ventimiglia Xavier (Educação Básica)", + "url": "https://sgmd.nute.ufsc.br/content/especializacao-cultura-digital/fundamental/pagina-2.html", + "img": "img/colecoes/ecd26.jpg", + "score": 100, + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "O módulo “A Prática Docente no Ensino Fundamental e Tecnologias Digitais de Informação e Comunicação (TDIC)” do curso “Educação na Cultura Digital” busca refletir sobre questões inerentes às especificidades da docência nos Anos Iniciais e, também, sobre as possibilidades e implicações do uso de TDIC nessa fase de escolarização, aprofundar os conhecimentos sobre o processo de aprendizagem e propor um novo olhar sobre as práticas pedagógicas baseando-se em Piaget.\nO material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de educadores. O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + } + ], + "score": 100, + "img": "img/colecoes/ecd.png", + "duration": 50, + "created_at": "2015-06-13T00:31:24.484Z", + "updated_at": "2015-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "O material oferece subsídios para uma formação apoiada nos diversos âmbitos das Tecnologias Digitais de Informação e Comunicação (TDIC) em currículos escolares, além de explorar, demonstrar e analisar as possibilidades criativas e elementos que contribuam para a construção de novas dinâmicas para a formação de professores(as) com foco na integração das Tecnologias de Informação e Comunicação nas escolas e seus diversos usos.", + "historic": "O curso foi criado numa parceria entre Ministério da Educação e Universidade Federal de Santa Catarina, tendo como público alvo professores, coordenadores, gestores pedagógicos e outros membros da equipe gestora que fossem responsáveis pelo processo de formação da escola, além de multiplicadores dos Núcleos de Tecnologia Educacional (NTE) e Núcleos de Tecnologia Municipal (NTM). O curso foi concluído em 2015, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 2, + "name": "Prevenção dos Problemas Relacionados ao Uso de Drogas", + "tags": [ + { + "name": "Drogas" + }, + { + "name": "Prevenção" + }, + { + "name": "Conselheiros" + }, + { + "name": "SENAD" + }, + { + "name": "Contextos" + } + ], + "developed": "Nute UFSC", + "developedurl": "http://lantec.ufsc.br", + "topic_name": "Módulos", + "topics": [ + { + "id": 0, + "pre_title": "Iniciando a Trilha", + "title": "", + "author": "Nute UFSC", + "url": "https://sgmd.nute.ufsc.br/content/sgmd-resources-conselheiros/ebook/iniciando-a-trilha.html", + "img": "img/colecoes/senad1.jpg", + "tags": [ + { + "name": "Drogas" + }, + { + "name": "Prevenção" + }, + { + "name": "Conselheiros" + }, + { + "name": "SENAD" + }, + { + "name": "Contextos" + } + ], + "score": 100, + "duration": 50, + "created_at": "2014-06-13T00:31:24.484Z", + "updated_at": "2014-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "O módulo “Iniciando a trilha” do curso “Prevenção dos Problemas Relacionados ao Uso de Drogas” tem como objetivo contextualizar a história do consumo de drogas, com o intuito de problematizar o tema. Busca introduzir material do curso, que almeja desconstruir visões reducionistas, trabalhando a partir de três dimensões: sujeito, contexto, e drogas. O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de conselheiros e agentes comunitários envolvidos na prevenção do uso de drogas no país. O curso foi concluído em 2014, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 1, + "pre_title": "Módulo 1: ", + "title": "Sujeitos, contextos e drogas", + "author": "Nute UFSC", + "url": "https://sgmd.nute.ufsc.br/content/sgmd-resources-conselheiros/ebook/modulo-1.html", + "img": "img/colecoes/senad2.jpg", + "tags": [ + { + "name": "Drogas" + }, + { + "name": "Prevenção" + }, + { + "name": "Conselheiros" + }, + { + "name": "SENAD" + }, + { + "name": "Contextos" + } + ], + "score": 100, + "duration": 50, + "created_at": "2014-06-13T00:31:24.484Z", + "updated_at": "2014-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "O módulo “Sujeitos, contextos e drogas” do curso “Prevenção dos Problemas Relacionados ao Uso de Drogas” expõe o contexto histórico, social e cultural de usuários de drogas, bem como seus padrões e tendências, buscando mostrar ao leitor os diferentes cenários existentes neste âmbito. São levantadas questões acerca dos sujeitos usuários, as substâncias individualmente e seus respectivos efeitos. O módulo ainda apresenta pesquisas e entrevistas com professores de diversas áreas do conhecimento relacionadas ao estudo de substâncias psicoativas e seus dependentes. O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de conselheiros e agentes comunitários envolvidos na prevenção do uso de drogas no país. O curso foi concluído em 2014, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 2, + "pre_title": "Módulo 2: ", + "title": "Redes para promoção, prevenção, redução de danos e tratamento", + "author": "Nute UFSC", + "url": "https://sgmd.nute.ufsc.br/content/sgmd-resources-conselheiros/ebook/modulo-2.html", + "img": "img/colecoes/senad3.jpg", + "tags": [ + { + "name": "Drogas" + }, + { + "name": "Prevenção" + }, + { + "name": "Conselheiros" + }, + { + "name": "SENAD" + }, + { + "name": "Contextos" + } + ], + "score": 100, + "duration": 50, + "created_at": "2014-06-13T00:31:24.484Z", + "updated_at": "2014-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "O módulo “Redes para promoção, prevenção, redução de danos e tratamento” do curso “Prevenção dos Problemas Relacionados ao Uso de Drogas” apresenta o histórico recente da bioética, os conceitos e riscos de vulnerabilidade, fatores de proteção e prevenção do uso de drogas, além de entrevistas com profissionais que atuam no campo de programas preventivos,visam trazer à tona a importância de informar a população acerca da dependência e de desenvolver políticas multidisciplinares e intersetoriais. O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de conselheiros e agentes comunitários envolvidos na prevenção do uso de drogas no país. O curso foi concluído em 2014, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 3, + "pre_title": "Módulo 3: ", + "title": "Políticas Públicas e Legislação sobre Drogas", + "author": "Nute UFSC", + "url": "https://sgmd.nute.ufsc.br/content/sgmd-resources-conselheiros/ebook/modulo-3.html", + "img": "img/colecoes/senad4.jpg", + "tags": [ + { + "name": "Drogas" + }, + { + "name": "Prevenção" + }, + { + "name": "Conselheiros" + }, + { + "name": "SENAD" + }, + { + "name": "Contextos" + } + ], + "score": 100, + "duration": 50, + "created_at": "2014-06-13T00:31:24.484Z", + "updated_at": "2014-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "O módulo “Políticas Públicas e Legislação sobre Drogas” do curso “Prevenção dos Problemas Relacionados ao Uso de Drogas” evidencia a relevância das medidas intersetoriais tomadas publicamente e o compromisso de cada um para o melhor cumprimento destas. Ainda é apresentada a relação entre os conselhos e movimentos sociais na atuação com fatores protetores e a importância das políticas de saúde mental e psicossociais presentes no SUS. O material foi elaborado para este curso de Especialização, na modalidade de ensino a distância, tendo em vista o seu papel na formação continuada de conselheiros e agentes comunitários envolvidos na prevenção do uso de drogas no país. O curso foi concluído em 2014, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + } + ], + "score": 100, + "img": "img/colecoes/senad.png", + "duration": 50, + "created_at": "2014-06-13T00:31:24.484Z", + "updated_at": "2014-06-16T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "Visa propiciar aos leitores a compreensão da conjuntura social dos usuários e dependentes de substâncias psicoativas, bem como problematizar as dimensões trabalhadas: sujeito, contexto e drogas. Tem como objetivo possibilitar uma formação crítica, que respeite a multiplicidade dos conhecimentos neste campo e que consolide o compromisso com práticas comprometidas com a transformação da realidade social. O material ainda traz pesquisas, entrevistas com profissionais da área e projetos de intervenção elaborados pelos próprios cursistas.", + "historic": "A 6ª edição do Curso de Prevenção dos Problemas Relacionados ao Uso de Drogas – Capacitação para Conselheiros e Lideranças Comunitárias foi promovido pela Secretaria Nacional de Políticas Sobre Drogas do Ministério da Justiça – SENAD/MJ em parceria com Universidade Federal de Santa Catarina. Foram oferecidas 40 mil vagas para conselheiros e lideranças comunitárias de todo o Brasil que receberam capacitação para atuar na prevenção de crack, álcool e outras drogas. O curso foi concluído em 2014, e agora o material está disponível para leitura a todos que tiverem interesse na temática.", + "likes_count": 3 + }, + { + "id": 3, + "name": "Banco de Práticas Inspiradoras", + "tags": [ + { + "name": "Práticas" + }, + { + "name": "Casos" + }, + { + "name": "Competências gerais" + }, + { + "name": "Base Nacional Comum Curricular" + }, + { + "name": "BNCC" + } + ], + "developed": "Instituto Península", + "developedurl": "http://www.institutopeninsula.org.br", + "topic_name": "Casos", + "topics": [ + { + "id": 0, + "pre_title": "Caso 1: Cara de Brasil (Competência 1)", + "title": "", + "author": "Beatriz Souza Duarte e Bruna Lúcia Frigo", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso01.html", + "img": "img/colecoes/boas1.jpg", + "tags": [ + "Educação por projetos", + "Relações étnico-raciais", + "Cultura afro", + "Cultura indígena", + "Identidade" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "O projeto “Brasil, cara de quê?”, das professoras Beatriz Duarte e Bruna Frigo, da Escola Municipal de Educação Infantil Parque das Nações I, em São Paulo, ajudou alunos da educação infantil a identificarem as principais etnias que formam a população brasileira – negra, indígena e europeia. Por meio das memórias da infância de seus pais, histórias de migração e miscigenação e de vivências lúdicas com representantes de cada cultura, as crianças conscientizaram-se a respeito de quem são e de onde vêm seus costumes. Os resultados mais relevantes foram a desconstrução de estereótipos e preconceitos e a autoaceitação dos alunos da etnia a qual pertencem. Os assuntos abordados no projeto foram inspirados no tema do projeto político-pedagógico da escola de 2016: as relações étnico-raciais.", + "likes_count": 3 + }, + { + "id": 1, + "pre_title": "Caso 2: Educação aplicada à vida no sertão (Competência 2)", + "title": "", + "author": "José Hélio Pereira", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso02.html", + "img": "img/colecoes/boas2.jpg", + "tags": [ + "Educação por projetos", + "Investigação", + "Meio ambiente", + "Água", + "Decantação", + "Resolução de problemas" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "\"Uma solução alternativa para o tratamento simplificado da água” é o nome do projeto do professor José Helio Pereira, desenvolvido na escola Casimira Leite Montenegro, em Desterro (PB), em 2017. Com clima semiárido, a região enfrentou problemas de abastecimento de água, o que deixou a população preocupada. Visando melhorar as condições da água barrenta fornecida por caminhões-pipa à comunidade, o professor do 4º ano propôs a seus alunos que pesquisassem formas de filtrar a água. Após leituras e investigações científicas, os alunos descobriram uma grande aliada encontrada na zona em que vivem: a acácia branca (Moringa oleífera) e comprovaram, na prática, a efetividade do processo de decantação estimulado pela semente da planta, que separa o barro da água. ", + "likes_count": 3 + }, + { + "id": 2, + "pre_title": "Caso 3: Pertencer para preservar (Competência 3)", + "title": "", + "author": "Laçanã Costa Simões", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso03.html", + "img": "img/colecoes/boas3.jpg", + "tags": [ + "Educação por projetos", + "Artes", + "Patrimônio", + "Preservação", + "Pertencimento", + "Diálogo", + "Cooperação" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "Na Escola Municipal Governador Roberto Santos, em Salvador, a professora de artes Iaçanã Simões desenvolveu, em 2017, o projeto “Seja bem-vindo e volte sempre! Um olhar para a conservação do patrimônio público escolar através da arte”. As duas mensagens contidas no título do projeto foram desenhadas, inicialmente, nas portas das turmas do ensino fundamental. A ideia da intervenção era conservar o patrimônio escolar e educar sobre a preservação do espaço público em geral, pois a professora observou que os estudantes não degradavam os ambientes nos quais tinham realizado algum projeto artístico. Além das mensagens, as portas ganharam ilustrações escolhidas por cada turma. Os alunos gostaram tanto da atividade que pintaram, também, outros ambientes da escola.", + "likes_count": 3 + }, + { + "id": 4, + "pre_title": "Caso 5: Curiosidade científica (Competência 5) ", + "title": "", + "author": "Maria Cristina Fachin Liberalesso", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso05.html", + "img": "img/colecoes/boas5.jpg", + "tags": [ + "Educação por projetos", + "Investigação", + "Pesquisa na internet", + "Raciocínio lógico", + "Insetos" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "Na cidade de Pinhal Grande (RS), fica a Escola Municipal de Educação Fundamental São Thomaz de Aquino, que, em 2016, teve um de seus banheiros infestado por insetos. A visita inesperada dos animais e a curiosidade dos alunos em saber que bichos eram aqueles, se eram venenosos, e, principalmente, porque havia tantos deles ali, levou a professora do 4º ano, Maria Cristina Fachin, a explorar a pesquisa científica com seus alunos. Ela recolheu uma amostra do inseto e incitou os estudantes a procurarem informações em fontes confiáveis, dando origem ao projeto “Pequeno Cientista”. Com isso, as crianças puderam aprender noções de metodologia de pesquisa e testaram hipóteses práticas para entender o que causou a infestação no banheiro da escola.", + "likes_count": 3 + }, + { + "id": 5, + "pre_title": "Caso 6: O Haiti é aqui (Competência 1)", + "title": "", + "author": "Diana Aparecida Feuser Ribeiro", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso06.html", + "img": "img/colecoes/boas6.jpg", + "tags": [ + "Educação por projetos", + "Berçário", + "Adaptação", + "Diversidade de saberes", + "Intercâmbio de culturas", + "Identidade" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "Em 2017, havia um bebê haitiano na turma do berçário 1 do Centro de Educação Infantil Castelo Branco, em Joinville (SC), e a pedagoga responsável, Diana Ribeiro, preocupou-se com a inclusão da família nas atividades escolares, o que é crucial para essa faixa-etária. Como os pais do bebê se comunicavam mal em português, a professora decidiu aprender expressões na língua nativa deles. Uma dessas expressões, “Sali, koman ouye?” (Olá, como vai?), nomeou o projeto de integração entre as culturas haitiana e brasileira. Ao ensinar os costumes locais, o trabalho beneficiou não somente a família estrangeira, mas também as famílias brasileiras procedentes de outros estados. O incentivo a essa descoberta cultural se materializou na decoração e em outras atividades, e trouxe para o berçário um pouco do lar de cada bebê.", + "likes_count": 3 + }, + { + "id": 6, + "pre_title": "Caso 7: Mensagens para um mundo sustentável (Competência 7)", + "title": "", + "author": "Martamiria Delmiro dos Santos", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso07.html", + "img": "img/colecoes/boas7.jpg", + "tags": [ + "Educação por projetos", + "Consciência socioambiental", + "Consumo responsável", + "Mineralogia", + "Coleta seletiva" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "Trabalhar a sustentabilidade com foco na mineralogia foi o diferencial do projeto da Escola Municipal Dr. Luiz Gonzaga Maranhão, em Jaboatão dos Guararapes (PE), que recebeu o nome “Educação ambiental: uso consciente dos recursos minerais”. Estimulada pelo tema do projeto político-pedagógico da escola em 2016, a professora Martamiria dos Santos, do 3º ano, decidiu mostrar aos alunos de onde vêm os materiais usados para construir objetos cotidianos, como cadeiras, paredes, portas, etc. Os alunos entenderam como as matérias-primas minerais são formadas na natureza, o valor comercial que possuem e a importância de usá-las de forma consciente, o que os estimulou a praticar a reciclagem e a preservação ambiental.", + "likes_count": 3 + }, + { + "id": 7, + "pre_title": "Caso 8: A África me representa (Competência 8)", + "title": "", + "author": " Márcia Theodorico Mezzomo", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso08.html", + "img": "img/colecoes/boas8.jpg", + "tags": [ + "Educação por projetos", + "Relações étnico-raciais", + "Cultura afro", + "Preconceito", + "Identidade", + "Representatividade", + "Diálogo" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "No entorno da Creche Morro da Queimada, em Florianópolis, há forte presença da cultura afro-brasileira. Na turma de educação infantil, por exemplo, metade dos alunos são negros, e isso fez com que a professora Marcia Mezzomo decidisse estimular a representatividade dessas crianças desde cedo. Para tanto, em consonância com a lei federal 10.639/03, sobre ensino da história da cultura afro-brasileira, ela trouxe para o imaginário infantil figuras como heróis, príncipes e princesas africanos, e pode explorar a diversidade cultural e as relações étnico-culturais a partir do tema “Do rei do fogo ao rei do samba: rainha e rei da África eu sou”. A população local, como familiares e representantes de grupos artísticos, contribuiu para mostrar às crianças as influências mais marcantes da cultura africana na cultura nacional.", + "likes_count": 3 + }, + { + "id": 8, + "pre_title": "Caso 9: Antídoto contra o preconceito (Competência 9)", + "title": "", + "author": "Lorena Bárbara Santos Costa", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso09.html", + "img": "img/colecoes/boas9.jpg", + "tags": [ + "Educação por projetos", + "Relações étnico-raciais", + "Cultura afro", + "Samba", + "Identidade", + "Representatividade", + "Bullying", + "Preconceito", + "Empatia", + "Respeito", + "Diversidade" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "A cultura afro-brasileira tem grande expressividade em Salvador, onde as salas de aulas costumam ser compostas, principalmente, por alunos negros, como no 5º ano da Escola Municipal Deputado Gersino Coelho. Ao perceber que seus alunos tinham dificuldade em aceitar-se como negros, e que tratavam uns ao outros de forma preconceituosa, a professora Lorena Costa usou a temática “Vem sambar e aprender: o samba como instrumento de resistência e representação da cultura afro-brasileira” para abordar a descendência africana no país. O resgate do samba da Bahia, ao longo das atividades, foi todo permeado por aspectos da história e da cultura afro, como a trajetória de resistência das comunidades quilombolas. Como resultado, a familiarização com essa cultura despertou a empatia, o respeito e o diálogo entre os alunos.", + "likes_count": 3 + }, + { + "id": 9, + "pre_title": "Caso 10: Um olhar de esperança (Competência 10)", + "title": "", + "author": "João Paulo Vicente da Silva", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso10.html", + "img": "img/colecoes/boas10.jpg", + "tags": [ + "Educação por projetos; Inclusão; Esporte; Adaptação curricular; Empatia" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "Em 2017, o aluno cadeirante Renner Luís entrou no 5o ano do Centro Infantil Estrela do Mar, em Extremoz (RN), e ninguém imaginava que alcançaria o 3º lugar estadual, e 5º nacional, em campeonatos paralímpicos de bocha. As conquistas do garoto foram possíveis graças ao empenho do professor de educação física João Paulo da Silva, que pesquisou maneiras de incluí-lo na disciplina e em outras atividades escolares, criando o projeto “Contribuições da educação física na inclusão das pessoas com paralisia cerebral no ensino regular”. A participação de Renner nas aulas e campeonatos ajudaram a melhorar a sociabilidade dos colegas com ele, além de ter contribuído positivamente para sua autoestima.", + "likes_count": 3 + }, + { + "id": 10, + "pre_title": "Caso 11: Fábulas favorecem alfabetização de crianças (Competência 4)", + "title": "", + "author": "Erika Silva do Carmo", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso11.html", + "img": "img/colecoes/boas11.jpg", + "tags": [ + "Educação por projetos", + "Narração de histórias", + "Fábulas", + "Alfabetização", + "Cooperação" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "Desde 2016 existe o projeto “Minha escola lê e multiplica saberes: viajando no mundo das fábulas” na Escola Estadual Coronel Cruz, em Itacoatiara (AM). Idealizado pela professora do 1º ano Erika do Carmo o projeto começou com fábulas clássicas, como a da galinha dos ovos de ouros, evoluiu para lendas da região amazônica, como a do boto-cor-de-rosa, até trabalhar a autoria própria das crianças. As principais atividades que estimularam os pequenos foram: assistir animações, ler fábulas e reinterpretá-las com desenhos, oralmente e textualmente, além de acompanhar narrativas com teatro de fantoches. O uso das diferentes linguagens melhorou o processo de alfabetização da turma, explorando tópicos como vocabulário e separação de sílabas.", + "likes_count": 3 + }, + { + "id": 11, + "pre_title": "Caso 12: Horta conecta famílias à escola (Competência 2)", + "title": "", + "author": "Cleide Maria de Souza", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso12.html", + "img": "img/colecoes/boas12.jpg", + "tags": [ + "Educação por projetos", + "Oralidade", + "Ciências", + "Controle biológico", + "Horta", + "Consciência socioambiental", + "Cooperação", + "Participação dos pais" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "A participação familiar foi crucial para o desenvolvimento do projeto “Horta Vertical: Ajudantes da Natureza” na Centro de Ensino Fundamental Cerâmicas Reunidas Dom Bosco, em Brasília (DF). Comandada pela professora Cleide de Souza, a educação infantil pode entender como a natureza trabalha de forma harmônica e a importância de cada ser vivo para manter a estabilidade ambiental. A relação entre insetos e plantas foi focalizada e, com a ajuda das famílias, hortaliças foram plantadas verticalmente em um muro ao lado da sala de aula. A partir de observação contínua da horta da escola, além de visita a uma horta orgânica de uma das mães da turma, as crianças aprenderam que os insetos são verdadeiros “ajudantes da natureza”, como elas mesmas definiram.", + "likes_count": 3 + }, + { + "id": 12, + "pre_title": "Caso 13: Meu espelho negro (Competência 8)", + "title": "", + "author": "Cristiane Santos de Melo", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso13.html", + "img": "img/colecoes/boas13.jpg", + "tags": [ + "Educação por projetos", + "Identidade", + "Representatividade", + "Mulher negra", + "Empoderamento feminino", + "Cabelo crespo", + "Ganhadeiras de Itapuã" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "Em 2015, a professora Cristiane de Melo, do Centro Municipal de Educação Infantil Dr. Djalma Ramos, em Lauro de Freitas (BA), valorizou as raízes africanas com o empoderamento do público feminino. O âmbito social, especialmente a mídia, poucas vezes apresenta mulheres negras como referencial de beleza, e as crianças da turma não consideravam bonita uma mulher sem pele clara e cabelos lisos. Ao convidar a cantora negra Mariene de Castro como personalidade de referência, esse cenário mudou. Foi aí que surgiu o projeto “Mariene: A flor que desabrochou nossa gente”. Por meio de sambas da cantora em parceria com um grupo de ganhadeiras, as meninas vivenciaram a representatividade e aprenderam a valorizar seus traços, como o cabelo crespo. O projeto também ajudou a elevar a autoestima de mães e funcionárias da escola.", + "likes_count": 3 + }, + { + "id": 13, + "pre_title": "Caso 14: Vestígios do tempo (Competência 1)", + "title": "", + "author": "Lilian Mara Bonette Bianchini", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso14.html", + "img": "img/colecoes/boas14.jpg", + "tags": [ + "Educação por projetos", + "Estudo do meio", + "Arqueologia", + "Cultura indígena", + "Caminho de Peabiru", + "Vestígios líticos" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "Na cidade de Engenheiro Beltrão (PR) há vestígios do Caminho de Peabiru, rota aberta por civilizações pré-coloniais que percorriam territórios entre os Oceanos Pacífico e Atlântico. A professora de história Lilian Bianchini, da Escola Municipal de Ensino Fundamental Maria Aparecida Medeiros, criou o projeto “Viajando pelos caminhos da nossa história” para mostrar aos alunos do ensino fundamental as marcas dos povos indígenas, habitantes do território nacional muito antes da chegada dos europeus. A turma ganhou uma “mala de exploração”, onde guardavam o caderno com o registro de suas descobertas a respeito da história e cultura desses povos. A visita a museus da região dedicados ao tema, além da realização de um percurso da rota histórica, deram insumos práticos para a pesquisa dos alunos.", + "likes_count": 3 + }, + { + "id": 14, + "pre_title": "Caso 15: Além da imaginação (Competência 7) ", + "title": "", + "author": "Francisca Deusineide dos Santos Nasário", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso15.html", + "img": "img/colecoes/boas15.jpg", + "tags": [ + "Educação por projetos", + "Pesquisa de campo", + "Lenda urbana", + "Tradição oral", + "Conto", + "Leitura", + "Reescrita", + "Rosa dos ventos" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "No projeto “A escola onde eu estudo e uma lenda tenebrosa”, da professora Francisca Nasário, os curiosos alunos do 4º ano investigaram se era verdadeira a lenda de que a escola teria sido construída no terreno de um antigo cemitério. Após entrevistas com antigos moradores, a turma relacionou as histórias da construção da escola às da formação de Pau dos Ferros (RN), e elaborou de uma linha do tempo. Para apresentar o gênero terror e suspense, a professora pediu aos alunos que produzissem as próprias lendas sobre a escola, inspiradas no que leram ou ouviram, aprendendo com a escrita noções de gênero, ortografia e paragrafação. Os contos reescritos foram lidos em sala de aula e integraram a exposição do Dia do Folclore da Escola Estadual Ubiratan Pereira Galvão.", + "likes_count": 3 + }, + { + "id": 15, + "pre_title": "Caso 16: Redescoberta indígena (Competência 3)", + "title": "", + "author": "Flávia Roberta Alves Costa", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso16.html", + "img": "img/colecoes/boas16.jpg", + "tags": [ + "Educação por projetos", + "Arte indígena", + "Cultura indígena", + "Identidade", + "Representatividade" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "O projeto “Inspirações indígenas” foi criado pela professora de artes Flávia Costa para quebrar estereótipos sobre o que é ser indígena nos dias de hoje. Em 2017, a Escola Municipal Divino Espírito Santo, no Recife, recebeu a visita de quatro índios fulni-ôs, que conversaram com os alunos. Como os estudantes ficaram interessados na pintura corporal dos índios, Flávia explicou conceitos de produções artísticas originais, criações inspiradas nelas e cópias, depois, relacionou a pintura corporal com a body art. Os alunos pintaram o próprio corpo com as palavras força, fé, luta, cultura e resistência. A professora também levou fotos das expressões artísticas de quatro etnias presentes em Pernambuco e deu uma oficina de tramas, reciclando sobras de papéis.", + "likes_count": 3 + }, + { + "id": 16, + "pre_title": "Caso 17: Além das fronteiras (Competência 1)", + "title": "", + "author": "Patrícia dos Santos Lima", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso17.html", + "img": "img/colecoes/boas17.jpg", + "tags": [ + "Educação por projetos", + "Pesquisa na internet", + "Oralidade", + "Cultura", + "Gamificação" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "Criado pela professora de inglês Patrícia Lima da Escola Estadual de Ensino Fundamental e Médio Marcelo Candia Subsede I, de Porto Velho (RO), o projeto “Viagem inglesa” pede ao ensino médico que “explore” um país de língua inglesa. Cada turma escolhe um país anglófono e tem de buscar informações históricas, geográficas, econômicas e culturais para apresentar aquela realidade numa feira multicultural aberta à comunidade. Os grupos ficam responsáveis por apresentações de dança, teatro, descrições de pratos típicos, entre outras, com parte dessas vivências faladas em inglês. Em paralelo, a professora faz um trabalho de tutoria, ajudando, por exemplo, a apurar os critérios de pesquisa na web para encontrar informações de fontes confiáveis.", + "likes_count": 3 + }, + { + "id": 17, + "pre_title": "Caso 18: Relaxar e dialogar para aprender (Competência 8)", + "title": "", + "author": "Carolina Corado da Silva Oliveira", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso18.html", + "img": "img/colecoes/boas18.jpg", + "tags": [ + "Educação por projetos", + "Ansiedade", + "Relaxamento", + "Diálogo", + "Protagonismo", + "Autonomia", + "Paulo Freire" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "O projeto “Aprender a relaxar e relaxar para aprender: metodologias ativas de ensino em biologia” desenvolvido pela professora Carolina Oliveira com os 1º e 3º anos do Instituto Federal do Rio Grande do Norte, propunha que os alunos se conhecessem melhor, reconhecessem estados de ansiedade para poder cuidar da própriab saúde física e emocional. Carolina aproximou-se de técnicas comuns à meditação e ao mindfulness para priorizar estratégias de diálogo e facilitar os quatro módulos criados para o ensino de biologia: os alunos conheceram conceitos de metodologia, discutiram bioquímica e nutrição ao andarem pelo jardim, responderam perguntas sobre os grupos alimentares e debateram metabolismo em um jogo, e trabalharam citologia ao vivenciarem experiências em sala, comparando as reações de infusão do chá em água quente e em água fria.", + "likes_count": 3 + }, + { + "id": 18, + "pre_title": "Caso 19: Os cordéis da minha terra (Competência 1)", + "title": "", + "author": "José Souza dos Santos", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso19.html", + "img": "img/colecoes/boas19.jpg", + "tags": [ + "Educação por projetos", + "Cultura nordestina", + "Folclore", + "Produção artística", + "Cordel", + "Lampião" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "O professor de português José dos Santos pediu aos alunos do 8º ano da Escola Municipal de Paripiranga (BA) que se inspirassem na tradição oral de familiares mais velhos, muitos analfabetos, para ir às ruas colher narrativas fantásticas. Após gravar ou anotar as histórias, os textos passariam da prosa ao verso, mais especificamente, ao cordel. Surgia o projeto “Cordelize a vida! Valorize a sua cultura!”. Os 24 cordéis escritos pelos alunos foram apresentados à comunidade escolar em uma “tarde de autógrafos”, e os entrevistados que deram origem a eles ganharam um livreto correspondente à história que contaram. Além disso, foram produzidos 40 audiolivros para distribuir gratuitamente os cordéis aos estudantes com deficiência visual.", + "likes_count": 3 + }, + { + "id": 19, + "pre_title": "Caso 20: Experimentação robótica (Competência 2)", + "title": "", + "author": "Diogo Tiago dos Santos", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso20.html", + "img": "img/colecoes/boas20.jpg", + "tags": [ + "Educação por projetos", + "Tecnologia", + "Robótica", + "Soluções de problemas", + "Autonomia" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "O projeto “A criação do grupo de física e robótica da Escola Estadual Ana Lins”, em São Miguel dos Campos (AL), começou com um kit de robótica encontrado no almoxarifado da escola em 2015. Desde então, o professor de física Diogo dos Santos coordena fundamentos da robótica no contraturno escolar para criar soluções que podem ser úteis à sociedade, como o reaproveitamento da água do ar condicionado para irrigação, uma lixeira “inteligente” que ajuda a separar materiais para reciclagem e um dispositivo para pacientes acamados pedirem ajuda com mais facilidade. Além disso, Diogo pediu que os alunos produzissem artigos científicos para apresentar à comunidade acadêmica o protótipo desenvolvido, trabalhando não apenas física, como também leitura e escrita.", + "likes_count": 3 + }, + { + "id": 20, + "pre_title": "Caso 21: Vivências como fundamento da aprendizagem (Competência 7)", + "title": "", + "author": "Maria do Socorro Braga Reis", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso21.html", + "img": "img/colecoes/boas21.jpg", + "tags": [ + "Educação por projetos", + "Crônica", + "Etnografia", + "Vivências", + "Fotografia", + "Reescrita", + "Autoestima" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "A professora de português Maria Reis elaborou o projeto “Histórias qu’eu vi-vi: crônicas etnográficas” para os jovens desenvolver habilidades mais apuradas de escrita, retratando atividades e hábitos cotidianos da comunidade paraense de Bragança. Maria apresentou o gênero crônica, explicou o conceito de etnografia e mostrou vídeos que abordavam o fazer etnográfico. Os alunos foram a campo, registraram suas descobertas com fotos e montaram na escola um mural com as imagens. Depois, levaram-no para uma praça perto da escola, onde expuseram as fotos à comunidade. Para a escrita da crônica, cada estudante produziu um texto sobre a prática desenvolvida. As 20 crônicas etnográficas produzidas pelo 2º ano do ensino médio da Escola Estadual Yolanda Chaves foram reunidas em um aplicativo e no site do governo do Estado.", + "likes_count": 3 + }, + { + "id": 21, + "pre_title": "Caso 22: A força da tradição pesqueira está com eles (Competência 6)", + "title": "", + "author": "Josiane Mendes Bezerra", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso22.html", + "img": "img/colecoes/boas22.jpg", + "tags": [ + "Educação por projetos", + "Pesca artesanal", + "Educação profissionalizante", + "Turismo", + "Alunos multiplicadores", + "Patrimônio cultural", + "Respeito", + "Empatia", + "Cultura caiçara" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "O projeto “Fazendo e acontecendo: pesca artesanal da tainha” foi estruturado pela professora Josiane Bezerra para mobilizar da população sobre o resgate histórico-cultural dessa pesca. Os 150 alunos do ensino médio integrado da Escola de Educação Básica Maria Rita Flor, voltado à educação profissionalizante, assistiram a uma aula com pescadores. Daí, buscaram estudos científicos para aprofundar os conhecimentos, criando 12 pôsteres técnico-científicos com enfoques que variaram da história da pesca e do ciclo da tainha a receitas de pratos típicos da região. Baseados em um documentário sobre os pescadores de Bombinhas (SC), os jovens fizeram uma encenação, que mobilizou os professores de geografia, história, matemática e música. Além disso, atuaram como “guias de turismo” ao explicar a pesca artesanal e apresentar a cultura dos pescadores a comunidades locais e visitantes.", + "likes_count": 3 + }, + { + "id": 22, + "pre_title": "Caso 23: Protagonismo na tela do cinema (Competência 5)", + "title": "", + "author": "Jayse Antonio da Silva Ferreira", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso23.html", + "img": "img/colecoes/boas23.jpg", + "tags": [ + "Educação por projetos", + "Cinema", + "Protagonismo", + "Autonomia", + "Participação dos pais", + "Preconceito", + "Inclusão" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "Criado pelo professor de arte Jayse Ferreira, o projeto “Vamos enCURTAr essa história?” nasceu com a proposta de os alunos produzirem curtas-metragens a partir dos próprios referenciais. Os dois primeiros curtas eram releituras de outras obras, mas para o terceiro o professor sugeriu um trabalho autoral: os alunos teriam que escrever histórias referentes à escola e a um tema social. Para tal, pediu ajuda de egressos da escola em oficinas de dinâmica corporal e de um escritor da cidade para aulas de roteiro. O argumento do suspense “Entre dois lados”, de 17 minutos, surgiu do depoimento de um morador que perdeu a perna após um acidente em que dirigia alcoolizado. Os curtas dos alunos da Escola de Referência em Ensino Médio Frei Orlando foram exibidos na praça central de Itambé (PE).", + "likes_count": 3 + }, + { + "id": 23, + "pre_title": "Caso 24: O celular como ferramenta pedagógica (Competência 5)", + "title": "", + "author": "Erizaldo Cavalcanti Borges Pimentel", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso24.html", + "img": "img/colecoes/boas24.jpg", + "tags": [ + "Educação por projetos", + "Cinema", + "Celulares", + "Cultura digital", + "Pensamento crítico", + "Cooperação", + "Responsabilidade" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "Contrariando a norma, que proibia o uso do celular em horário de aula, o professor Erizaldo Pimentel criou o projeto “Cine com ciência: luz, câmera... Educação!”. Nele, alunos 6º ao 9º ano do Centro de Ensino Fundamental 01 do Cruzeiro, na região administrativa de Brasília (DF), têm que produzir vídeos com seus smartphones. O professor ensina conceitos da linguagem cinematográfica, e detalha as etapas de pré-produção, em que os alunos devem elaborar a narrativa e o roteiro técnico, estimulando os estudantes à leitura, também analisa cenas de filmes e discute enquadramento e posicionamento de câmera. Os temas estão relacionados ao mundo dos estudantes, com forte traço social e desestimulando a violência. Em três anos de projeto, são cerca de 50 curtas finalizados.", + "likes_count": 3 + }, + { + "id": 24, + "pre_title": "Caso 25: Aplicativo para a saúde do jovem (Competência 2)", + "title": "", + "author": "Elmara Pereira de Souza", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso25.html", + "img": "img/colecoes/boas25.jpg", + "tags": [ + "Educação por projetos", + "Programação", + "Jogo digital", + "Alimentação", + "Atividade física", + "Investigação", + "Autonomia" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "Na “Incubadora de projetos: a experiência de construção do jogo digital Choices sobre a importância da alimentação saudável e da prática de atividade física na adolescência”, a professora Elmara Souza, do Centro Juvenil de Ciência e Cultura de Vitória da Conquista, exercitou a curiosidade de estudantes interessados em programação para criar um game que ajudasse os jovens a refletir sobre a saúde. O jogo digital tornou-se a história de um adolescente que pode voltar no tempo para fazer escolhas cotidianas mais saudáveis. Os jovens contaram com o apoio de um aluno de ciências da computação e de uma nutricionista para registrar parâmetros de colesterol e triglicérides no sangue. Premiado em um edital da Fundação de Amparo à Pesquisa do Estado da Bahia, o projeto rendeu um artigo, escrito pelos jovens com a ajuda da professora, para um congresso da Sociedade Brasileira para o Progresso da Ciência.", + "likes_count": 3 + }, + { + "id": 25, + "pre_title": "Caso 26: Tabuleiro de respeito (Competência 9)", + "title": "", + "author": "Raquel de Oliveira Campos", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso26.html", + "img": "img/colecoes/boas26.jpg", + "tags": [ + "Educação por projetos", + "Gamificação", + "Biomas", + "Cooperação", + "Diálogo", + "Responsabilidade", + "Autoestima" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "O projeto “Tabuleiro humano: uma viagem de descobertas pelos biomas brasileiros em defesa da vida”, desenvolvido no Colégio Estadual Pedro Álvares Cabral de São João de Meriti (RJ), foi criado pela professora de biologia Raquel Campos, com sua turma do 1º ano do ensino médio. Os alunos construíram um tabuleiro de seis metros quadrados com o mapa brasileiro dividido nos seis biomas do país: Pampa, Mata Atlântica, Caatinga, Cerrado, Pantanal e Amazônia. Em sala, seis grupos pesquisaram os biomas e aspectos culturais, históricos e linguísticos dessas áreas. Em casa, os jovens elaboraram perguntas lidas no jogo, em formato de quiz. No dia da competição, os estudantes venceram com facilidade a turma adversária, que não havia se engajado no trabalho pedagógico. Além disso, a dinâmica do jogo favoreceu o exercício da cooperação e o diálogo na turma.", + "likes_count": 3 + }, + { + "id": 26, + "pre_title": "Caso 27: Matemática para todos (Competência 4)", + "title": "", + "author": "Adalgísio Gonçalves Soares", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso27.html", + "img": "img/colecoes/boas27.jpg", + "tags": [ + "Educação por projetos", + "Curta-metragem", + "Malba Tahan", + "Resolução de problemas", + "Cultura digital", + "Cooperação", + "Responsabilidade" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "O projeto “Festival de curtas, uma viagem às mil e uma noites de Malba Tahan” apresentou contos do escritor aos alunos dos 8 e 9º anos da Escola Estadual Presidente Costa e Silva. Os estudantes se dividiram em grupos, resolveram coletivamente um desafio matemático presente na obra escolhida e, a partir daí, pensarem em uma narrativa para um filme. Além de apoiar as soluções dos problemas, o professor de matemática Adalgísio Soares alinhou as histórias ao conteúdo da disciplina, usando os contos para explicar equações do primeiro grau, operações com números racionais, entre outros. O professor trabalhou também o estudo do gênero textual e habilidades de leitura e escrita. Os moradores de Minas Novas (MG) ajudaram a viabilizar o festival de curtas-metragens, que exibiu 20 filmes em praça pública.", + "likes_count": 3 + }, + { + "id": 27, + "pre_title": "Caso 28: O segredo dos seus olhos (Competência 10)", + "title": "", + "author": "Elisangela Marina de Freitas e Silva", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso28.html", + "img": "img/colecoes/boas28.jpg", + "tags": [ + "Educação por projetos", + "Pré-história", + "Arqueologia", + "Acessibilidade", + "Inclusão", + "Braile", + " Desenho universal para a aprendizagem" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "A professora substituta de história Elisangela Silva encarou um desafio na Escola Básica Municipal Intendente Aricomedes da Silva, em Florianópolis: um aluno do 6º ano era cego. Visando sua inclusão, a professora recorreu à expertise das docentes Rosângela Kittel e Ruth dos Santos para trabalhar os conteúdos sobre pré-história, dando origem ao projeto “História nas pontas dos dedos: a acessibilidade ao conteúdo de pré-história”. A partir de elementos táteis, como materiais em braile e confecção de objetos em relevo, o aluno conseguiu vivenciar a aprendizagem plenamente. Para além de adaptar os conteúdos somente a ele, as docentes programaram atividades que permitissem que qualquer estudante pudesse agir com autonomia, democratizando, assim, o acesso ao conhecimento. ", + "likes_count": 3 + }, + { + "id": 28, + "pre_title": "Caso 29: Esta escola lhes pertence (Competência 3)", + "title": "", + "author": "Paulo Augusto Nedel", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso29.html", + "img": "img/colecoes/boas29.jpg", + "tags": [ + "Educação por projetos", + "Cultura artística", + "Pintura", + "Autonomia", + "Pertencimento", + "Patrimônio escolar" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "Idealizado pelo professor Paulo Nedel, o “Ateliê do GV” foi implantado em 2015 na Escola Municipal Presidente Getúlio Vargas, em Viamão (RS). O ateliê funciona no contraturno e os alunos do 5º ao 9º ano podem reproduzir pinturas de diferentes artistas sob a orientação de Paulo, que explica o processo de reprodução da imagem, como a mistura de cores e a maneira de pintar. O tempo de finalização varia de acordo com a complexidade do quadro e os estudantes, em geral, fazem duas assinaturas nos trabalhos, a dos autores originais e as deles. Em 2016, com a escola reformada e repintada, foi o momento de distribuir os quadros dos alunos pelas paredes. Os “corredores artísticos” fortaleceram o respeito pelo espaço escolar e os laços com a comunidade. No início de 2018, o ateliê contava com 110 reproduções.", + "likes_count": 3 + }, + { + "id": 29, + "pre_title": "Caso 30: O autocuidado como necessidade (Competência 8)", + "title": "", + "author": "Alessandra Aparecida Neves", + "url": "https://chapa2-ced-com-br.umbler.net/casos/caso30.html", + "img": "img/colecoes/boas30.jpg", + "tags": [ + "Educação por projetos", + "Leitura", + "Interpretação de texto", + "Literatura", + "Miniconto", + "Pesquisa na internet", + "Saúde emocional", + "Psicologia", + "Teoria da recepção" + ], + "score": 100, + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "Tendo como mote “o desafio da baleia azul”, a professora de português Alessandra Neves, em Dourados (MS), elaborou o projeto “Sem tristezas constantes, sem cortes, sem mortes precoces, entender para compreender-se”, envolvendo leitura, compreensão, interpretação e produção textual. Trabalhou com a música “Bring me to life”, com as obras “Amor de Perdição” e “Romeu e Julieta” e o filme “Inocência”. Então solicitou aos alunos pesquisas sobre depressão e suicídio. Para apresentá-las, a sala virou um “café-viagem”: cada grupo tinha um “anfitrião” que compartilhava os conhecimentos com os colegas. As atividades resultaram em microcontos sobre a temática. O projeto terminou com um papo com uma psicóloga, que orientou os jovens sobre os riscos das interações pela internet e os deixou à vontade para expor os próprios sentimentos.", + "likes_count": 3 + } + ], + "score": 100, + "img": "img/ipen_capa.jpg", + "duration": 50, + "created_at": "2018-03-26T00:31:24.484Z", + "updated_at": "2018-03-26T12:41:22.885Z", + "language": { + "id": 1, + "name": "Português", + "code": "pt" + }, + "license": null, + "description": "É um acervo de práticas inspiradoras realizadas por professores da rede pública de ensino e que estão vinculadas às dez competências gerais da Base Nacional Comum Curricular (BNCC). O objetivo é promover uma reflexão mais ampla sobre o papel dos professores, inspirar os docentes a desenvolverem práticas inovadoras e ajudá-los na implementação da Base em suas realidades, bem como valorizar o trabalho destes e tantos outros professores extraordinários pelo Brasil. As práticas, relatadas em formato de artigo e vídeo, foram desenvolvidas por professores de todo o Brasil, finalistas do Prêmio Professores do Brasil 2017. Conheça mais sobre o projeto aqui: https://www.youtube.com/watch?v=ceJywQbZSM8", + "historic": "O Banco de Práticas inspiradoras é uma iniciativa realizada pelo Instituto Península e Ministério da Educação. ", + "likes_count": 3 + } +] diff --git a/src/Components/GuardarModal.js b/src/Components/GuardarModal.js index e43a63fc3a122cf882407e8f59d6c3676fc35955..3a231ac260b33ab13c140f17acb59693910e7817 100644 --- a/src/Components/GuardarModal.js +++ b/src/Components/GuardarModal.js @@ -22,17 +22,15 @@ import Modal from '@material-ui/core/Modal'; import Backdrop from '@material-ui/core/Backdrop'; import Fade from '@material-ui/core/Fade'; import styled from 'styled-components' -import SignUpContainer from './SignUpContainerFunction.js' import {Store} from '../Store.js' -import axios from 'axios' -import {apiUrl, apiDomain} from '../env'; +import {apiDomain} from '../env'; import CloseIcon from '@material-ui/icons/Close'; -import Grid from '@material-ui/core/Grid'; import PublicIcon from '@material-ui/icons/Public'; import LockIcon from '@material-ui/icons/Lock'; import LoadingSpinner from './LoadingSpinner.js' import CriarColecaoForm from './CriarColecaoForm.js' import SnackbarComponent from './SnackbarComponent' +import {getRequest, postRequest} from './HelperFunctions/getAxiosConfig' function CloseModalButton (props) { return ( @@ -42,60 +40,42 @@ function CloseModalButton (props) { ) } -function getConfig () { - let config = { - headers : { - 'Accept': 'application/json', - 'Content-Type': 'application/json', - 'Access-Token': sessionStorage.getItem('@portalmec/accessToken'), - 'Client': sessionStorage.getItem('@portalmec/clientToken'), - 'Uid': sessionStorage.getItem('@portalmec/uid') - } - } - return config -} - export default function ReportModal (props) { const {state} = useContext(Store) const [collsArr, setcolls] = useState([]) const [loading, toggleLoading] = useState(true) const [creatingCol, setCreating] = useState(false) + + function handleSuccessGetCols (data) { + setcolls(data) + toggleLoading(false) + } const getCols = () => { if (collsArr.length === 0) { const id = state.currentUser.id - const config = getConfig() - - axios.get( (`${apiUrl}/users/` + id + '/collections'), config - ).then( (response) => { - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - console.log(response) - setcolls(response.data) - toggleLoading(false) - }, (error) => {console.log('error')}) + + const url = `/users/${id}/collections/` + + getRequest(url, handleSuccessGetCols, (error) => {console.log('error')}) } } + + function handleSuccessPostToCol (data) { + toggleSnackbar(true) + setCreating(false) + props.handleClose() + } const postToCol = (colId) => { - const config = getConfig() + const url = `/collections/${colId}/items` const payload = { "collection" : { "items" : [ {"id":props.recursoId, "type":"LearningObject"} ] } } + postRequest( url, payload, handleSuccessPostToCol, (error) => {console.log(error)}) - axios.post( (`${apiUrl}/collections/` + colId + '/items'), payload, config - ).then( (response) => { - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - console.log(response) - toggleSnackbar(true) - setCreating(false) - props.handleClose() - }, (error) => {console.log(error)}) } const [snackbarOpen, toggleSnackbar] = useState(false) @@ -150,7 +130,7 @@ export default function ReportModal (props) { ) : ( - state.currentUser.collectionsCount === 0 ? + state.currentUser.collections_count === 0 ? ( <> <div classname="no-cols"> diff --git a/src/Components/Header.js b/src/Components/Header.js index 361645e47b00b59106bc9cdb4ad7db45a6568536..a0eb0c727f385d59854a25bc5aac5d91b41a1f11 100644 --- a/src/Components/Header.js +++ b/src/Components/Header.js @@ -16,9 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { useContext, useState } from 'react' - -import AcessibilityBar from './AcessibilityBar' +import React, { useContext, useState, useEffect } from 'react' import MenuBar from './MenuBar' import SearchBar from './SearchBar' import SignUpModal from './SignUpModal' @@ -27,12 +25,16 @@ import { Store } from '../Store'; import ColaborarModal from './ColaborarModal.js' import Snackbar from '@material-ui/core/Snackbar'; import MuiAlert from '@material-ui/lab/Alert'; +import { useLocation } from 'react-router-dom' +import MenuBarMobile from './MenuBarMobile.js' +import {validateGoogleLoginToken} from './HelperFunctions/getAxiosConfig' + //const StyledButton = styled(Button)` // background : #ffa54c !important; // boxShadow :none; //` function Alert(props) { - return <MuiAlert elevation={6} variant="filled" {...props} />; + return <MuiAlert elevation={6} variant="filled" {...props} />; } @@ -43,6 +45,55 @@ export default function Header(props){ const [successfulLoginOpen, handleSuccessfulLogin] = useState(false) const [modalColaborar, setModalColaborar] = useState(false) + function handleSuccessValidateToken (data) { + dispatch ({ + type: "USER_LOGGED_IN", + userLoggedIn: !state.userIsLoggedIn, + login: data.data + } + ) + } + +/* useEffect( () => { + if (sessionStorage.getItem('@portalmec/auth_headers')) { + let config = { headers : JSON.parse(sessionStorage.getItem('@portalmec/auth_headers'))} + + validateToken(config, handleSuccessValidateToken, (error) => {console.log(error)}) + } + }, [])*/ + + let loc = useLocation() + useEffect(() => { + let query = new URLSearchParams(loc.search) + + if(query.get("auth_token")) { + let config = { + headers : { + "access-token" : query.get("auth_token"), + "client" : query.get("client_id"), + "uid" : query.get("uid"), + "expiry" : query.get("expiry"), + "token-type" : 'Bearer' + } + } + validateGoogleLoginToken(config, handleSuccessValidateToken, (error) => {console.log(error)}) + redirect() + } + }, [loc]) + + useEffect ( () => { + if (state.currentUser.askTeacherQuestion === true) { + dispatch({ + type: "TOGGLE_MODAL_COLABORAR_PLATAFORMA", + modalColaborarPlataformaOpen: true + }); + } + }, [state.currentUser.askTeacherQuestion]) + + const redirect = () => { + props.history.push('/') + } + const toggleSnackbar = (event, reason) => { if (reason === 'clickaway') { return; @@ -66,23 +117,40 @@ export default function Header(props){ }) } - return( - <> - <AcessibilityBar/> - <Snackbar open={successfulLoginOpen} autoHideDuration={1000} onClose={toggleSnackbar} - anchorOrigin = {{ vertical:'top', horizontal:'center' }} - > - <Alert severity="success" style={{backgroundColor:"#00acc1"}}>Você está conectado(a)!</Alert> - </Snackbar> - <MenuBar openSearchBar={handleClickSearch} openSignUp = {handleSignUp} openLogin = {handleLogin}/> - { state.searchOpen && - <SearchBar/> - } - <SignUpModal open={signUpOpen} handleClose={handleSignUp} openLogin={handleLogin}/> - <LoginModal open={loginOpen} handleClose={() => setLogin(false)} openSignUp={handleSignUp} - openSnackbar={() => {handleSuccessfulLogin(true)}}/> - <ColaborarModal open={modalColaborar} handleClose={() => {setModalColaborar(!modalColaborar)}} /> + let windowWidth = window.innerWidth + + return ( + <React.Fragment> + {/* + windowWidth > 990 && + <AcessibilityBar/> + */} + <Snackbar open={successfulLoginOpen} autoHideDuration={1000} onClose={toggleSnackbar} + anchorOrigin={{ vertical: 'top', horizontal: 'center' }} + > + <Alert severity="success" style={{ backgroundColor: "#00acc1" }}>Você está conectado(a)!</Alert> + </Snackbar> + { + windowWidth > 990 ? + ( + <React.Fragment> + <MenuBar openSearchBar={handleClickSearch} openSignUp={handleSignUp} openLogin={handleLogin} /> + { + state.searchOpen && + <SearchBar /> + } + </React.Fragment> - </> - ) + ) + : + ( + <MenuBarMobile openSignUp={handleSignUp} openLogin={handleLogin} /> + ) + } + <SignUpModal open={signUpOpen} handleClose={handleSignUp} openLogin={handleLogin} /> + <LoginModal open={loginOpen} handleClose={() => setLogin(false)} openSignUp={handleSignUp} + openSnackbar={() => { handleSuccessfulLogin(true) }} /> + <ColaborarModal open={modalColaborar} handleClose={() => { setModalColaborar(!modalColaborar) }} /> + </React.Fragment> + ) } diff --git a/src/Components/HelpCenter/Cards/CardEncontrando.js b/src/Components/HelpCenter/Cards/CardEncontrando.js index f1c2db1bc0ab81db242f04baf4facc0bc40425b2..173f179d24445dcc8aebdab0ef5ab7bfb59d3eda 100644 --- a/src/Components/HelpCenter/Cards/CardEncontrando.js +++ b/src/Components/HelpCenter/Cards/CardEncontrando.js @@ -46,7 +46,6 @@ export default function CardEncontrando(props) { > Como filtrar os resultados? </Link> - <a></a> <br /> <Link to={{ @@ -76,7 +75,7 @@ const CardAjuda = styled.div` height: 360px; margin-bottom: 20px; - + width: 100% .card { height: 280px; @@ -85,7 +84,7 @@ const CardAjuda = styled.div` font-size: 14px; background-color:#fff; box-shadow: 0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24); - + margin-top:30px h3 { font-size: 23px; font-weight: 400; diff --git a/src/Components/HelpCenter/Cards/CardGerenciando.js b/src/Components/HelpCenter/Cards/CardGerenciando.js index 3cc9506ab3f75de0f0ee1d8298fa714e6a07f6c4..d3e1daa3299815d50e1c948ce1810d172d49c9ae 100644 --- a/src/Components/HelpCenter/Cards/CardGerenciando.js +++ b/src/Components/HelpCenter/Cards/CardGerenciando.js @@ -93,7 +93,7 @@ const CardAjuda = styled.div` height: 360px; margin-bottom: 20px; - + width: 100% .card { height: 280px; @@ -102,6 +102,7 @@ const CardAjuda = styled.div` font-size: 14px; background-color:#fff; box-shadow: 0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24); + margin-top:30px h3 { font-size: 23px; diff --git a/src/Components/HelpCenter/Cards/CardParticipando.js b/src/Components/HelpCenter/Cards/CardParticipando.js index 9dfdbf1a8c0553adc760fc14bf3fd27dcd76f1d0..5091e9908cf3a52399f0ce08907601f24b93618a 100644 --- a/src/Components/HelpCenter/Cards/CardParticipando.js +++ b/src/Components/HelpCenter/Cards/CardParticipando.js @@ -66,7 +66,8 @@ const CardAjuda = styled.div` height: 360px; margin-bottom: 20px; - + width: 100% + .card { height: 280px; @@ -75,6 +76,8 @@ const CardAjuda = styled.div` font-size: 14px; background-color:#fff; box-shadow: 0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24); + margin-top:30px + h3 { font-size: 23px; diff --git a/src/Components/HelpCenter/Cards/CardPublicando.js b/src/Components/HelpCenter/Cards/CardPublicando.js index 673c7d153a5ae2fe6e75f0fd21b3739d17a5cba3..c5fb0a3ff925d87a602f30ff467daf95182bc8b9 100644 --- a/src/Components/HelpCenter/Cards/CardPublicando.js +++ b/src/Components/HelpCenter/Cards/CardPublicando.js @@ -74,7 +74,7 @@ const CardAjuda = styled.div` height: 360px; margin-bottom: 20px; - +width: 100% .card { height: 280px; @@ -83,7 +83,7 @@ margin-bottom: 20px; font-size: 14px; background-color:#fff; box-shadow: 0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24); - + margin-top:30px h3 { font-size: 23px; font-weight: 400; diff --git a/src/Components/HelpCenter/TabsManageAc/Forget.js b/src/Components/HelpCenter/TabsManageAc/Forget.js index a96de5c6059f10c439737d49474bba54de34a043..c3c247a3a93834ae0bef65bf6e27d393e35b4063 100644 --- a/src/Components/HelpCenter/TabsManageAc/Forget.js +++ b/src/Components/HelpCenter/TabsManageAc/Forget.js @@ -16,7 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { Component, useState, useEffect } from 'react'; +import React from 'react'; import styled from 'styled-components'; import LoginImg from '../../../img/ajuda/login_img.jpg' diff --git a/src/Components/HelpCenter/TabsManageAc/HowToAccess.js b/src/Components/HelpCenter/TabsManageAc/HowToAccess.js index f367cd4228e377798c981272934f44c90a36f470..aa06035616a818f7c2f82a0395ab93caaab5ea85 100644 --- a/src/Components/HelpCenter/TabsManageAc/HowToAccess.js +++ b/src/Components/HelpCenter/TabsManageAc/HowToAccess.js @@ -16,7 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { Component, useState, useEffect } from 'react'; +import React from 'react'; import styled from 'styled-components'; diff --git a/src/Components/HelpCenter/TabsManageAc/HowToChange.js b/src/Components/HelpCenter/TabsManageAc/HowToChange.js index 456d434ee41d3cfa05da84ce94c6473a91dff7ae..1b119e9909b898331d788c1098d0abe58d0d7fb1 100644 --- a/src/Components/HelpCenter/TabsManageAc/HowToChange.js +++ b/src/Components/HelpCenter/TabsManageAc/HowToChange.js @@ -16,7 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { Component, useState, useEffect } from 'react'; +import React from 'react'; import styled from 'styled-components'; diff --git a/src/Components/HelpCenter/TabsManageAc/HowToDo.js b/src/Components/HelpCenter/TabsManageAc/HowToDo.js index 084e78f39c2813df5ad1ff970a268c18e868856f..f2df2d292e40e39c2367a1939c956a8313cecc21 100644 --- a/src/Components/HelpCenter/TabsManageAc/HowToDo.js +++ b/src/Components/HelpCenter/TabsManageAc/HowToDo.js @@ -16,7 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { Component, useState, useEffect } from 'react'; +import React from 'react'; import styled from 'styled-components'; diff --git a/src/Components/HelpCenter/TabsManageAc/Why.js b/src/Components/HelpCenter/TabsManageAc/Why.js index a18088dc0a76b4e072037c50abca8d249f182340..09c243b07d805edb7d9d1efe93b56b92492eb479 100644 --- a/src/Components/HelpCenter/TabsManageAc/Why.js +++ b/src/Components/HelpCenter/TabsManageAc/Why.js @@ -16,7 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { Component, useState, useEffect } from 'react'; +import React from 'react'; import styled from 'styled-components'; diff --git a/src/Components/HelpCenter/TabsNetPart/How.js b/src/Components/HelpCenter/TabsNetPart/How.js index 8317ce5f7997c4096b520ab8eafb4ca573077851..221667e30390c391aa1dab7f9c3264eddcadfe9c 100644 --- a/src/Components/HelpCenter/TabsNetPart/How.js +++ b/src/Components/HelpCenter/TabsNetPart/How.js @@ -16,7 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { Component, useState, useEffect } from 'react'; +import React from 'react'; import styled from 'styled-components'; diff --git a/src/Components/HelpCenter/TabsNetPart/What.js b/src/Components/HelpCenter/TabsNetPart/What.js index 5970321c16779868a1a1a2f37344b2826d941e72..8171c7e4253436ddb50edb6a2c337981e51d4393 100644 --- a/src/Components/HelpCenter/TabsNetPart/What.js +++ b/src/Components/HelpCenter/TabsNetPart/What.js @@ -16,7 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { Component, useState, useEffect } from 'react'; +import React from 'react'; import styled from 'styled-components'; diff --git a/src/Components/HelpCenter/TabsPlataformaMEC/How.js b/src/Components/HelpCenter/TabsPlataformaMEC/How.js index 930476c1bb6525271e503dc7d40e508b15836d51..9834d9398962afcdd63315b747f1bb2f5880c2b7 100644 --- a/src/Components/HelpCenter/TabsPlataformaMEC/How.js +++ b/src/Components/HelpCenter/TabsPlataformaMEC/How.js @@ -31,6 +31,7 @@ export default function How(props) { </div> <div style={{ width: "640px", height: "360px" }}> <iframe + title="Video Página Ajuda" width="640" height="360" src="https://www.youtube.com/embed/CRW5h2pHugM" diff --git a/src/Components/HelpCenter/TabsResourseFind/HowToDo.js b/src/Components/HelpCenter/TabsResourseFind/HowToDo.js index 087f162553f7f9a559d5c04dc2b9ec801e8cee40..65934c1c01e640c5ad316674b38a6787708722f2 100644 --- a/src/Components/HelpCenter/TabsResourseFind/HowToDo.js +++ b/src/Components/HelpCenter/TabsResourseFind/HowToDo.js @@ -16,7 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { Component, useState, useEffect } from 'react'; +import React from 'react'; import styled from 'styled-components'; import Busca from '../../../img/ajuda/busca_img.jpg' diff --git a/src/Components/HelpCenter/TabsResourseFind/HowToFilter.js b/src/Components/HelpCenter/TabsResourseFind/HowToFilter.js index 78e362ff725494ad3209f4d6d2ffece03add983c..928d3dc99e598dd2fbc1204e162fc2e00f78e681 100644 --- a/src/Components/HelpCenter/TabsResourseFind/HowToFilter.js +++ b/src/Components/HelpCenter/TabsResourseFind/HowToFilter.js @@ -16,7 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { Component, useState, useEffect } from 'react'; +import React from 'react'; import styled from 'styled-components'; import Filtros from '../../../img/ajuda/filtros_img.jpg' diff --git a/src/Components/HelpCenter/TabsResourseFind/HowToRank.js b/src/Components/HelpCenter/TabsResourseFind/HowToRank.js index 0891ec5324efe7565f4460770b41bc7c9a0fc991..cb2a04b6a64b73d1721edaf51aed65214c6c2801 100644 --- a/src/Components/HelpCenter/TabsResourseFind/HowToRank.js +++ b/src/Components/HelpCenter/TabsResourseFind/HowToRank.js @@ -16,7 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { Component, useState, useEffect } from 'react'; +import React from 'react'; import styled from 'styled-components'; diff --git a/src/Components/HelpCenter/TabsResoursePub/How.js b/src/Components/HelpCenter/TabsResoursePub/How.js index fbf097e1a37e4d83d797e789c2edf682b03abf70..a84cd304098a103d6906a6ea2e5ed2f8481ae989 100644 --- a/src/Components/HelpCenter/TabsResoursePub/How.js +++ b/src/Components/HelpCenter/TabsResoursePub/How.js @@ -16,7 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { Component, useState, useEffect } from 'react'; +import React from 'react'; import styled from 'styled-components'; diff --git a/src/Components/HelpCenter/TabsResoursePub/Which.js b/src/Components/HelpCenter/TabsResoursePub/Which.js index 514e5211564eca79b8289a192c5c6098c470eabd..49a5e1f1e525cfdb04afe4fc6263bf9e57433185 100644 --- a/src/Components/HelpCenter/TabsResoursePub/Which.js +++ b/src/Components/HelpCenter/TabsResoursePub/Which.js @@ -16,7 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { Component, useState, useEffect } from 'react'; +import React from 'react'; import styled from 'styled-components'; diff --git a/src/Components/HelpCenter/TabsResoursePub/Why.js b/src/Components/HelpCenter/TabsResoursePub/Why.js index c0e703c02e30124913f408254fd112162f90ff23..ca1a16b9ece1538ed7640c181c5873d7f1e54668 100644 --- a/src/Components/HelpCenter/TabsResoursePub/Why.js +++ b/src/Components/HelpCenter/TabsResoursePub/Why.js @@ -16,7 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { Component, useState, useEffect } from 'react'; +import React from 'react'; import styled from 'styled-components'; diff --git a/src/Components/FormValidationFunction.js b/src/Components/HelperFunctions/FormValidationFunction.js similarity index 97% rename from src/Components/FormValidationFunction.js rename to src/Components/HelperFunctions/FormValidationFunction.js index c7a8407c5de125cbe34c97d559d6614296e5bfe9..27520b23d8ffac7e4f9e5a8585108c09cb9f77c5 100644 --- a/src/Components/FormValidationFunction.js +++ b/src/Components/HelperFunctions/FormValidationFunction.js @@ -1,4 +1,3 @@ -import React from 'react' //fieldName : form field name //userInput : user input for a given field diff --git a/src/Components/HelperFunctions/getAxiosConfig.js b/src/Components/HelperFunctions/getAxiosConfig.js index 99aef6a0221b4ca3c670ab966156b7d87178143d..7841d441bbf4c7085d8b965fe76f0d17863dbf99 100644 --- a/src/Components/HelperFunctions/getAxiosConfig.js +++ b/src/Components/HelperFunctions/getAxiosConfig.js @@ -1,15 +1,257 @@ -import React from 'react' +import {apiUrl} from '../../env.js' +import axios from 'axios' -export const getAxiosConfig = () => { +export function getAxiosConfigFromJSON () { let config = { - headers : { - 'Accept': 'application/json', - 'Content-Type': 'application/json', + headers : JSON.parse(sessionStorage.getItem('@portalmec/auth_headers')) + } + return config +} + +export function updateHeaders (newHeaders) { + + sessionStorage.setItem('@portalmec/accessToken', newHeaders['access-token']) + + let auth_headers = JSON.parse(sessionStorage.getItem('@portalmec/auth_headers')) + if (auth_headers) { + auth_headers['access-token'] = newHeaders['access-token'] + } + else { + auth_headers = { + client: newHeaders.client, + "access-token": newHeaders['access-token'], + uid: newHeaders.uid, + expiry: newHeaders.expiry, + "token-type": "Bearer" } } - config.headers["Access-Token"] = sessionStorage.getItem('@portalmec/accessToken'); - config.headers.Client = sessionStorage.getItem('@portalmec/clientToken') - config.headers.Uid = sessionStorage.getItem('@portalmec/uid') + sessionStorage.setItem('@portalmec/auth_headers', JSON.stringify(auth_headers)) +} + +function fetchHeaders () { + let auth_headers = JSON.parse(sessionStorage.getItem('@portalmec/auth_headers')) + + if (auth_headers) { + const myHeaders = new Headers(auth_headers) + return myHeaders + } + else { + return {} + } +} + +function checkPreviousTokens (new_token) { + + let prev_tokens = JSON.parse(sessionStorage.getItem('@portalmec/tokens')) + + if (prev_tokens) { + if (!prev_tokens.hasOwnProperty(new_token)) { + prev_tokens[new_token] = 1 + sessionStorage.setItem('@portalmec/tokens', JSON.stringify(prev_tokens)) + return true + } + else { + return false + } + } + else { + let tokens = {} + tokens[new_token] = 1 + sessionStorage.setItem('@portalmec/tokens', JSON.stringify(tokens)) + return true + } + +} + +function updateAccessToken (newAccessToken) { + + if (checkPreviousTokens(newAccessToken)) { + + sessionStorage.setItem('@portalmec/accessToken', newAccessToken) + + let auth_headers = JSON.parse(sessionStorage.getItem('@portalmec/auth_headers')) + + if (auth_headers) { + auth_headers['access-token'] = newAccessToken + } + + sessionStorage.setItem('@portalmec/auth_headers', JSON.stringify(auth_headers)) + } +} + +export const getRequest = (url, onSuccess, onError) => { + fetch((`${apiUrl}${url}`), { + headers : fetchHeaders() + }) + .then(response => { + if (response.headers.has('access-token')) { + updateAccessToken(response.headers.get('access-token')) + } + return response.json().catch(err => { + return {}; + }) + }) + .then(data => { + console.log(data) + onSuccess(data) + }) + .catch(error => { + onError(error) + }) +} + +export const deleteRequest = (url, onSuccess, onError) => { + fetch((`${apiUrl}${url}`), { + method : 'DELETE', + headers : fetchHeaders() + }) + .then(response => { + if (response.headers.has('access-token')) { + updateAccessToken(response.headers.get('access-token')) + } + return response.json().catch(err => { + return {}; + }) + }) + .then(data => { + console.log(data) + onSuccess(data) + }) + .catch(error => { + onError(error) + }) +} + +export const putRequest = (url, payload, onSuccess, onError) => { + let newHeaders = fetchHeaders() + if (payload instanceof FormData) { + newHeaders.append('Content-Type', 'multipart/form-data') + } + else { + newHeaders.append('Content-Type', 'application/json') + } + + fetch((`${apiUrl}${url}`), { + method : 'PUT', + headers : newHeaders, + body: payload instanceof FormData ? payload : JSON.stringify(payload) + }) + .then(response => { + if (response.headers.has('access-token')) { + updateAccessToken(response.headers.get('access-token')) + } + return response.json().catch(err => { + return {}; + }) + }) + .then(data => { + console.log(data) + onSuccess(data) + }) + .catch(error => { + onError(error) + }) +} + +export const postRequest = (url, payload, onSuccess, onError) => { + let newHeaders = fetchHeaders() + if (payload instanceof FormData) { + newHeaders.append('Content-Type', 'multipart/form-data') + } + else { + newHeaders.append('Content-Type', 'application/json') + } + + fetch((`${apiUrl}${url}`), { + method : 'POST', + headers : newHeaders, + body: payload instanceof FormData ? payload : JSON.stringify(payload) + }) + .then(response => { + if (response.headers.has('access-token')) { + updateAccessToken(response.headers.get('access-token')) + } + return response.json().catch(err => { + return {}; + }) + }) + .then(data => { + console.log(data) + onSuccess(data) + }) + .catch(error => { + onError(error) + }) +} + +export const fetchAllRequest = (urls, onSuccess, onError) => { + Promise.all( urls.map( url => fetch(`${apiUrl}${url}`, { + headers : fetchHeaders() + }))).then( (responses) => { + for(let res of responses) { + console.log(res) + if (res.headers.has('access-token') && res.status !== 304) { + console.log(res) + updateAccessToken(res.headers.get('access-token')) + } + } + return Promise.all(responses.map( (response) => response.json().catch(err => { + return {}; + }))) + }).then( (data) => { + onSuccess(data) + }).catch((error) => { + onError(error) + }) +} + +export const validateGoogleLoginToken = (config, onSuccess, onError) => { + axios.get( (`${apiUrl}/auth/validate_token/`), config ).then( + (response) => { + + if ( response.headers['access-token'] ) { + updateHeaders(response.headers) + } + + onSuccess(response.data) + }, + (error) => { + onError(error) + } + ) +} + +export const authentication = (url, payload, onSuccess, onError) => { + let formData = new FormData() + for (const [key, value] of Object.entries(payload)) { + formData.append(`${key}`,value); + } + + fetch((`${apiUrl}${url}`), { + method : 'POST', + body: formData + }) + .then(response => { + const auth_headers = { + client: response.headers.get('client'), + "access-token": response.headers.get('access-token'), + uid: response.headers.get('uid'), + expiry: response.headers.get('expiry'), + "token-type": "Bearer" + } + + sessionStorage.setItem('@portalmec/auth_headers', JSON.stringify(auth_headers)) + + return response.json().catch(err => { + return {}; + }) + }) + .then(data => { + console.log(data) + onSuccess(data) + }) + .catch(error => { + onError(error) + }) - return config } diff --git a/src/Components/HelperFunctions/getDefaultThumbnail.js b/src/Components/HelperFunctions/getDefaultThumbnail.js index 7bdaa5f274f409de0649a0fc6657ab49ca96e330..cb92a38fcb6f7bc2d947021ae24d2658518c67eb 100644 --- a/src/Components/HelperFunctions/getDefaultThumbnail.js +++ b/src/Components/HelperFunctions/getDefaultThumbnail.js @@ -1,4 +1,3 @@ -import React from 'react' import Animacao from '../../img/laranja/ANIMACAO_SIMULACAO.jpg' import AplicativoMovel from '../../img/laranja/APP.jpg' import Apresentacao from '../../img/laranja/APRESENTACAO.jpg' @@ -18,46 +17,32 @@ export const getDefaultThumbnail = (objType) => { switch (objType.toLowerCase()) { case "imagem": return Imagem; - break; case "mapa": return Mapa; - break; case "software educacional" : return SoftwareEducacional; - break; case "aplicativo móvel": return AplicativoMovel; - break; case "apresentação": return Apresentacao; - break; case "áudio": return Audio; - break; case "infográfico": return Infografico; - break; case "jogo": return Jogo; - break; case "livro digital" : return LivroDigital; - break; case "texto": return Texto; - break; case "vídeo": return Video; - break; case "animação": return Animacao; - break; case null: return Empty; - break; default: return Outros; - break; } } diff --git a/src/Components/HelperFunctions/saveTokens.js b/src/Components/HelperFunctions/saveTokens.js new file mode 100644 index 0000000000000000000000000000000000000000..15b89b05f5779c53cfdd209a8e33418e3074b944 --- /dev/null +++ b/src/Components/HelperFunctions/saveTokens.js @@ -0,0 +1,6 @@ +export const saveHeaders = (response) => { + if (response.headers['access-token']) + sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) + if (response.headers.client) + sessionStorage.setItem('@portalmec/clientToken', response.headers.client) +} \ No newline at end of file diff --git a/src/Components/IframeOverlay.js b/src/Components/IframeOverlay.js new file mode 100644 index 0000000000000000000000000000000000000000..2166e7165679798271a7d09d9718cedf752b288c --- /dev/null +++ b/src/Components/IframeOverlay.js @@ -0,0 +1,41 @@ +import React, { useState } from 'react'; +import styled from 'styled-components'; +import ExpandButton from './IframeOverlay/ExpandButton.js'; +import Drawer from '@material-ui/core/Drawer'; +import DrawerContent from './IframeOverlay/DrawerContent.js'; + +export default function IframeOverlay(props) { + const [expanded, setExpanded] = useState(false); + + const handleClickButton = () => { + setExpanded(!expanded); + } + + const closeDrawer = () => { + setExpanded(false); + } + + return ( + <div> + <WrapperDiv> + <ExpandButton + onClick={handleClickButton} + expanded={expanded} + /> + </WrapperDiv> + <StyledDrawer anchor="right" open={expanded} onClose={closeDrawer}> + <DrawerContent tag={props.tag}/> + </StyledDrawer> + </div> + ); +} + +const WrapperDiv=styled.div` + position: absolute; + right: 0; + top: 200px; + z-index: 2; +` +const StyledDrawer=styled(Drawer)` + overflow-y: scroll; +` diff --git a/src/Components/IframeOverlay/DrawerContent.js b/src/Components/IframeOverlay/DrawerContent.js new file mode 100644 index 0000000000000000000000000000000000000000..38907d688fab7632769096ecf825394c7c817573 --- /dev/null +++ b/src/Components/IframeOverlay/DrawerContent.js @@ -0,0 +1,80 @@ +import React, { useState, useEffect } from 'react'; +import styled from 'styled-components'; +import Grid from '@material-ui/core/Grid'; +import SearchInput from './SearchInput.js'; +import ResourceCard from './ResourceCard.js'; +import SmallFooter from './SmallFooter.js'; +import CircularProgress from '@material-ui/core/CircularProgress'; +import {getRequest} from '../HelperFunctions/getAxiosConfig' + +export default function DrawerContent(props) { + const [resources, setResources] = useState([]); + const [isLoading, setIsLoading] = useState(false); + + function handleSuccess(data) { + setResources(data) + } + const search = (query) => { + const url = `/search? + page=0&results_per_page=5&query=${query}&search_class=LearningObject` + + getRequest(url, handleSuccess, (error) => {console.log(error)}) + } + + useEffect(() => { + search(props.tag); + }, [props.tag]); + + useEffect(() => { + console.log(resources); + }, [resources]); + + return( + <Wrapper container + direction="row" + justify="center" + alignItems="flex-start" + > + <Grid item xs={11}> + <SearchInput stdin={props.tag} search={search}/> + </Grid> + <Grid item xs={11}> + <Description> + Recursos Relacionados na Plataforma MEC: + </Description> + </Grid> + + { + isLoading ? <CircularProgress style={{color : 'white'}}/> + : + resources.map((r, index) => { + return( + <Grid item xs={11} key={index}> + <ResourceCard + id={r.id} + name={r.name} + likes={r.likes_count} + thumb={r.thumbnail} + /> + </Grid> + );} + )} + <Grid item xs={12}> + <SmallFooter /> + </Grid> + </Wrapper> + ); +} + +const Wrapper=styled(Grid)` + min-width: 400px; + max-width: 400px; + background-color: #666; + height: 100%; + overflow-x: scroll !important; +` +const Description=styled.p` + color: white; + margin-left: 20px !important; + margin-right: 20px !important; +` diff --git a/src/Components/IframeOverlay/ExpandButton.js b/src/Components/IframeOverlay/ExpandButton.js new file mode 100644 index 0000000000000000000000000000000000000000..6749e1d99d9cc98e997761ff3e55aa5f055dcec5 --- /dev/null +++ b/src/Components/IframeOverlay/ExpandButton.js @@ -0,0 +1,23 @@ +import React from 'react'; +import AddIcon from '@material-ui/icons/Add'; +import RemoveIcon from '@material-ui/icons/Remove'; +import IconButton from '@material-ui/core/IconButton'; +import styled from 'styled-components'; + +export default function ExpandButton(props) { + return ( + <IconWrapper> + <IconButton + onClick={props.onClick} + style={{color: 'white'}} + > + { props.expanded ? <RemoveIcon /> : <AddIcon /> } + </IconButton> + </IconWrapper> + ); +} + +const IconWrapper=styled.div` + background-color: #5dbcd2; + border-radius: 15px 0px 0px 15px; +` diff --git a/src/Components/IframeOverlay/ResourceCard.js b/src/Components/IframeOverlay/ResourceCard.js new file mode 100644 index 0000000000000000000000000000000000000000..365ea9a3d6574cd63503c060bf94d08308be7748 --- /dev/null +++ b/src/Components/IframeOverlay/ResourceCard.js @@ -0,0 +1,53 @@ +import React from 'react'; +import { Link } from 'react-router-dom'; +import styled from 'styled-components'; +import Paper from '@material-ui/core/Paper'; +import Grid from '@material-ui/core/Grid'; +import WhiteAreaOfCard from './WhiteAreaOfCard.js'; + +export default function ResourceCard(props) { + + const getThumb = () => { + return props.thumb ? + `https://api.portalmec.c3sl.ufpr.br${props.thumb}` + : require('../../img/laranja/IMAGEM.jpg'); + + } + + return( + <Anchor + to={'/recurso/'+props.id} + > + <CardPaper elevation={3}> + <Grid container + direction="row" + justify="flex-start" + alignItems="center" + > + <Grid item> + <Img src={getThumb()} /> + </Grid> + <Grid item> + <WhiteAreaOfCard name={props.name} likes={props.likes} /> + </Grid> + </Grid> + </CardPaper> + </Anchor> + ); +} + +const CardPaper=styled(Paper)` + width: 312px; + height: 100px; + margin-bottom: 15px; + margin-left: 20px; + margin-right: 20px; +` +const Img=styled.img` + height: 100px; + width: 150px; +` +const Anchor=styled(Link)` + text-decoration: none !important; + color: inherit !important; +` diff --git a/src/Components/IframeOverlay/SearchInput.js b/src/Components/IframeOverlay/SearchInput.js new file mode 100644 index 0000000000000000000000000000000000000000..3fd246cb70a501f5d0c091df2e133ce8c2ac3f80 --- /dev/null +++ b/src/Components/IframeOverlay/SearchInput.js @@ -0,0 +1,74 @@ +import React, { useState } from 'react'; +import styled from 'styled-components'; +import SearchIcon from '@material-ui/icons/Search'; +import IconButton from '@material-ui/core/IconButton'; +import OutlinedInput from '@material-ui/core/OutlinedInput'; +import InputAdornment from '@material-ui/core/InputAdornment'; +import FormControl from '@material-ui/core/FormControl'; +import Divider from '@material-ui/core/Divider'; +import CloseRoundedIcon from '@material-ui/icons/CloseRounded'; + +export default function SearchInput(props) { + const [text, setText] = useState(props.stdin); + + const handleChange = (event) => { + setText(event.target.value); + } + + const handleClickSearch = () => { + props.search(text); + } + + const handleCleanInput = () => { + setText(""); + } + + const handleKeyUp = (event) => { + if (event.key === "Enter") + handleClickSearch() + } + + return ( + <Wrapper> + <FormControl variant="outlined" style={{ width: '100%' }}> + <OutlinedInput + type="text" + value={text} + placeholder="O quê você está buscando?" + onChange={handleChange} + onKeyUp={handleKeyUp} + endAdornment={ + <> + <InputAdornment position="end"> + <IconButton + onClick={handleCleanInput} + edge="end" + > + <CloseRoundedIcon /> + </IconButton> + </InputAdornment> + <SizedWidhtBox /> + <Divider orientation="vertical" flexItem /> + <InputAdornment position="end"> + <IconButton + onClick={handleClickSearch} + edge="end" + > + <SearchIcon style={{ fill: "#00bcd4" }} /> + </IconButton> + </InputAdornment> + </> + } + /> + </FormControl> + </Wrapper> + ); +} +const Wrapper = styled.div` + background-color: white; + border-radius: 5px; + margin: 20px; +` +const SizedWidhtBox = styled.div` + margin-right : 22px; +` diff --git a/src/Components/IframeOverlay/SmallFooter.js b/src/Components/IframeOverlay/SmallFooter.js new file mode 100644 index 0000000000000000000000000000000000000000..95350b07de94f7287391c608dd00c2cd9f4753bf --- /dev/null +++ b/src/Components/IframeOverlay/SmallFooter.js @@ -0,0 +1,56 @@ +import React from 'react'; +import styled from 'styled-components'; +import ImgInfo from '../../img/acesso-a-informacao.png'; + +export default function SmallFooter(props) { + return( + <Wrapper> + <SecondaryWrapper> + <ImgDiv> + <a + alt="Governo Federal" + href="http://www.brasil.gov.br/" + rel="noreferrer" + target="_blank" + > + <Img src={ImgInfo} /> + </a> + </ImgDiv> + <TextDiv> + 2017 + <br /> + C3SL-UFPR | FNDE | NUTE-UFSC | MEC. + <br /> + Todos os direitos reservados. + </TextDiv> + </SecondaryWrapper> + </Wrapper> + ); +} + +const Wrapper=styled.div` + width: 100%; + background-color: #444; + color: white; + padding-top: 30px; + padding-bottom: 30px; +` +const ImgDiv=styled.div` + border-right: 2px solid #666; + padding: 5px; + display: inline-block; +` +const Img=styled.img` + width: 100px; +` +const TextDiv=styled.div` + padding-left: 5px; + display: inline-block; + line-height: 12px; + font-size: 0.7em; + text-align: center; +` +const SecondaryWrapper=styled.div` + margin-left: 25px; + margin-right: 20px; +` diff --git a/src/Components/IframeOverlay/WhiteAreaOfCard.js b/src/Components/IframeOverlay/WhiteAreaOfCard.js new file mode 100644 index 0000000000000000000000000000000000000000..0f4604bb451bd9f0a7d69b57ce341ad18395106b --- /dev/null +++ b/src/Components/IframeOverlay/WhiteAreaOfCard.js @@ -0,0 +1,57 @@ +import React from 'react'; +import styled from 'styled-components'; +import Grid from '@material-ui/core/Grid'; +import OndemandVideoIcon from '@material-ui/icons/OndemandVideo'; +import FavoriteIcon from '@material-ui/icons/Favorite'; + +export default function WhiteAreaOfCard(props) { + return( + <Grid container + style={{height: '90px', width: '150px'}} + direction="column" + justify="space-between" + alignItems="flex-start" + > + <Grid item> + <Title> + {props.name} + </Title> + </Grid> + <Grid item> + <IconsDiv> + <OndemandVideoIcon /> + <RightFavoriteIcon /> + </IconsDiv> + </Grid> + </Grid> + ); +} + +const Title=styled.span` + margin-left: 5px; + font-size: 14px; + position: relative; + top: 0; + margin-top: 0; + pading-top: 0; + color: #666; + overflow: hidden; + text-overflow: ellipsis; + + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + overflow: hidden; +` +const IconsDiv=styled.div` + margin-left: 5px; + margin-right: 5px; + color: #666 !important; + width: 150px; + position: relative; + top: 0; +` +const RightFavoriteIcon=styled(FavoriteIcon)` + position: absolute; + right: 0; +` diff --git a/src/Components/IllegalContentModal.js b/src/Components/IllegalContentModal.js index 01ccf37bca84035048722dc7e1175c0c4b03a3f9..976bb5d8728791502ced2db51534bf6b4cc5b703 100644 --- a/src/Components/IllegalContentModal.js +++ b/src/Components/IllegalContentModal.js @@ -5,8 +5,6 @@ import styled from 'styled-components' import { Button } from '@material-ui/core'; import Backdrop from '@material-ui/core/Backdrop'; import { Store } from '../Store.js'; -import axios from 'axios' -import {apiUrl} from '../env'; const StyledModal = styled(Modal)` margin : 0 !important; @@ -81,26 +79,14 @@ const StyledDivContainer = styled.div` ` export default function IllegalContentModal (props) { - const {state, dispatch} = useContext(Store) - - // const func = () => { - // let name = '' - // axios.get(`${apiUrl}/users/:id`,{ - // - // } - // ).then ( (response) => { - // name = response.name - // }, (error) => { - // console.log(':(') - // }) - // } + const {state} = useContext(Store) return ( <StyledModal aria-labelledby="transition-modal-title" aria-describedby="transition-modal-description" open={props.open} - + centered="true" onClose={props.handleClose} closeAfterTransition @@ -112,7 +98,7 @@ export default function IllegalContentModal (props) { <Fade in={props.open}> <StyledDivContainer > <StyledDivContent> - <StyledH2>{state.currentUser.username}!</StyledH2> + <StyledH2>{state.currentUser.name}!</StyledH2> <div> <StyledParagraph>Seu recurso não está de acordo com os termos</StyledParagraph> </div> diff --git a/src/Components/ItemCard.js b/src/Components/ItemCard.js index 21f87f4f9e0bc70f04145db5ff832961e1f383cf..dea4bd2a34c970cc9cc26bb45d0baab857b90c17 100644 --- a/src/Components/ItemCard.js +++ b/src/Components/ItemCard.js @@ -15,13 +15,11 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useState, useContext} from 'react'; +import React from 'react'; import styled from 'styled-components'; import Grid from '@material-ui/core/Grid'; import Card from '@material-ui/core/Card'; -import CardActions from '@material-ui/core/CardActions'; import CardContent from '@material-ui/core/CardContent'; -import gem from '../img/gamification/gem.svg'; import ItemCardAction from './ItemCardAction.js'; const ItemImage = styled.img` diff --git a/src/Components/ItemCardAction.js b/src/Components/ItemCardAction.js index c5e9f41d67a65b1f1a1c81a037504baaae581219..ed1cc7dde66752bb622375c25b65172ab3d42e92 100644 --- a/src/Components/ItemCardAction.js +++ b/src/Components/ItemCardAction.js @@ -15,16 +15,12 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useState, useContext} from 'react'; +import React, {useState} from 'react'; import styled from 'styled-components'; -import Card from '@material-ui/core/Card'; -import CardActions from '@material-ui/core/CardActions'; -import CardContent from '@material-ui/core/CardContent'; import Snackbar from '@material-ui/core/Snackbar'; import MuiAlert from '@material-ui/lab/Alert'; import Button from '@material-ui/core/Button'; import gem from '../img/gamification/gem.svg'; -import SnackbarContent from '@material-ui/core/SnackbarContent'; import Dialog from '@material-ui/core/Dialog'; import DialogActions from '@material-ui/core/DialogActions'; import DialogContent from '@material-ui/core/DialogContent'; @@ -45,7 +41,7 @@ const actionStyle = (operation) => { fontWeight: 'bold', cursor: 'pointer' } - stl.color = operation != 'buy' ? '#02a5c3' : '#666666'; + stl.color = operation !== 'buy' ? '#02a5c3' : '#666666'; return stl; } @@ -65,32 +61,35 @@ export default function ItemCardAction (props) { const [failure, setFailure] = useState(false); const [message, setMessage] = useState(""); const [info, setInfo] = useState(false); + // eslint-disable-next-line const [item_id, setItemID] = useState(0); const [last_operation, setLastOperation] = useState(); const [open_dialog, setOpenDialog] = useState(false); - const nonPurchaseMessage = <span>Item {last_operation == 'equip' ? 'retirado' : 'equipado'}. <a onClick={revertLastOperation}>Desfazer</a></span>; + + + const revertLastOperation = () => { + manageItemAndShowSnackbar(last_operation === 'equip' ? 'unequip' : 'equip', + setInfo, + nonPurchaseMessage, + 'Erro'); + } + + const nonPurchaseMessage = <span>Item {last_operation === 'equip' ? 'retirado' : 'equipado'}. <div onClick={revertLastOperation}>Desfazer</div></span>; const handleClose = (snackbar) => { - if (snackbar == 'success') + if (snackbar === 'success') setSuccess(false); - else if (snackbar == 'info') + else if (snackbar === 'info') setInfo(false); else setFailure(false); } - const revertLastOperation = () => { - manageItemAndShowSnackbar(last_operation == 'equip' ? 'unequip' : 'equip', - setInfo, - nonPurchaseMessage, - 'Erro'); - } - const manageItemAndShowSnackbar = (operation, setSnackbar, successMessage, failureMessage) => { axios.patch(apiUrl + '/users/' + operation + '_item?id=' + item_id).then( response => { - if (response.status == 200) { + if (response.status === 200) { setSnackbar(true); setMessage(successMessage); } else { @@ -99,7 +98,7 @@ export default function ItemCardAction (props) { } } ); - setLastOperation(operation == 'purchase' ? last_operation : (operation == 'equip' ? 'unequip' : 'equip')); + setLastOperation(operation === 'purchase' ? last_operation : (operation === 'equip' ? 'unequip' : 'equip')); } const handleClickBuyItem = () => { @@ -114,11 +113,11 @@ export default function ItemCardAction (props) { const handleClick = () => { // this will become an axios get - if (props.operation == 'unequip') + if (props.operation === 'unequip') manageItemAndShowSnackbar('unequip', setInfo, nonPurchaseMessage, 'Erro'); - else if (props.operation == 'equip') + else if (props.operation === 'equip') manageItemAndShowSnackbar('equip', setInfo, nonPurchaseMessage, 'Erro'); - else if (props.operation == 'buy') { + else if (props.operation === 'buy') { setOpenDialog(true); } } @@ -141,9 +140,9 @@ export default function ItemCardAction (props) { </Alert> </Snackbar> <span style={actionStyle(props.operation)} onClick={handleClick}> - {props.operation == 'buy' ? <GemImg src={gem}/> : <span/>} - {props.operation == 'buy' ? "COMPRAR" : - props.operation == 'equip' ? "USAR" : "TIRAR"} + {props.operation === 'buy' ? <GemImg src={gem}/> : <span/>} + {props.operation === 'buy' ? "COMPRAR" : + props.operation === 'equip' ? "USAR" : "TIRAR"} </span> <Dialog open={open_dialog} diff --git a/src/Components/ItemCarousel.js b/src/Components/ItemCarousel.js index a3e03e8e4fbcbf3a6a442a433896bb1191334030..a790b4f18c67fd3ad2fc2726334d3140b07f69ad 100644 --- a/src/Components/ItemCarousel.js +++ b/src/Components/ItemCarousel.js @@ -15,12 +15,8 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useState, useContext} from 'react'; -import styled from 'styled-components'; +import React, {useState} from 'react'; import Grid from '@material-ui/core/Grid'; -import Card from '@material-ui/core/Card'; -import CardActions from '@material-ui/core/CardActions'; -import CardContent from '@material-ui/core/CardContent'; import ItemCard from './ItemCard.js'; import ArrowBackIcon from '@material-ui/icons/ArrowBack'; import ArrowForwardIcon from '@material-ui/icons/ArrowForward'; @@ -32,13 +28,13 @@ export default function ItemCarousel (props) { const [right, setRight] = useState(5); const goLeft = () => { - setRight(right == 0 ? props.items.length-1 : right-1); - setLeft(left == 0 ? props.items.length-1 : left-1); + setRight(right === 0 ? props.items.length-1 : right-1); + setLeft(left === 0 ? props.items.length-1 : left-1); } const goRight = () => { - setRight(right == props.items.length-1 ? 0 : right+1); - setLeft(left == props.items.length-1 ? 0 : left+1); + setRight(right === props.items.length-1 ? 0 : right+1); + setLeft(left === props.items.length-1 ? 0 : left+1); } return ( diff --git a/src/Components/LevelDescriptionCard.js b/src/Components/LevelDescriptionCard.js index 90e43b78d1343e2e5fa971349e87bc7b175b54e4..7c55a81f33b75bcdb375ee02c1919df2ab4a3b24 100644 --- a/src/Components/LevelDescriptionCard.js +++ b/src/Components/LevelDescriptionCard.js @@ -1,16 +1,9 @@ -import React, { Component, useState, useEffect } from 'react'; - -import {Container} from 'react-grid-system'; -import Card from '@material-ui/core/Card'; -import CardContent from '@material-ui/core/CardContent'; +import React from 'react'; import styled from 'styled-components' import ShinyProgressBar from './ShinyProgressBar.js' import { Grid } from '@material-ui/core' -import axios from 'axios'; -import { apiUrl } from '../env'; - export default function LevelDescriptionCard(props) { return ( @@ -54,9 +47,6 @@ const CurrentCoins = styled.p` margin-right: 30px; ` -const CurrentLevelInfo = styled.div` - background-color: red; -` const CurrentLevelNumber = styled.h1` font-weight: 500; font-size: 40px; diff --git a/src/Components/LoadingSpinner.js b/src/Components/LoadingSpinner.js index ffeec90992457ab00d31c18dff77e14ba0d40b61..68c447c4c3be4aee028bf6b4997ceefa956fd197 100644 --- a/src/Components/LoadingSpinner.js +++ b/src/Components/LoadingSpinner.js @@ -3,7 +3,7 @@ import LoadingGif from '../img/loading_busca.gif' const LoadingSpinner = (props) => ( <div style={{display:"flex", flexDirection:"column", alignItems:"center", justifyContent:"center"}}> - <img src={LoadingGif} /> + <img alt="" src={LoadingGif} /> <span style={{textTransform:"uppercase"}}>{props.text}</span> </div> ); diff --git a/src/Components/LoginContainer.js b/src/Components/LoginContainer.js deleted file mode 100644 index aaf89d2182dfb74eedb1da3228ea950ae5880e76..0000000000000000000000000000000000000000 --- a/src/Components/LoginContainer.js +++ /dev/null @@ -1,320 +0,0 @@ -/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre -Departamento de Informatica - Universidade Federal do Parana - -This file is part of Plataforma Integrada MEC. - -Plataforma Integrada MEC is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -Plataforma Integrada MEC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {Component} from "react"; -import GoogleLogin from 'react-google-login' -import { Button } from '@material-ui/core'; -//import FacebookLogin from 'react-facebook-login'; -import CloseIcon from '@material-ui/icons/Close'; -import styled from 'styled-components' -import {device} from './device.js' -import LabeledCheckbox from './Checkbox.js' -import FormInput from "./FormInput.js" -import GoogleLogo from "../img/logo_google.svg" - -//arrumar isso -const responseGoogle = (response) => { - console.log(response); -} - -class LoginContainer extends Component { - constructor (props) { - super(props); - - this.state = { - email : localStorage.getItem("@portalmec/email") || "", - senha : localStorage.getItem("@portalmec/senha") ||"", - checkboxChecked : false - }; - this.handleChecked = this.handleChecked.bind(this) - } - - switchModal = (e) => { - e.preventDefault() - this.props.handleClose() - this.props.openSignUp() - } - - handleChange = e => { - this.setState({[e.target.name]: e.target.value}) - } - - onSubmit = (e) => { - e.preventDefault(); - const login = this.state - - this.props.handleLoginInfo(login); - - this.setState({ - email: "", - senha: "" - }) - } - - handleChecked = (e) => { - const value = !this.state.checkboxChecked - console.log(this.state.checkboxChecked) - console.log(value) - this.setState({ - checkboxChecked :value - }) - } - - render () { - return ( - <ContainerStyled > - <DialogHeaderStyled> - <span style={{width:"32px"}}/> - <H2Styled> Entrar - </H2Styled> - <StyledCloseModalButton onClick={this.props.handleClose}> - <CloseIcon/> - </StyledCloseModalButton> - </DialogHeaderStyled> - - <DialogContentDiv> - <SocialConnectDiv> - <StyledGoogleLoginButton - clientId="658977310896-knrl3gka66fldh83dao2rhgbblmd4un9.apps.googleusercontent.com" - - onSuccess={responseGoogle} - onFailure={responseGoogle} - cookiePolicy={'single_host_origin'} - > - <span style={{textTransform:"none", fontSize:"13px", color : "#666"}}>Usando o Google</span> - </StyledGoogleLoginButton> - </SocialConnectDiv> - - <H3Div> - <H3Styled> - <RightSideStrikedH3/> - <span style={{verticalAlign:"middle"}}>ou</span> - <LeftSideStrikedH3/> - </H3Styled> - </H3Div> - - <form onSubmit={this.onSubmit}> - <FormInput - inputType={"text"} - name={"email"} - value={this.state.email} - placeholder={"E-mail"} - handleChange={e => this.handleChange(e)} - required={true} - /> - <br/> - <FormInput - inputType={"password"} - name={"senha"} - value={this.state.senha} - placeholder={"Senha"} - handleChange={e => this.handleChange(e)} - required={true} - /> - <br/> - - <RememberRecover> - <LabeledCheckbox label={<StyledLabel><StyledSpan>Lembrar-me</StyledSpan></StyledLabel>} handleChange={this.handleChecked} /> - <UserForgotTheirPasswordSpan>Esqueceu a senha? <a href="recuperar-senha" style={{textAlign: "right", color:"#4cd0e1"}}>Clique aqui!</a></UserForgotTheirPasswordSpan> - </RememberRecover> - - <ConfirmContainerStyled> - <StyledLoginButton type="submit" variant="contained"> - <span style={{borderRadius:"3px", boxSizing:"border-box", fontFamily:"Roboto, sans serif", fontWeight:"500", color:"#fff"}}>ENTRAR</span> - </StyledLoginButton> - </ConfirmContainerStyled> - </form> - - <DialogFooterStyled> - <span style={{textAlign:"center", fontSize: "14px", color:"rgb(102, 102, 102)"}}>Ainda não tem cadastro? <StyledAnchor href="" onClick={e => this.switchModal(e)}>CADASTRE-SE</StyledAnchor></span> - </DialogFooterStyled> - </DialogContentDiv> - </ContainerStyled> - ) - } -} - -export default LoginContainer - -const ContainerStyled = styled.div` - box-sizing : border-box; - background-color : white; - max-width : none; - display : flex; - flex-direction : column; - min-width : 440px; - min-height : 550px; - align : center; - padding : 10px; - border-radius: 4px; - line-height : 20px; - font-size : 14px; - @media ${device.mobileM} { - width : 100%; - height : 100%; - } -` - -export const DialogHeaderStyled = styled.div` - text-align : center; - display : flex; - flex-direction : row; - justify-content : space-between; - padding : 10px 26px 0 26px; - height : 64px; -` -const H2Styled = styled.h2` - align-self : center; - color : #666; - font-size : 26px; - font-weight : 100; - font-family: 'Roboto', sans serif, 'Helvetica Neue', Helvetica, Arial, sans-serif !important; - justify-content: space-between; - text-align: center; - letter-spacing: .005em; -` - -export const StyledCloseModalButton = styled(Button)` - display : inline-block; - position : relative; - float : right !important; - margin-right : -8px !important; - background : transparent !important; - min-width: 0 !important; - width : 40px; -` -export const DialogContentDiv = styled.div` - padding : 20px 30px; - overflow : visible !important; -` - -export const SocialConnectDiv = styled.div` - margin-top : 0; - display : flex; - flex-direction : row; -` -export const StyledGoogleLoginButton = styled(GoogleLogin)` - background-color : #fff !important; - color : #666 !important; - border : 1px solid rgb(66, 133, 244); - box-shadow: 0 0 0 1px #4285f4 !important; - :hover { - background-color: #f4f4f4 !important; - } -` - -const DialogFooterStyled = styled.div` - box-sizing : border-box; - font-family : 'Roboto', sans serif; - margin : 20px -20px; - padding-top : 20px; - border-top : 1px #e5e5e5 solid; - justify-content : center; - text-align : center; - line-height : 1.42857143 -` - - -const RightSideStrikedH3 = styled.div` - display : inline-block; - border-bottom: 1px dotted #666; - vertical-align : middle; - font-weight : 500; - margin-right : 5px; - width : 45%; -` - -const LeftSideStrikedH3 = styled.div` - display : inline-block; - border-bottom: 1px dotted #666; - vertical-align : middle; - font-weight : 500; - margin-left : 5px; - width : 45%; -` - -export const H3Div = styled.div` - margin-top : 0; - margin-bottom : 10px; -` - -const H3Styled = styled.h3` - overflow : hidden; - text-align : center; - font-size : 14px; - color : #666; - margin : 10px 0; -` - -const StyledAnchor = styled.a` - color : #00bcd4; - text-decoration : none; -` -const ConfirmContainerStyled = styled.div` - display : flex; - margin-top : 10px; - align-items : center; - justify-content : center; -` -const StyledLoginButton = styled(Button)` - background-color : #00bcd4 !important; - box-shadow : none !important; - outline: none !important; - border : 0 !important; - overflow : hidden !important; - width : 35% !important; - display : inline-block !important; - font-family : 'Roboto', sans serif !important; - font-size: 14px !important; - height : 36px !important; - align-items : center !important; - border-radius: 3px !important; - align-self : 50% !important; - :hover { - background-color : #00acc1 !important; - } -` - - -const RememberRecover = styled.div` - display : flex; - justify-content : space-between; - font-size: 12px; - font-weight : 400; -` - -const StyledLabel = styled.div` - box-sizing : border-box; - position : relative; - vertical-align : middle !important; - color : #666; - -` - -const UserForgotTheirPasswordSpan = styled.span` - margin-top : 1em; - font-size : 12px; - font-weight : 400; - text-align : right; - color : #666; -` - -const StyledSpan = styled.span` - font-size : 12px; - font-weight : 400; - padding-top : 2px; -` diff --git a/src/Components/LoginContainerFunction.js b/src/Components/LoginContainerFunction.js index 31aa61bef9e926835707b867bbe1a943caf432c0..8534da0ad3bbe1154612b62b1eeff24f4f26cbfc 100644 --- a/src/Components/LoginContainerFunction.js +++ b/src/Components/LoginContainerFunction.js @@ -25,8 +25,17 @@ import {device} from './device.js' import LabeledCheckbox from './Checkbox.js' import FormInput from "./FormInput.js" import GoogleLogo from "../img/logo_google.svg" -import ValidateUserInput from '../Components/FormValidationFunction.js' +import ValidateUserInput from './HelperFunctions/FormValidationFunction.js' import {Link} from 'react-router-dom' +import {apiUrl} from '../env.js' + +async function handleGoogleAttempt () { + console.log("handleGoogleAttempt") + let request_url = ( + `${apiUrl}/omniauth/google_oauth2?auth_origin_url=` + window.location.href + '&omniauth_window_type=sameWindow&resource_class=User' + ) + window.location.replace(request_url) +} export default function LoginContainer (props) { const [formEmail, setEmail] = useState( @@ -60,14 +69,14 @@ export default function LoginContainer (props) { key : flag, value : userInput }) - {/*console.log(formEmail)*/} + // {/*console.log(formEmail)*/} } else if(type === 'password') { setSenha({...formSenha, key : flag, value : userInput }) - {/*console.log(formSenha)*/} + // {/*console.log(formSenha)*/} } } @@ -85,7 +94,7 @@ export default function LoginContainer (props) { const onSubmit = (e) => { e.preventDefault() - const login = {email : formEmail.value, senha : formSenha.value, checkbox : checkboxControl} + const login = {email : formEmail.value, senha : formSenha.value, checkboxChecked : checkboxControl} if (!(formEmail.key || formSenha.key)) { props.handleLoginInfo(login) @@ -94,11 +103,6 @@ export default function LoginContainer (props) { } - //arrumar isso - const handleGoogleResponse = (response) => { - console.log(response); - } - return ( <div> <ContainerStyled > @@ -113,14 +117,10 @@ export default function LoginContainer (props) { <DialogContentDiv> <SocialConnectDiv> - {/*<StyledGoogleLoginButton - clientId="288460085642-k4veg4fo8kddvjer8b055n9da5qtgha7.apps.googleusercontent.com" - onSuccess={ } - onFailure={ } - cookiePolicy={'single_host_origin'} - > - <span style={{textTransform:"none", fontSize:"13px", color : "#666"}}>Usando o Google</span> - </StyledGoogleLoginButton>*/} + <GoogleLoginButton onClick={handleGoogleAttempt}> + <img src={GoogleLogo} alt="google-logo" className="google-logo"/> + <span>Usando o Google</span> + </GoogleLoginButton> </SocialConnectDiv> <H3Div> @@ -140,7 +140,7 @@ export default function LoginContainer (props) { handleChange={e => handleChange(e, 'email')} required={true} error = {formEmail.key} - help = {formEmail.key ? ( formEmail.value.length == 0 ? "Faltou preencher seu e-mail." : <span>Insira um endereço de e-mail válido.<br/>Por exemplo: seunome@gmail.com, seunome@hotmail.com</span>) : ""} + help = {formEmail.key ? ( formEmail.value.length === 0 ? "Faltou preencher seu e-mail." : <span>Insira um endereço de e-mail válido.<br/>Por exemplo: seunome@gmail.com, seunome@hotmail.com</span>) : ""} /> <br/> <FormInput @@ -151,7 +151,7 @@ export default function LoginContainer (props) { handleChange={e => handleChange(e, 'password')} required={true} error = {formSenha.key} - help = {formSenha.key ? (formSenha.value.length == 0 ? "Faltou digitar sua senha." : "A senha precisa ter no mínimo 8 caracteres.") : ""} + help = {formSenha.key ? (formSenha.value.length === 0 ? "Faltou digitar sua senha." : "A senha precisa ter no mínimo 8 caracteres.") : ""} /> <br/> @@ -192,7 +192,10 @@ export default function LoginContainer (props) { font-size : 14px; @media ${device.mobileM} { width : 100%; + min-width : unset; height : 100%; + min-width : unset !important; + } ` @@ -262,7 +265,7 @@ export const RightSideStrikedH3 = styled.div` vertical-align : middle; font-weight : 500; margin-right : 5px; - width : 45%; + width : 44%; ` export const LeftSideStrikedH3 = styled.div` @@ -271,7 +274,7 @@ export const RightSideStrikedH3 = styled.div` vertical-align : middle; font-weight : 500; margin-left : 5px; - width : 45%; + width : 44%; ` export const H3Div = styled.div` @@ -344,3 +347,23 @@ export const RightSideStrikedH3 = styled.div` font-weight : 400; padding-top : 2px; ` +export const GoogleLoginButton = styled(Button)` + background-color : #fff; + box-shadow : 0 0 0 1px #4285f4 !important; + color : #666 !important; + font-weight : bolder !important; + font-size : 12px !important; + text-transform: none !important; + width: 40%; + + ${'' /* .MuiButton-root { + min-width : 88px; + } */} + + .google-logo { + max-height : 18px ; + padding-right : 5px; + + } + +` diff --git a/src/Components/LoginModal.js b/src/Components/LoginModal.js index 5f2c5931996915e89c6c79e6820d7172d406cc19..b18ab1cc252bd0598aae745c41997bd67678c41d 100644 --- a/src/Components/LoginModal.js +++ b/src/Components/LoginModal.js @@ -17,17 +17,15 @@ You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ import React, {useContext, useState} from 'react'; -import { Button } from '@material-ui/core'; import Modal from '@material-ui/core/Modal'; import Backdrop from '@material-ui/core/Backdrop'; import Zoom from '@material-ui/core/Fade'; import styled from 'styled-components' import LoginContainer from './LoginContainerFunction.js' import {Store} from '../Store.js' -import axios from 'axios' -import {apiUrl} from '../env'; import Snackbar from '@material-ui/core/Snackbar'; import MuiAlert from '@material-ui/lab/Alert'; +import {authentication} from './HelperFunctions/getAxiosConfig' const StyledLogin = styled(Modal)` margin : 0 !important; @@ -57,51 +55,36 @@ export default function LoginModal (props){ handleSnackbar(false); } + function renameKeys (obj) { + if (obj.avatar_file_name) { + Object.defineProperty(obj, 'avatar', + Object.getOwnPropertyDescriptor(obj, 'avatar_file_name')); + delete obj['avatar_file_name']; + } + } + + function handleSuccess (data) { + renameKeys(data.data) + dispatch ({ + type: "USER_LOGGED_IN", + userLoggedIn: !state.userIsLoggedIn, + login: data.data + } + ) + props.handleClose(); + props.openSnackbar(); + } + function handleError (error) { + handleSnackbar(true) + } const handleLoginInfo = (login) => { - axios.post(`${apiUrl}/auth/sign_in`, - { + const url = `/auth/sign_in` + const payload = { email : login.email, password : login.senha } - ).then( (response) => { - console.log(response) - dispatch ({ - type: "USER_LOGGED_IN", - userLoggedIn: !state.userIsLoggedIn, - login: { - askTeacherQuestion : response.data.data.ask_teacher_question, - id : response.data.data.id, - username : response.data.data.name, - email : response.data.data.email, - accessToken : response.headers['access-token'], - clientToken : response.headers.client, - userAvatar : response.data.data.avatar_file_name, - userCover : response.data.data.cover_file_name, - uid : response.data.data.uid, - followCount : response.data.data.follows_count, - collectionsCount : response.data.data.collections_count, - submitter_request : response.data.data.submitter_request, - roles : response.data.data.roles - } - } - ) - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - sessionStorage.setItem('@portalmec/clientToken', response.headers.client) - sessionStorage.setItem('@portalmec/id', response.data.data.id) - sessionStorage.setItem('@portalmec/username', response.data.data.name) - sessionStorage.setItem('@portalmec/uid', response.data.data.uid) - sessionStorage.setItem('@portalmec/senha', login.senha) - - if (login.checkboxChecked) { - localStorage.setItem('@portalmec/email', login.email) - localStorage.setItem('@portalmec/senha', login.senha) //MUDAR ISSO ASAP - } - props.handleClose(); - props.openSnackbar(); - }, (error) => { - {handleSnackbar(true)} - } - ) + + authentication(url, payload, handleSuccess, handleError) } @@ -131,6 +114,7 @@ export default function LoginModal (props){ /> </Zoom> </StyledLogin> + </> ) } diff --git a/src/Components/MaterialCard.js b/src/Components/MaterialCard.js index c5353a918fd0f5aafdf7b2e532c82cfa93cb4b85..33cf3d8ddccf32591fdb77753956331d3ec87b51 100644 --- a/src/Components/MaterialCard.js +++ b/src/Components/MaterialCard.js @@ -16,40 +16,102 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {Component} from 'react'; +import React from 'react'; import Card from '@material-ui/core/Card'; import CardContent from '@material-ui/core/CardContent'; import CardActions from '@material-ui/core/CardActions'; import Typography from '@material-ui/core/Typography'; -import livro from "../img/laranja/LIVRO_DIGITAL.jpg"; import Library from '@material-ui/icons/LibraryBooks'; +import Rating from '@material-ui/lab/Rating'; +import StarBorderIcon from '@material-ui/icons/StarBorder'; +import Grid from '@material-ui/core/Grid'; +import styled from 'styled-components'; +import Button from '@material-ui/core/Button'; +import ExpandMoreRoundedIcon from '@material-ui/icons/ExpandMoreRounded'; +import {Link} from 'react-router-dom'; +export default function MaterialCard(props) { -class MaterialCard extends Component { - constructor(props) { - super(props); - this.state={ - thumbnail: livro, - }; - } - render(){ - return ( - <Card> - <img src={this.state.thumbnail} alt="thumbnail do recurso"/> - <CardContent style={{height: "60%", textAlign: "left", paddingBottom: "0px"}}> - <Typography variant="body2" color="textSecondary" component="p" style={{overflow: "hidden", fontSize: "0.8em"}}> - {this.props.name} - </Typography> - </CardContent> - <CardActions style={{justifyContent: "space-between"}}> - <Library style={{color:"#e81f4f"}} /> - </CardActions> - <CardActions style={{borderTop:"1px solid #e5e5e5", justifyContent: "space-between"}}> - <Typography>Expandir??</Typography> - </CardActions> - </Card> - );} - } - - -export default MaterialCard; + const thumb = require(`../../public/${props.thumb}`) + + const HandleButtonPressed = () => { + props.handleExpand(props.id); + } + + const width = window.innerWidth; + + return ( + <Card> + <img src={thumb} alt="thumbnail do recurso" /> + <CardContent style={{ height: "60px", textAlign: "left", paddingBottom: "0px", width: "100%" }}> + <Title> + {props.name} + </Title> + </CardContent> + <CardActions> + <Grid container direction="column" justify="flex-start" alignItems="flex-start" style={{ marginLeft: "5px" }}> + <Grid item> + <Rating + name="customized-empty" + value={props.score} + precision={0.5} + style={{ color: "#666" }} + emptyIcon={<StarBorderIcon fontSize="inherit" />} + readOnly + /> + </Grid> + <Grid container direction="row" alignItems="center"> + <Library style={{ color: "#e81f4f" }} /> + <SizedBox /> + <Typography variant="body2" color="textSecondary" component="p" style={{ overflow: "hidden", fontSize: "0.8em" }}> + {props.modules.length} módulos + </Typography> + </Grid> + </Grid> + </CardActions> + <CardActions style={{ borderTop: "1px solid #e5e5e5", justifyContent: "center" }}> + { + width <= 767 ? + <StyledLink to={`/colecao?colecao=${props.id}`}> + <Button + color="secondary" + endIcon={<ExpandMoreRoundedIcon />} + > + + Ver módulos + </Button> + </StyledLink> + : + <Button + color="secondary" + endIcon={<ExpandMoreRoundedIcon />} + onClick={HandleButtonPressed} + > + + Ver módulos + </Button> + } + </CardActions> + </Card > + ) +} + +const SizedBox = styled.div` + width : 5px; +` +const Title = styled(Typography)` + font-weight: 500; + color: rgb(102, 102, 102); + font-size: 0.9em; + margin-left: 10px; + margin-right: 10px; + + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; +` +const StyledLink = styled(Link)` + text-decoration: none ; + color: inherit ; +` \ No newline at end of file diff --git a/src/Components/MenuBar.js b/src/Components/MenuBar.js index 8ea5f1620e085fcf23fa8ae0b867a8bb3df1ef84..dd911f2b4f04d9f33403cb8eda7f1d0a0d30f408 100644 --- a/src/Components/MenuBar.js +++ b/src/Components/MenuBar.js @@ -37,10 +37,10 @@ const ContainerStyled = styled(Container)` align-items: center; border-top: 1px rgba(0,0,0,.1) solid; padding: 5px; - + padding-top : 10px; ` -const ButtonStyled = styled(Button)` +export const ButtonStyled = styled(Button)` text-transform: capitalize !important; margin : 0 8px !important; font-weight : normal !important; @@ -86,7 +86,7 @@ const Left = styled.span ` align-items: center; ` -const ButtonPubRecursoStyled = styled(Button)` +export const ButtonPubRecursoStyled = styled(Button)` font-weight : 500 !important; border : 1.5px #666 solid !important; color: #666; @@ -98,11 +98,11 @@ const ButtonPubRecursoStyled = styled(Button)` export default function MenuBar(props){ - const { state, dispatch } = useContext(Store) + const { state } = useContext(Store) const menuSobre = [ { name: "Sobre a Plataforma", href: "sobre" }, - { name: "Portais Parceiros", href: "" }, + { name: "Portais Parceiros", href: "sobre#portaisparceiros" }, { name: "Termos de Uso", href: "termos" }, { name: "Contato", href: "contato" } ] @@ -117,11 +117,10 @@ export default function MenuBar(props){ const minhaArea = [ { name: "Perfil e Atividades", href: "/perfil", value : '0'}, - { name: "Status e Conquistas", href: "/perfil", value: '1'}, - { name: "Recursos Publicados", href: "/perfil", value : '2'}, - { name: "Favoritos", href: "/perfil", value : '3'}, - { name: "Coleções", href: "/perfil", value : '4'}, - { name: "Rede", href: "/perfil", value : '5'}, + { name: "Recursos Publicados", href: "/perfil", value : '1'}, + { name: "Favoritos", href: "/perfil", value : '2'}, + { name: "Coleções", href: "/perfil", value : '3'}, + { name: "Rede", href: "/perfil", value : '4'}, { name: "Configurações", href: "/editarperfil"}, ] @@ -134,10 +133,11 @@ export default function MenuBar(props){ <a href="http://educacaoconectada.mec.gov.br/" rel="noopener noreferrer" target="_blank" > <ButtonStyled >Educação Conectada</ButtonStyled> </a> - <Link to="/loja"> + {/*<Link to="/loja"> <ButtonStyled>Lojinha</ButtonStyled> - </Link> - <ButtonStyled onClick={props.openSearchBar} ><IconSearchStyled />Buscar</ButtonStyled> + </Link>*/} + <ButtonStyled onClick={props.openSearchBar} ><IconSearchStyled />Buscar</ButtonStyled> + </Left> <Right> { @@ -145,7 +145,7 @@ export default function MenuBar(props){ ? ( <> <div style={{boxSizing:"border-box"}}> - <Link to="/termos-publicar-recurso" cameFromPublishButton={true}> + <Link to="/termos-publicar-recurso"> <ButtonPublicarRecurso> <CloudUploadIcon style={{color:"white", marginLeft : "0"}}/> <span style={{color : "#fff", textAlign: "center", alignSelf : "center", fontWeight:"500"}} > diff --git a/src/Components/MenuBarMobile.js b/src/Components/MenuBarMobile.js new file mode 100644 index 0000000000000000000000000000000000000000..4590e9dd578da0ed15a585e37982710e33cfced0 --- /dev/null +++ b/src/Components/MenuBarMobile.js @@ -0,0 +1,100 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + +import React from 'react' +import MenuIcon from '@material-ui/icons/Menu'; +import styled from 'styled-components' +import { Button } from '@material-ui/core' +import logo from '../img/logo_small.svg' +import { Link } from 'react-router-dom' +import Grid from '@material-ui/core/Grid'; +import MobileDrawerMenu from './MobileDrawerMenu'; + +export default function MenuBarMobile(props) { + + const [drawerOpen, setDrawerStatus] = React.useState(false); + + const toggleDrawer = (open) => (event) => { + if (event.type === 'keydown' && (event.key === 'Tab' || event.key === 'Shift')) { + return; + } + setDrawerStatus(open); + }; + + return ( + <> + <MobileDrawerMenu anchor={'left'} open={drawerOpen} + onClose={toggleDrawer(false)} + openSignUp={props.openSignUp} openLogin={props.openLogin} + /> + <OuterDiv> + <DrawerButtonDiv style={{justifySelf : "flex-start", position : "absolute", left : 0}}> + <Button style={{ color: "#00bcd4" }} onClick={toggleDrawer(true)}> + <MenuIcon className="icon" /> + </Button> + </DrawerButtonDiv> + <div className="logo"> + <Link to="/"> + <img src={logo} alt={"Plataforma Integrada"} /> + </Link> + </div> + </OuterDiv> + </> + ) +} + +const OuterDiv = styled.div` + height : 48px; + width : 100%; + display : flex; + flex-direction : row; + align-items : center; + justify-content : center; + position : relative; + + .logo { + align-content : center; + justify-self : center; + text-align : center; + img { + height : 38px; + overflow : hidden; + } + } + + .icon { + vertical-align : middle !important; + font-weight : normal !important; + font-style : normal !important; + font-size : 24px !important; + line-height : 1 !important; + letter-spacing : normal !important; + text-transform : none !important; + display : inline-block !important; + white-space : nowrap !important; + word-wrap : normal !important; + direction : ltr !important; + padding-right : 2px; + color : inherit !important; + } +` +const DrawerButtonDiv = styled.div` + justify-self : center; + position : absolute; + left : 0; +` \ No newline at end of file diff --git a/src/Components/MenuList.js b/src/Components/MenuList.js index 796b57b386e93056825e0ced50a2b1d8b4a4cae0..643b4b04a72b14cda85a328c8f14ee572a13be83 100644 --- a/src/Components/MenuList.js +++ b/src/Components/MenuList.js @@ -20,24 +20,15 @@ import React, {useContext} from 'react'; import Button from '@material-ui/core/Button'; import Menu from '@material-ui/core/Menu'; import MenuItem from '@material-ui/core/MenuItem'; -import AccountCircleRoundedIcon from '@material-ui/icons/AccountCircleRounded'; import KeyboardArrowDownIcon from '@material-ui/icons/KeyboardArrowDown'; import { Link } from 'react-router-dom' import ExitToAppIcon from '@material-ui/icons/ExitToApp'; import { Store } from '../Store'; -import { Redirect } from "react-router-dom"; import Profile from '../img/default_profile0.png' import styled from 'styled-components' import {apiDomain} from '../env.js' +import {deleteRequest} from './HelperFunctions/getAxiosConfig' -const iconStyles = { - fontSize : "xxx-large", - color: "white", - backgroundColor: "gray", - borderRadius : "50%", - overflow : "hidden", - border : "2px solid #fff", -} const OverrideButton = styled(Button)` text-transform : none !important; @@ -55,21 +46,15 @@ export default function MenuList(props) { setAnchorEl(null); }; - const handleLogout = () => { - localStorage.removeItem('@portalmec/username'); - sessionStorage.removeItem('@portalmec/uid'); - sessionStorage.removeItem('@portalmec/senha'); + function handleSuccessSignOut (data) { dispatch( { type: 'USER_LOGGED_OUT', userLoggedOut: !state.userIsLoggedIn, - login: { - username : '', - email : '', - accessToken : '', - client : '' - } - } - ) + }) + } + const handleLogout = () => { + const url = `/auth/sign_out` + deleteRequest(url, handleSuccessSignOut, (error) => {console.log(error)}) } return ( @@ -83,13 +68,13 @@ export default function MenuList(props) { > <div style={{borderRadius: "50%", border: "2px solid #fff", background: "#fff", overflow: "hidden", maxWidth : "50px", maxHeight : "50px"}}> { - state.currentUser.userAvatar == '' || state.currentUser.userAvatar == null ? + state.currentUser.avatar === '' || state.currentUser.avatar === null || state.currentUser.avatar === undefined ? ( <img src={Profile} alt={'user avatar'} style={{width:"100%", height:"100%", verticalAlign : "middle", marginLeft : "0"}}/> ): ( - <img src={apiDomain + state.currentUser.userAvatar} alt={'user avatar'} style={{width:"100%", height:"100%", verticalAlign : "middle", marginLeft : "0"}}/> + <img src={apiDomain + state.currentUser.avatar} alt={'user avatar'} style={{width:"100%", height:"100%", verticalAlign : "middle", marginLeft : "0"}}/> ) } </div> @@ -116,7 +101,7 @@ export default function MenuList(props) { <Link to={{ pathname : item.href, state : item.value - }} style={{textDecoration:"none"}} key={item.value}><MenuItem style= {{fontSize:"14px", padding:"5px 20px", color:"#666"}}>{item.name}</MenuItem></Link> + }} style={{textDecoration:"none"}} key={item.value}><MenuItem style= {{fontSize:"14px", padding:"5px 20px", color:"#666"}} key={item.value}>{item.name}</MenuItem></Link> ) } <StyledButtonSair onClick={handleLogout}> <StyledMenuItem disableGutters={true}>Sair<StyledExitToAppIcon/></StyledMenuItem></StyledButtonSair> diff --git a/src/Components/MobileDrawerMenu.js b/src/Components/MobileDrawerMenu.js new file mode 100644 index 0000000000000000000000000000000000000000..f872b4583c995b8ec6da6dad2d1d1c62b13d4b14 --- /dev/null +++ b/src/Components/MobileDrawerMenu.js @@ -0,0 +1,266 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + +import React, {useContext} from 'react' +import { Store } from '../Store'; +import Drawer from '@material-ui/core/Drawer'; +import styled from 'styled-components' +import {Link} from 'react-router-dom' +import HomeIcon from '@material-ui/icons/Home'; +import InfoIcon from '@material-ui/icons/Info'; +import MailOutlineIcon from '@material-ui/icons/MailOutline'; +import HelpOutlineIcon from '@material-ui/icons/HelpOutline'; +import AssignmentIcon from '@material-ui/icons/Assignment'; +import {ButtonStyled} from './MenuBar' +import ExitToAppIcon from '@material-ui/icons/ExitToApp' +import { Button } from '@material-ui/core'; +import DefaultAvatar from '../img/default_profile0.png' +import CloudUploadIcon from '@material-ui/icons/CloudUpload'; +import CloudDoneIcon from '@material-ui/icons/CloudDone'; +import HistoryIcon from '@material-ui/icons/History'; +import FavoriteBorderIcon from '@material-ui/icons/FavoriteBorder'; +import FolderOpenIcon from '@material-ui/icons/FolderOpen'; +import SettingsIcon from '@material-ui/icons/Settings'; +import {apiDomain} from '../env.js' +import {deleteRequest} from './HelperFunctions/getAxiosConfig' +import SearchIcon from '@material-ui/icons/Search'; + +export default function MobileDrawerMenu (props) { + const {state, dispatch} = useContext(Store) + + const menuSobre = [ + { name : "Página Inicial", href : "/", icon : <HomeIcon/>}, + { name : "Sobre a Plataforma", href : "sobre", icon : <InfoIcon/>}, + { name : "Contato", href : "contato", icon : <MailOutlineIcon/>}, + { name : "Central de Ajuda", href : "ajuda", icon : <HelpOutlineIcon/>}, + { name: "Busca", href: `/busca?query=${state.search.query}&search_class=${state.search.class}`, icon : <SearchIcon/>}, + { name : "Termos de Uso", href : "termos", icon : <AssignmentIcon/>}, + ] + + // {/*used in dynamic css selection*/} + const [selectedIndex, setSelectedIndex] = React.useState(-1); + const handleMenuItemClick = (event, index) => { + setSelectedIndex(index); + }; + + const getUserAvatar = () => { + if (state.currentUser.avatar === '' || state.currentUser.avatar == null) { + return DefaultAvatar + } + else { + return apiDomain + state.currentUser.avatar + } + } + + // {/*main user actions array */} + const minhaArea = [ + { name: "Publicar Recurso", href: "/termos-publicar-recurso", icon : <CloudUploadIcon/>}, + { name: "Recursos Publicados", href: "/perfil", icon : <CloudDoneIcon/>, value : '1'}, + { name: "Perfil e Atividades", href: "/perfil", icon : <HistoryIcon/>, value : '0'}, + { name: "Favoritos", href: "/perfil", icon : <FavoriteBorderIcon/>, value : '2'}, + { name: "Coleções", href: "/perfil", icon : <FolderOpenIcon/>, value : '3'}, + ] + + + function handleSuccessSignOut (data) { + dispatch( { + type: 'USER_LOGGED_OUT', + userLoggedOut: !state.userIsLoggedIn, + }) + } + const handleLogout = () => { + const url = `/auth/sign_out` + deleteRequest(url, handleSuccessSignOut, (error) => {console.log(error)}) + } + + return ( + <StyledDrawer anchor={props.anchor} open={props.open} onClose={props.onClose}> + <MenuBody> + {/*Renders menuSobre array options*/} + { + menuSobre.map( (item, index) => + <Link to={item.href} className={`menu-buttons ${selectedIndex === index ? 'selected' : ''}`} onClick={(event) => handleMenuItemClick(event, index)}> + {item.icon} + {item.name} + </Link> + ) + } + </MenuBody> + + + <div style={{borderTop : "1px solid #e5e5e5", borderBottom : "1px solid #e5e5e5", marginTop : "10px", paddingTop : "10px", marginBottom : "10px"}}> + { + /*If user is logged in, render user actions menu; else render log in/sign in buttons*/ + state.userIsLoggedIn ? + ( + <div style={{display : "flex", flexDirection : "column", color : "#666", paddingBottom : "10px"}}> + <MyArea> + <div className="user-avatar"> + <img alt="user-avatar" + src={getUserAvatar()} + /> + </div> + <span className="text">Minha área</span> + </MyArea> + + { + minhaArea.map( (item, index) => + <Link to={{ + pathname : item.href, + state: item.value + }} + className={`menu-buttons ${selectedIndex === (index + menuSobre.length) ? 'selected' : ''}`} + onClick={(event) => handleMenuItemClick(event, index + menuSobre.length)} + > + {item.icon} + {item.name} + </Link> + ) + } + + </div> + ) + : + ( + <React.Fragment> + <div style={{display : "flex", justifyContent : "center", marginTop : "10px"}}> + <ButtonPublicarRecurso onClick={props.openLogin}> + PUBLICAR RECURSO? + </ButtonPublicarRecurso> + </div> + + <div style={{display : "flex", flexDirection : "row", margin : "10px 0", justifyContent : "center"}}> + <div style={{borderRight : "1px solid #e5e5e5"}}> + <ButtonStyled onClick={props.openLogin}> + <ExitToAppIcon style={{color:"#00bcd4"}}/>Entrar + </ButtonStyled> + </div> + + <div> + <ButtonStyled onClick={props.openSignUp}> + Cadastre-se + </ButtonStyled> + </div> + </div> + </React.Fragment> + ) + } + </div> + { + /*Renders settings and log off buttons */ + state.userIsLoggedIn && + <React.Fragment> + <Link to={"/editarperfil"} className={`menu-buttons`}> + <SettingsIcon/> Configurações + </Link> + + <Link to={"/"} className={`menu-buttons`} onClick={handleLogout}> + <ExitToAppIcon/> Sair + </Link> + </React.Fragment> + } + </StyledDrawer> + ) +} + +const MyArea = styled.div` + margin : 0 16px; + display : flex; + flex-direction : row; + + .text { + font-size : 16px; + color : #666; + align-self : center; + } + + .user-avatar { + margin-right : 10px; + align-self : center; + border-radius : 50%; + border : 1px solid #fff; + max-width : 50px; + max-height : 50px; + overflow : hidden; + + img { + width : 100%; + height : 100%; + vertical-align : middle; + } + } +` + +const ButtonPublicarRecurso = styled(Button)` + font-weight : 500 !important; + border : 1.5px #666 solid !important; + color: #666; + box-shadow: none; + margin : 0 8px !important; + padding : 6px 25px !important; + +` + +const StyledDrawer = styled(Drawer)` + .MuiPaper-root { + width : 65% !important; + } + + .menu-buttons { + padding : 10px 16px; + font-size : 14px; + font-weight : 500; + cursor : pointer; + outline : 0; + color : #666 !important; + text-decoration : none !important; + background-color : transparent; + font-family : 'Roboto', sans serif; + + .MuiSvgIcon-root { + color : #a5a5a5 !important; + margin-right : 20px; + vertical-align : middle !important; + font-weight : normal !important; + font-style : normal !important; + font-size : 24px !important; + line-height : 1 !important; + letter-spacing : normal !important; + text-transform : none !important; + display : inline-block !important; + white-space : nowrap !important; + word-wrap : normal !important; + direction : ltr !important; + } + } + + .selected { + color : #fff !important; + background-color : #00bcd4; + .MuiSvgIcon-root { + color : #fff !important; + } + } +` + +const MenuBody = styled.div` + margin-top : 20px; + display : flex; + flex-direction : column; + color : #666; +` diff --git a/src/Components/Modal.js b/src/Components/Modal.js index cd970dd2d1436cdd4e423838ffd2f51235a9b183..dd2de1bc9e16debc20d88233ae5f907200dd79c2 100644 --- a/src/Components/Modal.js +++ b/src/Components/Modal.js @@ -23,11 +23,9 @@ import Modal from '@material-ui/core/Modal'; import TermsCarousel from './Carousel'; import Backdrop from '@material-ui/core/Backdrop'; -import Grid from '@material-ui/core/Grid'; import Fade from '@material-ui/core/Fade'; import VisibilityOutlinedIcon from '@material-ui/icons/VisibilityOutlined'; -import styled from 'styled-components' /*Importação de imagens para o componente*/ diff --git a/src/Components/ModalAbout.js b/src/Components/ModalAbout.js index 3739a8935ab0dcc98d29fde4c2bb956aa5c21d75..84998e7cbe28194b29663cc6fc47a78ba8cfeec3 100644 --- a/src/Components/ModalAbout.js +++ b/src/Components/ModalAbout.js @@ -23,9 +23,7 @@ import Modal from '@material-ui/core/Modal'; import Formulario from "./ContactForm"; import Backdrop from '@material-ui/core/Backdrop'; -import Grid from '@material-ui/core/Grid'; import Fade from '@material-ui/core/Fade'; -import VisibilityOutlinedIcon from '@material-ui/icons/VisibilityOutlined'; import styled from 'styled-components' diff --git a/src/Components/ModalAlterarAvatar/ComponentAlterarAvatar.js b/src/Components/ModalAlterarAvatar/ComponentAlterarAvatar.js index 657c8183971fc197ba1c1a4a36dd1f4e6d31fe21..8936af0a751bcd2d139c08bf631e489415688a24 100644 --- a/src/Components/ModalAlterarAvatar/ComponentAlterarAvatar.js +++ b/src/Components/ModalAlterarAvatar/ComponentAlterarAvatar.js @@ -18,17 +18,13 @@ along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/> import React, {useContext, useState} from 'react'; import { Button } from '@material-ui/core'; -import Modal from '@material-ui/core/Modal'; -import Backdrop from '@material-ui/core/Backdrop'; -import Zoom from '@material-ui/core/Fade'; import styled from 'styled-components' import {Store} from '../../Store.js' -import axios from 'axios' -import {apiUrl, apiDomain} from '../../env'; +import {apiDomain} from '../../env'; import CloseIcon from '@material-ui/icons/Close'; import Profile from '../../img/default_profile0.png' import Cropper from '../Cropper.js' - +import {putRequest} from '../HelperFunctions/getAxiosConfig' function ChooseImage (props) { return ( @@ -54,7 +50,7 @@ function ChooseImage (props) { </DivAlterarFoto> { props.tempImg && - <img src={props.tempImg}/> + <img alt="" src={props.tempImg}/> } <ButtonsDiv> <ButtonCancelar onClick={props.handleClose}> @@ -68,21 +64,6 @@ function ChooseImage (props) { ) } -const GetHeaderConfig = () => { - - let config = { - headers : { - 'Accept': 'application/json', - 'Content-Type': 'application/json', - 'Access-Token': sessionStorage.getItem('@portalmec/accessToken'), - 'Client': sessionStorage.getItem('@portalmec/clientToken'), - 'Uid': sessionStorage.getItem('@portalmec/uid'), - } - } - {/*'Host': 'api.portalmec.c3sl.ufpr.br', - 'Cookie': ''*/} - return config -} export default function ComponentAlterarAvatar (props) { const {state, dispatch} = useContext(Store) @@ -106,28 +87,23 @@ export default function ComponentAlterarAvatar (props) { aspect: 1 }); + function handleSuccess(data) { + const target = state.currentUser + const source = {userAvatar : data.avatar} + dispatch({ + type : 'USER_CHANGED_COVER', + currUser : Object.assign(target, source) + }) + } + const completeSelection = () => { - console.log(newAvatar) + const url = `/users/${props.id}` + //newAvatar is a base64 encoded image file let fdAvatar = new FormData() fdAvatar.set('user[avatar]', newAvatar) - axios.put( (`${apiUrl}/users/` + props.id ), - fdAvatar, - GetHeaderConfig() - ).then( (response) => { - console.log(response) - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - const target = state.currentUser - const source = {userAvatar : response.data.avatar} - dispatch({ - type : 'USER_CHANGED_COVER', - currUser : Object.assign(target, source) - }) - }, (error) => {console.log(error)} - ) + putRequest(url, fdAvatar, handleSuccess, (error) => {console.log(error)}) } return ( diff --git a/src/Components/ModalAlterarAvatar/ModalAlterarAvatar.js b/src/Components/ModalAlterarAvatar/ModalAlterarAvatar.js index 0698c94b2a09389d8f787f36bc29c5975ea390b0..735832040ab11c6b79e7f969bb554e42a514ebfe 100644 --- a/src/Components/ModalAlterarAvatar/ModalAlterarAvatar.js +++ b/src/Components/ModalAlterarAvatar/ModalAlterarAvatar.js @@ -17,16 +17,10 @@ You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ import React from 'react'; -import { Button } from '@material-ui/core'; import Modal from '@material-ui/core/Modal'; import Backdrop from '@material-ui/core/Backdrop'; import Fade from '@material-ui/core/Fade'; import styled from 'styled-components' -import {Store} from '../../Store.js' -import axios from 'axios' -import {apiUrl} from '../../env'; -import CloseIcon from '@material-ui/icons/Close'; -import Profile from '../../img/default_profile0.png' import ComponentAlterarAvatar from './ComponentAlterarAvatar.js' const StyledModal = styled(Modal)` diff --git a/src/Components/ModalAlterarCover/ComponentAlterarCover.js b/src/Components/ModalAlterarCover/ComponentAlterarCover.js index 4178b3cf9cdf4d74f9197b4c341ad779b40db235..99a5f5493eca3735ae00b5a2431934ed5b9f8201 100644 --- a/src/Components/ModalAlterarCover/ComponentAlterarCover.js +++ b/src/Components/ModalAlterarCover/ComponentAlterarCover.js @@ -18,37 +18,16 @@ along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/> import React, {useContext, useState} from 'react'; import { Button } from '@material-ui/core'; -import Modal from '@material-ui/core/Modal'; -import Backdrop from '@material-ui/core/Backdrop'; -import Zoom from '@material-ui/core/Fade'; import styled from 'styled-components' import {Store} from '../../Store.js' -import axios from 'axios' -import {apiUrl, apiDomain} from '../../env'; import CloseIcon from '@material-ui/icons/Close'; -import Profile from '../../img/default_profile0.png' import Cropper from '../Cropper.js' - - -const GetHeaderConfig = () => { - - let config = { - headers : { - 'Accept': 'application/json', - 'Content-Type': 'application/json', - 'Access-Token': sessionStorage.getItem('@portalmec/accessToken'), - 'Client': sessionStorage.getItem('@portalmec/clientToken'), - 'Uid': sessionStorage.getItem('@portalmec/uid'), - } - } - {/*'Host': 'api.portalmec.c3sl.ufpr.br', - 'Cookie': ''*/} - return config -} +import {putRequest} from '../HelperFunctions/getAxiosConfig' export default function ComponentAlterarCover (props) { const {state, dispatch} = useContext(Store) + // eslint-disable-next-line const [tempImgURL, setTempImg] = useState(props.cover) const [newCover, setNewCover] = useState('') const updateCover = (cover) => {setNewCover(cover)} @@ -58,27 +37,23 @@ export default function ComponentAlterarCover (props) { aspect: 16 / 9 }); + function handleSuccess (data) { + const target = state.currentUser + const source = {userCover : data.cover} + dispatch({ + type : 'USER_CHANGED_COVER', + currUser : Object.assign(target, source) + }) + } + const completeSelection = () => { - console.log(newCover) + const url = `/users/${props.id}` + //newCover is a base64 encoded image file. let fdCover = new FormData() fdCover.set('user[cover]', newCover) - axios.put( (`${apiUrl}/users/` + props.id ), - fdCover, - GetHeaderConfig() - ).then( (response) => { - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - const target = state.currentUser - const source = {userCover : response.data.cover} - dispatch({ - type : 'USER_CHANGED_COVER', - currUser : Object.assign(target, source) - }) - }, (error) => {console.log(error)} - ) + putRequest(url, fdCover, handleSuccess, (error) => {console.log(error)}) } return ( diff --git a/src/Components/ModalAlterarCover/ModalAlterarCover.js b/src/Components/ModalAlterarCover/ModalAlterarCover.js index 86636826010d9e129fd22192535c8aec56c310ed..7e971f5806c6cee5239b1b480cc166c5b31b05a3 100644 --- a/src/Components/ModalAlterarCover/ModalAlterarCover.js +++ b/src/Components/ModalAlterarCover/ModalAlterarCover.js @@ -16,17 +16,11 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useContext, useState} from 'react'; -import { Button } from '@material-ui/core'; +import React from 'react'; import Modal from '@material-ui/core/Modal'; import Backdrop from '@material-ui/core/Backdrop'; import Fade from '@material-ui/core/Fade'; import styled from 'styled-components' -import {Store} from '../../Store.js' -import axios from 'axios' -import {apiUrl} from '../../env'; -import CloseIcon from '@material-ui/icons/Close'; -import Profile from '../../img/default_profile0.png' import ComponentAlterarCover from './ComponentAlterarCover.js' const StyledModal = styled(Modal)` @@ -38,24 +32,7 @@ const StyledModal = styled(Modal)` ` export default function ModarAlterarCover (props){ - const {state, dispatch} = useContext(Store) - const [avatarFile, setFile] = useState('') - - {/*const handleUploadCover = (img) => { - axios.post(`${apiUrl}`, - { - - } - ).then( (response) => { - dispatch ({ - - }, (error) => { - - } - ) - }) - }*/} - + return ( <StyledModal diff --git a/src/Components/ModalAvaliarRecurso.js b/src/Components/ModalAvaliarRecurso.js index 9d6c588e45636305070905de8b59b0b0dcdc2f89..8604461a878c3b4e781d23ef9bc6f779bea276b6 100644 --- a/src/Components/ModalAvaliarRecurso.js +++ b/src/Components/ModalAvaliarRecurso.js @@ -22,9 +22,6 @@ import Modal from '@material-ui/core/Modal'; import Backdrop from '@material-ui/core/Backdrop'; import Fade from '@material-ui/core/Fade'; import styled from 'styled-components' -import {Store} from '../Store.js' -import axios from 'axios' -import {apiDomain} from '../env'; import Grid from '@material-ui/core/Grid'; import RadioGroup from '@material-ui/core/RadioGroup'; import Radio from '@material-ui/core/Radio'; @@ -32,7 +29,6 @@ import FormControl from '@material-ui/core/FormControl'; import FormControlLabel from '@material-ui/core/FormControlLabel'; import CloseModalButton from './CloseModalButton' import Snackbar from '@material-ui/core/Snackbar'; -import Alert from '../Components/Alert.js'; import TextField from '@material-ui/core/TextField'; import { withStyles } from '@material-ui/core/styles'; @@ -232,16 +228,6 @@ const Header = styled.div` } ` -const StyledCloseModalButton = styled(Button)` - display : inline-block; - position : relative; - float : right !important; - margin-right : -8px !important; - background : transparent !important; - min-width: 0 !important; - width : 40px; -` - const StyledModal = styled(Modal)` .djXaxP{ margin : 0 !important; diff --git a/src/Components/ModalConfirmarCuradoria.js b/src/Components/ModalConfirmarCuradoria.js index 9e12906b13c7e0a0457819160a1dd358515c7b24..4687b1876be5b3ae5376901a97eb2e00aca3df66 100644 --- a/src/Components/ModalConfirmarCuradoria.js +++ b/src/Components/ModalConfirmarCuradoria.js @@ -16,22 +16,14 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useState} from 'react'; +import React from 'react'; import { Button } from '@material-ui/core'; import Modal from '@material-ui/core/Modal'; import Backdrop from '@material-ui/core/Backdrop'; import Fade from '@material-ui/core/Fade'; import styled from 'styled-components' -import {Store} from '../Store.js' -import axios from 'axios' -import {apiDomain, apiUrl} from '../env'; -import Grid from '@material-ui/core/Grid'; -import RadioGroup from '@material-ui/core/RadioGroup'; -import Radio from '@material-ui/core/Radio'; -import FormControl from '@material-ui/core/FormControl'; -import FormControlLabel from '@material-ui/core/FormControlLabel'; import CloseModalButton from './CloseModalButton' -import {getAxiosConfig} from './HelperFunctions/getAxiosConfig' +import {postRequest} from './HelperFunctions/getAxiosConfig' export default function ModalConfirmarCuradoriaOpen (props) { @@ -48,8 +40,11 @@ export default function ModalConfirmarCuradoriaOpen (props) { return newArr } + function handleSuccess (data) { + props.finalizeCuratorshipFlow() + } const handleConfirmation = () => { - let config = getAxiosConfig() + const url = `/submissions/${props.recursoId}/answer` let payload = { "submission" : { @@ -57,16 +52,7 @@ export default function ModalConfirmarCuradoriaOpen (props) { "answers" : transformReportCriteria(props.reportCriteria) } } - - axios.post( (`${apiUrl}/submissions/` + props.recursoId + '/answer'), payload, config).then( - (response) => { - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - console.log(response.data) - props.finalizeCuratorshipFlow() - }, (error) => {console.log(error)} - ) + postRequest(url, payload, handleSuccess, (error) => {console.log(error)}) } return ( @@ -163,16 +149,6 @@ const Header = styled.div` } ` -const StyledCloseModalButton = styled(Button)` - display : inline-block; - position : relative; - float : right !important; - margin-right : 4px !important; - background : transparent !important; - min-width: 0 !important; - width : 40px; -` - const StyledModal = styled(Modal)` .djXaxP{ margin : 0 !important; diff --git a/src/Components/ModalConfirmarUnfollow.js b/src/Components/ModalConfirmarUnfollow.js index f8deb98a454280ce7a6c78f952caabf12f3e2527..7d349e085ec89cac173286a5406a810cc08d04dd 100644 --- a/src/Components/ModalConfirmarUnfollow.js +++ b/src/Components/ModalConfirmarUnfollow.js @@ -1,13 +1,9 @@ -import React, {useContext} from 'react'; +import React from 'react'; import Modal from '@material-ui/core/Modal'; import Fade from '@material-ui/core/Fade'; import styled from 'styled-components' import { Button } from '@material-ui/core'; import Backdrop from '@material-ui/core/Backdrop'; -import { Store } from '../Store.js'; -import axios from 'axios' -import {apiUrl} from '../env'; -import CloseIcon from '@material-ui/icons/Close'; import CloseModalButton from './CloseModalButton' const StyledModal = styled(Modal)` diff --git a/src/Components/ModalEditarColecao.js b/src/Components/ModalEditarColecao.js new file mode 100644 index 0000000000000000000000000000000000000000..8617baf38ccb065bef540c6767237d03df587324 --- /dev/null +++ b/src/Components/ModalEditarColecao.js @@ -0,0 +1,113 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + +import React from 'react' +import Modal from '@material-ui/core/Modal'; +import Backdrop from '@material-ui/core/Backdrop'; +import Fade from '@material-ui/core/Fade'; +import styled from 'styled-components' +import CloseModalButton from './CloseModalButton' +import EditarColecaoForm from './EditarColecaoForm.js' +export default function ModalEditarColecao (props) { + + return ( + <StyledModal + aria-labelledby="transition-modal-title" + aria-describedby="transition-modal-description" + open={props.open} + + centered="true" + onClose={props.handleClose} + closeAfterTransition + BackdropComponent={Backdrop} + BackdropProps={{ + timeout: 500, + }} + > + <Fade in={props.open}> + <Container> + <Header> + <span style={{width:"32px"}}/> + <h2>Editar Coleção</h2> + <CloseModalButton handleClose={props.handleClose} id={props.id}/> + </Header> + <Content style={{paddingTop : "0"}}> + <EditarColecaoForm id={props.id} handleClose={props.handleClose} finalize={props.handleClose}/> + </Content> + </Container> + </Fade> + </StyledModal> + ) +} + +const Content = styled.div` + padding : 20px 30px; + overflow-y: visible; + +` + +const Header = styled.div` + display : flex; + flex-direction : row; + padding : 10px 26px 0 26px; + align-items : center; + justify-content : space-between; + height : 64px; + + h2 { + font-size : 26px; + font-weight : lighter; + color : #666 + } +` + +const StyledModal = styled(Modal)` + .djXaxP{ + margin : 0 !important; + } + display : flex; + align-items: center; + justify-content : center; + text-align : center; + padding : 10px !important; + max-width : none; + max-height : none; +` + +const Container = styled.div` + box-sizing : border-box; + box-shadow : 0 7px 8px -4px rgba(0,0,0,.2),0 13px 19px 2px rgba(0,0,0,.14),0 5px 24px 4px rgba(0,0,0,.12); + background-color : white; + align : center; + display : flex; + flex-direction : column; + min-width : 240px; + max-height : none; + position : relative; + padding : 10px; + border-radius : 4px; + + @media screen and (min-width : 96px) { + width : 500px; + } + + @media screen and (max-width : 699px) { + width : 100%; + height : 100%; + } +` diff --git a/src/Components/ModalExcluirColecao.js b/src/Components/ModalExcluirColecao.js index 9c1b61b65600d0bef69cf3ee21bd37ec03216f7c..879112aebb46690447dcc1b3cdecb62e90adbbff 100644 --- a/src/Components/ModalExcluirColecao.js +++ b/src/Components/ModalExcluirColecao.js @@ -17,34 +17,26 @@ You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ import React, {useState} from 'react'; -import { Button } from '@material-ui/core'; import Modal from '@material-ui/core/Modal'; import Backdrop from '@material-ui/core/Backdrop'; import Fade from '@material-ui/core/Fade'; import styled from 'styled-components' -import {Store} from '../Store.js' -import axios from 'axios' -import {apiUrl} from '../env'; import GreyButton from './GreyButton.js' import PurpleButton from './PurpleButton.js' -import {getAxiosConfig} from '../Components/HelperFunctions/getAxiosConfig' import SnackbarComponent from './SnackbarComponent' +import {deleteRequest} from './HelperFunctions/getAxiosConfig' export default function ModalExcluirColecao (props) { const [snackbarOpen, toggleSnackbar] = useState(false) + function handleDeleteSuccess (data) { + toggleSnackbar(true) + props.handleClose() + } const handleDelete = () => { - let config = getAxiosConfig() - - axios.delete( (`${apiUrl}/collections/` + props.id), config - ).then( (response) => { - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - console.log(response) - toggleSnackbar(true) - props.handleClose() - }, (error) => {console.log(error);}) + const url = `/collections/${props.id}` + + deleteRequest(url, handleDeleteSuccess, (error) => {console.log(error)}) } return ( diff --git a/src/Components/ModalExcluirComentario.js b/src/Components/ModalExcluirComentario.js index 88ceeceff8c5c798b2e1fe85872451a43178172e..1345ee369a1471558274f42c3d6574c92122dfdb 100644 --- a/src/Components/ModalExcluirComentario.js +++ b/src/Components/ModalExcluirComentario.js @@ -1,12 +1,9 @@ -import React, {useContext} from 'react'; +import React from 'react'; import Modal from '@material-ui/core/Modal'; import Fade from '@material-ui/core/Fade'; import styled from 'styled-components' import { Button } from '@material-ui/core'; import Backdrop from '@material-ui/core/Backdrop'; -import { Store } from '../Store.js'; -import axios from 'axios' -import {apiUrl} from '../env'; const StyledModal = styled(Modal)` margin : 0 !important; @@ -69,7 +66,7 @@ export default function ModalExcluir (props) { aria-labelledby="transition-modal-title" aria-describedby="transition-modal-description" open={props.open} - + centered="true" onClose={props.handleClose} closeAfterTransition @@ -101,3 +98,4 @@ export default function ModalExcluir (props) { ) } + diff --git a/src/Components/ModalLearningObjectPublished.js b/src/Components/ModalLearningObjectPublished.js index 8fe0d148a07896c378474e0928e2684ab0eb6ae2..2a8fbd78bb463b752ded4ac47d16a11292f060b0 100644 --- a/src/Components/ModalLearningObjectPublished.js +++ b/src/Components/ModalLearningObjectPublished.js @@ -16,16 +16,12 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useRef} from 'react'; +import React from 'react'; import { Button } from '@material-ui/core'; import Modal from '@material-ui/core/Modal'; import Backdrop from '@material-ui/core/Backdrop'; import Fade from '@material-ui/core/Fade'; import styled from 'styled-components' -import SignUpContainer from './SignUpContainerFunction.js' -import {Store} from '../Store.js' -import axios from 'axios' -import {apiDomain} from '../env'; import Grid from '@material-ui/core/Grid'; import Facebook from '../img/facebook.svg' import Twitter from '../img/twitter.svg' @@ -33,12 +29,12 @@ import LinkIcon from '../img/link_icon.svg' import CloseModalButton from './CloseModalButton.js' export default function ModalLearningObjectPublished (props) { - const refContainer = useRef(props.link); + // const refContainer = useRef(props.link); - function copyToClipboard(e) { - let copyText = document.getElementById('p-text') - console.log(copyText) - }; + // function copyToClipboard(e) { + // let copyText = document.getElementById('p-text') + // console.log(copyText) + // }; return ( <StyledModal @@ -79,6 +75,7 @@ export default function ModalLearningObjectPublished (props) { <div className="logos-shared"> <a href={"https://www.facebook.com/sharer/sharer.php?u=https://plataformaintegrada.mec.gov.br/recurso/" + props.draftID} + rel="noreferrer" target="_blank"> <ShareButton> <img src={Facebook} alt="facebook-logo"/> @@ -87,6 +84,7 @@ export default function ModalLearningObjectPublished (props) { <a href={"https://www.twitter.com/intent/tweet?url=https://plataformaintegrada.mec.gov.br/recurso/" + props.draftID} + rel="noreferrer" target="_blank"> <ShareButton> <img src={Twitter} alt="twitter-logo"/> @@ -186,16 +184,6 @@ const Header = styled.div` } ` -const StyledCloseModalButton = styled(Button)` - display : inline-block; - position : relative; - float : right !important; - margin-right : -8px !important; - background : transparent !important; - min-width: 0 !important; - width : 40px; -` - const StyledModal = styled(Modal)` .djXaxP{ margin : 0 !important; diff --git a/src/Components/ModalVideoApresentacao.js b/src/Components/ModalVideoApresentacao.js new file mode 100644 index 0000000000000000000000000000000000000000..286cdf69dd9c4bf42c8e94c9a84a8010d0f4091e --- /dev/null +++ b/src/Components/ModalVideoApresentacao.js @@ -0,0 +1,78 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + +import React from 'react'; +import Modal from '@material-ui/core/Modal'; +import Backdrop from '@material-ui/core/Backdrop'; +import Fade from '@material-ui/core/Fade'; +import styled from 'styled-components'; + +export default function ModalVideoApresentacao (props) { + + return ( + <StyledModal + aria-labelledby="transition-modal-title" + aria-describedby="transition-modal-description" + open={props.open} + centered="true" + onClose={props.handleClose} + closeAfterTransition + BackdropComponent={Backdrop} + BackdropProps={{ + timeout: 500, + }} + > + <Fade in={props.open}> + <VideoContainer> + <iframe + title="Video Apresentação" + src="https://www.youtube.com/embed/gejBqyfJr9A" width="560" height="315" + frameBorder="0" allowFullScreen className="video" + /> + </VideoContainer> + </Fade> + </StyledModal> + ) +} + +const VideoContainer = styled.div` + position : relative; + width : 70%; + height : 70%; + + .video { + width : 100%; + height : 100%; + position : absolute; + top : 0; + left : 0; + } +` + +const StyledModal = styled(Modal)` + .djXaxP{ + margin : 0 !important; + } + display : flex; + align-items: center; + justify-content : center; + text-align : center; + padding : 10px !important; + max-width : none; + max-height : none; +` diff --git a/src/Components/Notifications.js b/src/Components/Notifications.js index 03f16486b99a2b9efdd96b6def38d08c97f507b4..cf8a2f055f3fc17d46b9ba856d05c3bfa96b7b8d 100644 --- a/src/Components/Notifications.js +++ b/src/Components/Notifications.js @@ -21,16 +21,12 @@ import { Button } from '@material-ui/core'; import Badge from '@material-ui/core/Badge'; import styled from 'styled-components' import Menu from '@material-ui/core/Menu'; -import ListItemIcon from '@material-ui/core/ListItemIcon'; -import MenuItem from '@material-ui/core/MenuItem'; -import MoreVertIcon from '@material-ui/icons/MoreVert'; -import OpenIcon from '@material-ui/icons/OpenInNew'; -import ReportIcon from '@material-ui/icons/Error'; -import NotificationsInner from './NotificationsInner.js' -import {apiDomain, apiUrl} from '../env.js' -import axios from 'axios' +import {apiDomain} from '../env.js' import ActivityListItem from './ActivityListItem.js' -import {getAxiosConfig} from './HelperFunctions/getAxiosConfig.js' +import {getRequest} from './HelperFunctions/getAxiosConfig.js' +import { withStyles } from '@material-ui/core/styles'; +import {Link} from 'react-router-dom' + const StyledBadge = styled(Badge) ` .MuiBadge-dot-45{ height : 9px ; @@ -55,29 +51,50 @@ const StyledNotificationButton = styled(Button)` } ` +const StyledMenu = withStyles({ + paper: { + border: '1px solid #d3d4d5', + }, +})((props) => ( + <Menu + elevation={0} + getContentAnchorEl={null} + anchorOrigin={{ + horizontal: 'center', + vertical: "bottom", + }} + transformOrigin={{ + vertical: 'top', + horizontal: 'center', + }} + {...props} + /> +)); + export default function Notification (props) { const [anchorEl, setAnchorEl] = React.useState(null); const [notifications, setNotifications] = useState([]); + // eslint-disable-next-line const [notificatonsLength, setLength] = useState(0); - useEffect(() => { - let config = getAxiosConfig() - axios.get(`${apiUrl}/feed?offset=0&limit=30`, config) - .then( (response) => { - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - console.log('atividades response: ', response) - setNotifications(response.data) - setLength(response.data.length) + function handleAxiosSuccess (data) { + setNotifications(data) + setLength(data.length) + } + + function handleAxiosError (error) { + console.log('error getNotifications') + console.log(error) + } + - }, - (error) => { - console.log('error while running getNotifications') - } - ) + useEffect(() => { + getRequest('/feed?offset=0&limit=30', handleAxiosSuccess, handleAxiosError) }, []) + + function handleClick(event) { + console.log('event.currentTarget: ', event.currentTarget) setAnchorEl(event.currentTarget); } @@ -118,6 +135,13 @@ export default function Notification (props) { /> ) } + <div style={{padding : "0 15px", borderTop : "1px solid #dadada"}}> + <Link to="/perfil"> + <NoPadButton> + MOSTRAR TODAS + </NoPadButton> + </Link> + </div> </ContainerDiv> </StyledMenu> </React.Fragment> @@ -125,8 +149,8 @@ export default function Notification (props) { } -const StyledMenu = styled(Menu)` - +const NoPadButton = styled(Button)` + padding : 6px 0 !important; ` const ContainerDiv = styled.div` @@ -134,15 +158,16 @@ const ContainerDiv = styled.div` right : 5%; width : 360px; max-height : 400px; - position : absolute; box-shadow : 8px 8px 8px 8px rgba(0,0,0,.1); overflow-y : scroll; padding : 5px 5px 5px 5px; min-width : 160px; + background-color : #f1f1f1; .cabecalho { - border-bottom : 1px solid #666; + border-bottom : 1px solid #dadada; + padding : 10px 15px; .cabecalho-marcar { font-family: Lato,bold; diff --git a/src/Components/NotificationsInner.js b/src/Components/NotificationsInner.js index 5b80924a112447925393c4d6a3117aa9826d7e58..4630287968d81ff709a2fb3d4dd46e88ab70d38e 100644 --- a/src/Components/NotificationsInner.js +++ b/src/Components/NotificationsInner.js @@ -1,30 +1,21 @@ import React, {useState, useContext, useEffect} from 'react' import styled from 'styled-components' -import {apiDomain, apiUrl} from '../env.js' -import axios from 'axios' +import {apiDomain} from '../env.js' import ActivityListItem from './ActivityListItem.js' -import {getAxiosConfig} from './HelperFunctions/getAxiosConfig.js' +import {getRequest} from './HelperFunctions/getAxiosConfig' export default function NotificationInner (props) { const [notifications, setNotifications] = useState([]); const [notificatonsLength, setLength] = useState(0); - useEffect(() => { - let config = getAxiosConfig() - axios.get(`${apiUrl}/feed?offset=0&limit=30`, config) - .then( (response) => { - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - console.log('atividades response: ', response) - setNotifications(response.data) - setLength(response.data.length) + function handleSuccess (data) { + setNotifications(data) + setLength(data.length) + } + useEffect(() => { + const url = `/feed?offset=0&limit=30` - }, - (error) => { - console.log('error while running getNotifications') - } - ) + getRequest(url, handleSuccess, (error) => {console.log('error while running getNotifications')}) }, []) return ( diff --git a/src/Components/PageProfessorComponents/ModalConfirmarProfessor.js b/src/Components/PageProfessorComponents/ModalConfirmarProfessor.js index cc25a3b4aeb1f0fad21b2d9f56e6b9d6f915c719..f8bceee1e9452edcd3562d71f954d923a21d7d91 100644 --- a/src/Components/PageProfessorComponents/ModalConfirmarProfessor.js +++ b/src/Components/PageProfessorComponents/ModalConfirmarProfessor.js @@ -16,14 +16,12 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useContext, useState} from 'react'; +import React from 'react'; import { Button } from '@material-ui/core'; import Modal from '@material-ui/core/Modal'; import Backdrop from '@material-ui/core/Backdrop'; import Fade from '@material-ui/core/Fade'; import styled from 'styled-components' -import axios from 'axios' -import {apiUrl} from '../../env'; import CloseIcon from '@material-ui/icons/Close'; const StyledModal = styled(Modal)` diff --git a/src/Components/PageProfessorComponents/PartOne.js b/src/Components/PageProfessorComponents/PartOne.js index 6fe3e70cb933c64da77e923804f69fe375fbc580..ad8fcf9a72464421bb2a467cd1c4b32aa9244db0 100644 --- a/src/Components/PageProfessorComponents/PartOne.js +++ b/src/Components/PageProfessorComponents/PartOne.js @@ -88,7 +88,6 @@ export default function PartOne (props) { } const handleSubmit = () => { - console.log('handle submit : ', uf.abbreviation, uf.name, municipio.name, codigoINEP.value) props.handleBuscar(uf.abbreviation, uf.name, municipio.name, codigoINEP.value) } diff --git a/src/Components/PageProfessorComponents/PartThree.js b/src/Components/PageProfessorComponents/PartThree.js index 2ee7c262ad0e85e3ba1a3c6221cf5241bde4b207..d52d17ba19da2ebb4a9105dc028c2d4d249aa940 100644 --- a/src/Components/PageProfessorComponents/PartThree.js +++ b/src/Components/PageProfessorComponents/PartThree.js @@ -1,8 +1,7 @@ import React, {useState} from 'react' -import {Content, ButtonsArea} from './PartOne.js' +import {Content} from './PartOne.js' import {ButtonCancelar, ButtonGrey} from './PartTwo.js' import FormControl from '@material-ui/core/FormControl'; -import InputLabel from '@material-ui/core/InputLabel'; import Stepper from '../Stepper.js' import FormInput from '../FormInput.js' import styled from 'styled-components' diff --git a/src/Components/PasswordRecoveryComponents/Success.js b/src/Components/PasswordRecoveryComponents/Success.js index d366bc3c8958f7560816e5ee27fe0172c0fb2789..34feb617ef2094f169acb826e40ea73cd16d4e8a 100644 --- a/src/Components/PasswordRecoveryComponents/Success.js +++ b/src/Components/PasswordRecoveryComponents/Success.js @@ -1,6 +1,4 @@ import React from 'react' -import {CompletarCadastroButton} from '../TabPanels/UserPageTabs/PanelSolicitarContaProfessor.js' -import FormInput from "../FormInput.js" export default function Default (props) { return ( diff --git a/src/Components/PublicationPermissionsContent.js b/src/Components/PublicationPermissionsContent.js index fe3536dc8c3afb0eb810835cb5f5c56430660d21..ddccba30f8c1ec5f98349ae1e9589c2a90554dca 100644 --- a/src/Components/PublicationPermissionsContent.js +++ b/src/Components/PublicationPermissionsContent.js @@ -8,19 +8,13 @@ import Radio from '@material-ui/core/Radio'; import FormControl from '@material-ui/core/FormControl'; import Grid from '@material-ui/core/Grid'; import { withStyles } from '@material-ui/core/styles'; -import axios from 'axios' -import {apiUrl} from '../env'; +import {getRequest} from './HelperFunctions/getAxiosConfig' const StyledFormControl = styled(FormControl)` display: "block ruby"; margin-top : 0 !important ; ` -const StyledDivEvaluateQuestion = styled.div` - display :flex; - justify-content : space-between; -` - const BlueRadio = withStyles({ root: { color: '#666', @@ -32,21 +26,18 @@ const BlueRadio = withStyles({ })((props) => <Radio color="default" {...props} />); export default function PublicationPermissionsContent (props) { - {/*To DO change to get https://api.portalmec.c3sl.ufpr.br/v1/questions*/} const [questionsArr, setQuestionsArr] = useState([]) const handleSetQuestionsArr = (newArr) => {setQuestionsArr(newArr)} + function handleSuccess (data) { + handleSetQuestionsArr(data) + } + useEffect(() => { - axios.get(`${apiUrl}/questions/`).then( - (response) => { - console.log(response) - handleSetQuestionsArr(response.data) - }, - (error) => { - console.log('falhou em get questions') - } - ) + const url = `/questions/` + + getRequest(url, handleSuccess, (error) => {console.log(error)}) }, []) @@ -86,7 +77,7 @@ export default function PublicationPermissionsContent (props) { </RadioGroup> </Grid> </React.Fragment> - + ) } </Grid> @@ -97,37 +88,37 @@ export default function PublicationPermissionsContent (props) { ) } -{/* - <Grid item xs={10}> - <p> - O recurso apresenta conteúdo de cunho político-partidário? (Ex: o conteúdo expressa qualquer forma de manifestação que se caracterize como propaganda política)? - </p> - </Grid> - <Grid item xs={2}> - <RadioGroup row name="radio1" onChange={props.handleRadios}> - <FormControlLabel value="Sim" control={<BlueRadio/>} label="Sim"/> <FormControlLabel value="Não" control={<BlueRadio/>} label="Não"/> - </RadioGroup> - </Grid> +// {/* +// <Grid item xs={10}> +// <p> +// O recurso apresenta conteúdo de cunho político-partidário? (Ex: o conteúdo expressa qualquer forma de manifestação que se caracterize como propaganda política)? +// </p> +// </Grid> +// <Grid item xs={2}> +// <RadioGroup row name="radio1" onChange={props.handleRadios}> +// <FormControlLabel value="Sim" control={<BlueRadio/>} label="Sim"/> <FormControlLabel value="Não" control={<BlueRadio/>} label="Não"/> +// </RadioGroup> +// </Grid> - <Grid item xs={10}> - <p> - O recurso apresenta conteúdo ofensivo? (Ex: material pornográfico e/ou que invada a privacidade de terceiros, viole os Direitos Humanos ou seja ilegal, ofensivo, e que incite a violência)? - </p> - </Grid> - <Grid item xs={2}> - <RadioGroup row name="radio2" onChange={props.handleRadios}> - <FormControlLabel value="Sim" control={<BlueRadio/>} label="Sim"/> <FormControlLabel value="Não" control={<BlueRadio/>} label="Não"/> - </RadioGroup> - </Grid> - <Grid item xs={10}> - <p> - O recurso apresenta algum tipo de propaganda ou marca? (Ex: o conteúdo tem cunho comercial)? - </p> - </Grid> - <Grid item xs={2}> - <RadioGroup row name="radio3" onChange={props.handleRadios}> - <FormControlLabel value="Sim" control={<BlueRadio/>} label="Sim"/> <FormControlLabel value="Não" control={<BlueRadio/>} label="Não"/> - </RadioGroup> - </Grid> - </Grid> - */} +// <Grid item xs={10}> +// <p> +// O recurso apresenta conteúdo ofensivo? (Ex: material pornográfico e/ou que invada a privacidade de terceiros, viole os Direitos Humanos ou seja ilegal, ofensivo, e que incite a violência)? +// </p> +// </Grid> +// <Grid item xs={2}> +// <RadioGroup row name="radio2" onChange={props.handleRadios}> +// <FormControlLabel value="Sim" control={<BlueRadio/>} label="Sim"/> <FormControlLabel value="Não" control={<BlueRadio/>} label="Não"/> +// </RadioGroup> +// </Grid> +// <Grid item xs={10}> +// <p> +// O recurso apresenta algum tipo de propaganda ou marca? (Ex: o conteúdo tem cunho comercial)? +// </p> +// </Grid> +// <Grid item xs={2}> +// <RadioGroup row name="radio3" onChange={props.handleRadios}> +// <FormControlLabel value="Sim" control={<BlueRadio/>} label="Sim"/> <FormControlLabel value="Não" control={<BlueRadio/>} label="Não"/> +// </RadioGroup> +// </Grid> +// </Grid> +// */} diff --git a/src/Components/RedirectModal.js b/src/Components/RedirectModal.js index bc786eca8e32d73651fcb3b7f279b0aa9b0a5180..f826b54ea543053125444fa4ab79d008d67c762f 100644 --- a/src/Components/RedirectModal.js +++ b/src/Components/RedirectModal.js @@ -16,7 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useEffect, useState} from 'react' +import React from 'react' import styled from 'styled-components' import { Button } from '@material-ui/core'; import Modal from '@material-ui/core/Modal'; diff --git a/src/Components/ReportButton.js b/src/Components/ReportButton.js index ea8bb313cc7adc7f1b60187ae780e55a0ae0befb..654780a75533a8deac35c1cf08121d8634915f3b 100644 --- a/src/Components/ReportButton.js +++ b/src/Components/ReportButton.js @@ -42,6 +42,7 @@ export default function ReportButton (props) { /*modal variables------------------------------------*/ const [reportModal, toggleReportModal] = useState(false) + // eslint-disable-next-line const [loginModal, toggleLoginModal] = useState(false) const handleModal = () => { diff --git a/src/Components/ReportColecaoForm.js b/src/Components/ReportColecaoForm.js index fcea00e793912b73c072b2b146a33d809be9402c..37c4a77336c79e8f58496143cbe8840725d7c4da 100644 --- a/src/Components/ReportColecaoForm.js +++ b/src/Components/ReportColecaoForm.js @@ -15,13 +15,12 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useContext} from 'react'; +import React from 'react'; import { Button } from '@material-ui/core'; import styled from 'styled-components' import Radio from '@material-ui/core/Radio'; import RadioGroup from '@material-ui/core/RadioGroup'; import FormControlLabel from '@material-ui/core/FormControlLabel'; -import FormControl from '@material-ui/core/FormControl'; import TextField from '@material-ui/core/TextField'; import {StyledFormControl, ButtonsDiv, ButtonCancelar} from './ReportUserForm.js' import { withStyles } from '@material-ui/core/styles'; @@ -71,7 +70,7 @@ export default function ReportColecaoForm (props) { const finalRadioValue = value const finalMoreInfo = moreInfo - if( finalRadioValue != -1 && !(finalMoreInfo.key)) { + if( finalRadioValue !== -1 && !(finalMoreInfo.key)) { props.handleSubmit(finalRadioValue, finalMoreInfo.value) } else { @@ -101,7 +100,6 @@ export default function ReportColecaoForm (props) { rowsMax = {"5"} error = {moreInfo.key} required = {false} - helperText ={moreInfo.value.length + '/150'} style={{width : "100%"}} /> diff --git a/src/Components/ReportCollectionForm.js b/src/Components/ReportCollectionForm.js new file mode 100644 index 0000000000000000000000000000000000000000..34fd87b2417016fa80fc43bce90300242a764901 --- /dev/null +++ b/src/Components/ReportCollectionForm.js @@ -0,0 +1,103 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ +import React from 'react'; +import { Button } from '@material-ui/core'; +import styled from 'styled-components' +import Radio from '@material-ui/core/Radio'; +import RadioGroup from '@material-ui/core/RadioGroup'; +import FormControlLabel from '@material-ui/core/FormControlLabel'; +import FormControl from '@material-ui/core/FormControl'; +import TextField from '@material-ui/core/TextField'; +import {StyledFormControl, StyledTextField, ButtonsDiv, ButtonCancelar, ButtonEnviar} from './ReportUserForm.js' + +export default function ReportRecursoForm (props) { + const [value, setValue] = React.useState(-1); + + const handleChange = (event) => { + setValue(event.target.value); + }; + + /*values are set according to backend complaint id*/ + const [options] = React.useState([ + {value : "1", text : 'A Coleção viola os direitos autorais.'}, + {value : "2", text : 'A Coleção contém conteúdo ofensivo/abusivo.'}, + {value : "5", text : 'A descrição da Coleção não corresponde ao seu conteúdo.'} + ]) + + const [moreInfo, setMoreInfo] = React.useState({ + key : false, + value : "", + }) + + const handleChangeMoreInfo = (e) => { + const userInput = e.target.value + + const flag = userInput.length > 150 ? true : false + + setMoreInfo({...moreInfo, + key : flag, + value : userInput + }) + } + + const handleSubmit = (e) => { + e.preventDefault() + const finalRadioValue = value + const finalMoreInfo = moreInfo + + if( finalRadioValue != -1 && !(finalMoreInfo.key)) { + props.handleSubmit(finalRadioValue, finalMoreInfo.value) + } + else { + console.log('oops') + } + } + + return ( + <form onSubmit={(e) => handleSubmit(e)} style={{textAlign : "left"}}> + <StyledFormControl component="fieldset"> + <RadioGroup value={value} onChange={handleChange}> + { + options.map(option => + <FormControlLabel value={option.value} control={<Radio color="orange"/>} label={option.text} /> + ) + } + </RadioGroup> + </StyledFormControl> + + <StyledTextField + id = {"report-text-field"} + label={"Escreva mais sobre o problema"} + value = {moreInfo.value} + onChange = {e => handleChangeMoreInfo(e)} + helperText = {moreInfo.value.length + '/150'} + multiline={true} + rowsMax = {"5"} + error = {moreInfo.key} + required = {false} + helperText ={moreInfo.value.length + '/150'} + style={{width : "100%"}} + /> + + <ButtonsDiv> + <ButtonCancelar onClick={props.handleClose}>CANCELAR</ButtonCancelar> + <ButtonEnviar type="submit">ENVIAR</ButtonEnviar> + </ButtonsDiv> + </form> + ) +} diff --git a/src/Components/ReportModal.js b/src/Components/ReportModal.js index ed472b3890cda0cbc7bd02e7aa6b1f44714e0131..079ca75fd3dd6454d6e26263767ac33d3ad3b556 100644 --- a/src/Components/ReportModal.js +++ b/src/Components/ReportModal.js @@ -16,20 +16,19 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useContext} from 'react'; +import React, {useContext, useState} from 'react'; import { Button } from '@material-ui/core'; import Modal from '@material-ui/core/Modal'; import Backdrop from '@material-ui/core/Backdrop'; import Fade from '@material-ui/core/Fade'; import styled from 'styled-components' -import SignUpContainer from './SignUpContainerFunction.js' import {Store} from '../Store.js' -import axios from 'axios' -import {apiUrl} from '../env'; import CloseIcon from '@material-ui/icons/Close'; import ReportUserForm from './ReportUserForm.js' import ReportRecursoForm from './ReportRecursoForm.js' import ReportColecaoForm from './ReportColecaoForm.js' +import {postRequest} from './HelperFunctions/getAxiosConfig' +import SnackbarComponent from './SnackbarComponent.js' function CloseModalButton (props) { return ( @@ -41,11 +40,10 @@ function CloseModalButton (props) { export default function ReportModal (props) { const {state} = useContext(Store) + const [snackbarOpen, handleSnackbar] = useState(false) const handleSubmit = (complaint_reason_id, description) => { - console.log('complaint_reason_id: ', complaint_reason_id) - console.log('description: ', description) - + const url = `/complaints/` const payload = { "complaint" : { "user_id" : state.currentUser.id, @@ -55,18 +53,13 @@ export default function ReportModal (props) { "complaint_reason_id" : complaint_reason_id } } - console.log(payload) - axios.post(`${apiUrl}/complaints`, - { - "complaint" : { - "user_id" : state.currentUser.id, - "description" : description, - "complainable_id" : props.complainableId, - "complainable_type" : props.complainableType, - "complaint_reason_id" : complaint_reason_id - } - }).then( (response) => {console.log(response)}, (error) => {console.log(error)}) + postRequest(url, payload, (data) => { + console.log(data) + props.handleClose(); + handleSnackbar(true); + }, (error) => {console.log(error)}) + } const renderForm = (formType) => { @@ -79,7 +72,6 @@ export default function ReportModal (props) { return ( <ReportRecursoForm handleClose={props.handleClose} handleSubmit={handleSubmit}/> ) - break; default: return ( <ReportUserForm handleClose={props.handleClose} handleSubmit={handleSubmit}/> @@ -88,35 +80,39 @@ export default function ReportModal (props) { } return ( - <StyledModal - aria-labelledby="transition-modal-title" - aria-describedby="transition-modal-description" - open={props.open} - - centered="true" - onClose={props.handleClose} - closeAfterTransition - BackdropComponent={Backdrop} - BackdropProps={{ - timeout: 500, - }} - > - <Fade in={props.open}> - <ReportContainer> - <Header> - <span style={{width:"32px"}}/> - <h2>O que está acontecendo?</h2> - <CloseModalButton handleClose={props.handleClose}/> - </Header> - - <Content> - { - renderForm(props.form) - } - </Content> - </ReportContainer> - </Fade> - </StyledModal> + <React.Fragment> + <SnackbarComponent snackbarOpen={snackbarOpen} severity={"success"} handleClose={() => {handleSnackbar(false)}} text={"Sua reclamação foi recebida."} + /> + <StyledModal + aria-labelledby="transition-modal-title" + aria-describedby="transition-modal-description" + open={props.open} + + centered="true" + onClose={props.handleClose} + closeAfterTransition + BackdropComponent={Backdrop} + BackdropProps={{ + timeout: 500, + }} + > + <Fade in={props.open}> + <ReportContainer> + <Header> + <span style={{width:"32px"}}/> + <h2>O que está acontecendo?</h2> + <CloseModalButton handleClose={props.handleClose}/> + </Header> + + <Content> + { + renderForm(props.form) + } + </Content> + </ReportContainer> + </Fade> + </StyledModal> + </React.Fragment> ) } diff --git a/src/Components/ReportRecursoForm.js b/src/Components/ReportRecursoForm.js index 66704bde8cda4ddad3c60c4aaf3ecd22e74760f8..a1c7312713319d9b4320cf4bc844d3c160c5ed79 100644 --- a/src/Components/ReportRecursoForm.js +++ b/src/Components/ReportRecursoForm.js @@ -15,14 +15,10 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useContext} from 'react'; -import { Button } from '@material-ui/core'; -import styled from 'styled-components' +import React from 'react'; import Radio from '@material-ui/core/Radio'; import RadioGroup from '@material-ui/core/RadioGroup'; import FormControlLabel from '@material-ui/core/FormControlLabel'; -import FormControl from '@material-ui/core/FormControl'; -import TextField from '@material-ui/core/TextField'; import {StyledFormControl, StyledTextField, ButtonsDiv, ButtonCancelar, ButtonEnviar} from './ReportUserForm.js' import { withStyles } from '@material-ui/core/styles'; @@ -71,7 +67,7 @@ export default function ReportRecursoForm (props) { const finalRadioValue = value const finalMoreInfo = moreInfo - if( finalRadioValue != -1 && !(finalMoreInfo.key)) { + if( finalRadioValue !== -1 && !(finalMoreInfo.key)) { props.handleSubmit(finalRadioValue, finalMoreInfo.value) } else { @@ -101,7 +97,6 @@ export default function ReportRecursoForm (props) { rowsMax = {"5"} error = {moreInfo.key} required = {false} - helperText ={moreInfo.value.length + '/150'} style={{width : "100%"}} /> diff --git a/src/Components/ReportUserForm.js b/src/Components/ReportUserForm.js index 2ed7bd88d9cf7b29803d97788159116764263390..370865722d5a85cb2b458f326b891dbfe962a3e8 100644 --- a/src/Components/ReportUserForm.js +++ b/src/Components/ReportUserForm.js @@ -15,7 +15,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useState, useContext} from 'react'; +import React, {useState} from 'react'; import { Button } from '@material-ui/core'; import styled from 'styled-components' import Radio from '@material-ui/core/Radio'; @@ -35,7 +35,7 @@ const StyledRadio = withStyles({ })((props) => <Radio color="default" {...props} />); export default function ReportForm (props) { - const [value, setValue] = React.useState(-1); + const [value, setValue] = useState(-1); const handleChange = (event) => { setValue(event.target.value); @@ -71,7 +71,7 @@ export default function ReportForm (props) { const finalRadioValue = value const finalMoreInfo = moreInfo - if( finalRadioValue != -1 && !(finalMoreInfo.key)) { + if( finalRadioValue !== -1 && !(finalMoreInfo.key)) { props.handleSubmit(finalRadioValue, finalMoreInfo.value) } } diff --git a/src/Components/RequirementsDialog.js b/src/Components/RequirementsDialog.js index a8f5f208cf28c0ac536b66e959013887eb543f7d..49aeb47335556faa0d6fa700973c0541a217819b 100644 --- a/src/Components/RequirementsDialog.js +++ b/src/Components/RequirementsDialog.js @@ -1,36 +1,12 @@ import React from 'react'; -import { makeStyles } from '@material-ui/core/styles'; import Button from '@material-ui/core/Button'; import Dialog from '@material-ui/core/Dialog'; import DialogActions from '@material-ui/core/DialogActions'; import DialogContent from '@material-ui/core/DialogContent'; import DialogContentText from '@material-ui/core/DialogContentText'; import DialogTitle from '@material-ui/core/DialogTitle'; -import FormControl from '@material-ui/core/FormControl'; -import FormControlLabel from '@material-ui/core/FormControlLabel'; -import InputLabel from '@material-ui/core/InputLabel'; -import MenuItem from '@material-ui/core/MenuItem'; -import Select from '@material-ui/core/Select'; -import Switch from '@material-ui/core/Switch'; - -const useStyles = makeStyles(theme => ({ - form: { - display: 'flex', - flexDirection: 'column', - margin: 'auto', - width: 'fit-content', - }, - formControl: { - marginTop: theme.spacing(2), - minWidth: 120, - }, - formControlLabel: { - marginTop: theme.spacing(1), - }, -})); export default function MaxWidthDialog(props) { - const classes = useStyles(); const [open, setOpen] = React.useState(false); const fullWidth = true; const maxWidth = 'sm'; diff --git a/src/Components/ResourceCard.css b/src/Components/ResourceCard.css new file mode 100644 index 0000000000000000000000000000000000000000..c7b97b5cb76d3373765410177a1cfd4749a31fef --- /dev/null +++ b/src/Components/ResourceCard.css @@ -0,0 +1,22 @@ +/* transform: translateX(-1284.61px); visibility: hidden; */ +/* .slideContentLinkAfterActivefalse{ + transform: translateX(-1285.55px); + position: relative; +}*/ +.slideContentLinkAfterActivetrue{ + position: absolute; + transform: none; + /* transition: transform 1000ms cubic-bezier(0,0,0.2,1) 0ms; */ + +} + +.slideContentLinkBeforeActivefalse{ + position: absolute; + transform: none; + transition: transform 500ms cubic-bezier(0,0,0.2,1) 0ms; + +} +.slideContentLinkBeforeActivetrue{ + transform: translateX(-1285.55px); + position: relative; +} \ No newline at end of file diff --git a/src/Components/ResourceCard.js b/src/Components/ResourceCard.js index ea072ee2f98061fc4a0a36a9daddcd980c86c176..2e76e5fc66116d288e3be56b7af41c85ef77878e 100644 --- a/src/Components/ResourceCard.js +++ b/src/Components/ResourceCard.js @@ -25,6 +25,7 @@ import CardActions from "@material-ui/core/CardActions"; import IconButton from "@material-ui/core/IconButton"; import Typography from "@material-ui/core/Typography"; import FavoriteIcon from "@material-ui/icons/Favorite"; +import styled from 'styled-components'; import animacao from "../img/laranja/ANIMACAO_SIMULACAO.jpg"; import apresentacao from "../img/laranja/APRESENTACAO.jpg"; import aplicativo from "../img/laranja/APP.jpg"; @@ -74,7 +75,7 @@ const slideStyle = { const publisherStyle = { color: "white", paddinLeft: "30px", - fontSize: "15px" + fontSize: "15px", }; class ResourceCard extends Component { @@ -86,23 +87,23 @@ class ResourceCard extends Component { userAvatar: null }; } - renderType(type){ - if (!this.state.thumbnail) { - if(!this.props.thumbnail) { - const aux = types.find(function(element){return element.label === type}); - this.setState({thumbnail: aux.thumb}); - } - else{ - this.setState({thumbnail: `${apiDomain}` + this.props.thumbnail}); - } + renderType(type) { + if (!this.state.thumbnail) { + if (!this.props.thumbnail) { + const aux = types.find(function (element) { return element.label === type }); + this.setState({ thumbnail: aux.thumb }); + } + else { + this.setState({ thumbnail: `${apiDomain}` + this.props.thumbnail }); } - {/*if (!this.state.thumbnail && !this.props.thumbnail ) { - var aux = types.find(function(element){ return element.label === type}); - this.setState({thumbnail: aux.thumb}); } - if (!this.state.thumbnail && this.props.thumbnail ) { - this.setState({thumbnail: apiDomain + this.props.thumbnail}); - }*/} + // {/*if (!this.state.thumbnail && !this.props.thumbnail ) { + // var aux = types.find(function(element){ return element.label === type}); + // this.setState({thumbnail: aux.thumb}); + // } + // if (!this.state.thumbnail && this.props.thumbnail ) { + // this.setState({thumbnail: apiDomain + this.props.thumbnail}); + // }*/} } onHover() { this.setState({ userStyle: "animatiOn" }); @@ -135,10 +136,10 @@ class ResourceCard extends Component { > <div className={this.state.userStyle}> <img style={slideStyle} src={this.state.userAvatar} alt="Avatar" /> - <Typography style={publisherStyle}> + <StyledPublisher style={publisherStyle}> Enviado por: <br /> {this.props.author} - </Typography> + </StyledPublisher> </div> <img src={this.state.thumbnail} @@ -163,6 +164,7 @@ class ResourceCard extends Component { name="customized-empty" value={this.props.rating * 10} precision={0.5} + readOnly emptyIcon={<StarBorderIcon fontSize="inherit" />} /> </Container> @@ -172,8 +174,8 @@ class ResourceCard extends Component { {this.props.type === "Vídeo" ? ( <Video style={{ color: "#ff7f00" }} /> ) : ( - <br /> - )} + <br /> + )} <IconButton aria-label="Favoritar" size="small"> <FavoriteIcon /> </IconButton> @@ -194,4 +196,11 @@ class ResourceCard extends Component { } } +const StyledPublisher = styled(Typography)` + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; +` + export default ResourceCard; diff --git a/src/Components/ResourceCardFunction.js b/src/Components/ResourceCardFunction.js index 8ff31bd892ff7c08aaacbc4ca208b1b0f12d0917..08d07b6190f283703263cbbabf3e676737425bc3 100644 --- a/src/Components/ResourceCardFunction.js +++ b/src/Components/ResourceCardFunction.js @@ -16,55 +16,54 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useState, useEffect} from 'react'; +import React, { useState, useEffect } from 'react'; import Card from '@material-ui/core/Card'; -import axios from 'axios' -import {apiDomain, apiUrl} from '../env'; +import {apiDomain} from '../env'; import ResourceCardOptions from './ResourceCardOptions' import noAvatar from "../img/default_profile.png"; -import { makeStyles } from '@material-ui/core/styles'; +// import { makeStyles } from '@material-ui/core/styles'; import Button from '@material-ui/core/Button'; import styled from 'styled-components' -import animacao from "../img/laranja/ANIMACAO_SIMULACAO.jpg"; -import apresentacao from "../img/laranja/APRESENTACAO.jpg"; -import aplicativo from "../img/laranja/APP.jpg"; -import audio from "../img/laranja/AUDIO.jpg"; -import vazio from "../img/laranja/EMPTY.jpg"; -import imagem from "../img/laranja/IMAGEM.jpg"; -import grafico from "../img/laranja/INFOGRAFICO.jpg"; -import jogo from "../img/laranja/JOGO.jpg"; -import livro from "../img/laranja/LIVRO_DIGITAL.jpg"; -import mapa from "../img/laranja/MAPA.jpg"; -import outros from "../img/laranja/OUTROS.jpg"; -import software from "../img/laranja/SOFTWARE.jpg"; -import texto from "../img/laranja/TEXTO.jpg"; -import video from "../img/laranja/VIDEO.jpg"; +// import animacao from "../img/laranja/ANIMACAO_SIMULACAO.jpg"; +// import apresentacao from "../img/laranja/APRESENTACAO.jpg"; +// import aplicativo from "../img/laranja/APP.jpg"; +// import audio from "../img/laranja/AUDIO.jpg"; +// import vazio from "../img/laranja/EMPTY.jpg"; +// import imagem from "../img/laranja/IMAGEM.jpg"; +// import grafico from "../img/laranja/INFOGRAFICO.jpg"; +// import jogo from "../img/laranja/JOGO.jpg"; +// import livro from "../img/laranja/LIVRO_DIGITAL.jpg"; +// import mapa from "../img/laranja/MAPA.jpg"; +// import outros from "../img/laranja/OUTROS.jpg"; +// import software from "../img/laranja/SOFTWARE.jpg"; +// import texto from "../img/laranja/TEXTO.jpg"; +// import video from "../img/laranja/VIDEO.jpg"; import Rating from '@material-ui/lab/Rating'; import StarBorderIcon from '@material-ui/icons/StarBorder'; -import AddIcon from '@material-ui/icons/CreateNewFolder'; -import Video from '@material-ui/icons/OndemandVideo'; -import MoreIcon from '@material-ui/icons/More'; +// import AddIcon from '@material-ui/icons/CreateNewFolder'; +// import Video from '@material-ui/icons/OndemandVideo'; +// import MoreIcon from '@material-ui/icons/More'; import FavoriteIcon from '@material-ui/icons/Favorite'; import ButtonGuardarColecao from './ButtonGuardarColecao.js' import Slide from '@material-ui/core/Slide'; import Grid from '@material-ui/core/Grid'; -import {Link} from 'react-router-dom'; -import {getDefaultThumbnail} from './HelperFunctions/getDefaultThumbnail' +import { Link } from 'react-router-dom'; +import { getDefaultThumbnail } from './HelperFunctions/getDefaultThumbnail' import GetIconByName from './UploadPageComponents/GetIconByName' -import {getAxiosConfig} from './HelperFunctions/getAxiosConfig' +import "./ResourceCard.css"; +import {putRequest} from './HelperFunctions/getAxiosConfig' -const types = [{label: "Animação", thumb: animacao}, {label: "Apresentação", thumb: apresentacao}, -{label: "Aplicativo" , thumb: aplicativo}, {label: "Áudio", thumb: audio}, {label: "Vazio", thumb: vazio}, {label: "Imagem", thumb: imagem}, {label: "Gráfico", thumb: grafico}, {label: "Jogo", thumb: jogo}, {label: "Livro", thumb: livro}, {label:"Livro digital", thumb: livro}, {label: "Mapa", thumb: mapa}, {label: "Outros", thumb: outros}, {label: "Software Educacional", thumb:software}, {label: "Software", thumb:software}, {label: "Texto", thumb:texto}, {label: "Vídeo", thumb:video}] - -export default function ResourceCardFunction (props) { +export default function ResourceCardFunction(props) { const [thumbnail, setThumbnail] = useState(null) + // eslint-disable-next-line const [label, setLabel] = useState(props.type) const [userAvatar, setUserAvatar] = useState(noAvatar) const [slideIn, setSlide] = useState(false) - const controlSlide = () => {setSlide(!slideIn)} + const controlSlide = () => { setSlide(!slideIn) } const [liked, toggleLiked] = useState(props.liked) + const [likesCount, setLikesCount] = useState(props.likeCount) - useEffect( () => { + useEffect(() => { //decide which thumbnail to use if (props.thumbnail) { setThumbnail(`${apiDomain}` + props.thumbnail) @@ -76,41 +75,47 @@ export default function ResourceCardFunction (props) { if (props.avatar) { setUserAvatar(`${apiDomain}` + props.avatar) } + else { + setUserAvatar(require('../img/logo_parceiros/ic_default.png')) + } }, []) + function handleSuccessLike (data) { + toggleLiked(!liked) + setLikesCount(data.count) + } + const handleLike = () => { - let payload = {} - let config = getAxiosConfig() + const url = `/learning_objects/${props.id}/like/` - axios.put( (`${apiUrl}/learning_objects/` + props.id + '/like'),payload, config - ).then( (response) => {toggleLiked(!liked)}, (error) => {console.log(error)}) + putRequest(url, {}, handleSuccessLike, (error) => {console.log(error)}) } const SlideAnimationContent = () => { return ( <SlideContentDiv> - <div style={{display:"flex", flex:"1"}}>{/*marginBottom:10px*/} - <AvatarDiv> - <img className="img" src={userAvatar} alt="user avatar"/> - </AvatarDiv> - <EnviadoPor> - Enviado por: - <br/> - <p>{props.author}</p> - </EnviadoPor> + <div style={{padding : 7}}> + <HeaderContainer container="row" justify="flex-start" alignItems="center" >{/*marginBottom:10px*/} + <AvatarDiv item xs={2}> + <img className="img" src={userAvatar} alt="user avatar" /> + </AvatarDiv> + <EnviadoPor item xs={10}> + Enviado por: + <br /> + <p>{props.author}</p> + </EnviadoPor> + </HeaderContainer> + <TagContainer container direction="row"> + { + props.tags.map((tag) => + <Grid item key={tag.id}> + <span >{tag.name}</span> + </Grid> + ) + } + </TagContainer> </div> - <TagContainer> - <Grid container spacing={1} justify='safe' style={{height : "inherit"}}> - { - props.tags.map( (tag) => - <Grid item key={tag.id}> - <span key={tag.id}>{tag.name}</span> - </Grid> - ) - } - </Grid> - </TagContainer> </SlideContentDiv> ) } @@ -121,48 +126,47 @@ export default function ResourceCardFunction (props) { <CardReaDiv> <Header onMouseEnter={controlSlide} onMouseLeave={controlSlide}> { - props.published && - <Slide direction="right" in={slideIn}> - <Link to={props.href} className="text"> - {SlideAnimationContent()} - </Link> - </Slide> + <Slide direction="left" in={slideIn} timeout={1000}> + <div className={`slideContentLinkAfterActive${slideIn}`}> + <Link to={props.href} className="text" > + {SlideAnimationContent()} + </Link> + </div> + </Slide > } - <Link to={props.href}> {/*add link to learningObject*/} - <img className="img-cover" src={thumbnail} alt="learning object thumbnail"/> - </Link> + <div className={`slideContentLinkBeforeActive${slideIn}`} style={{ height: '100%' }}> + <Link to={props.href}> + <img className="img-cover" src={thumbnail} alt="learning object thumbnail" style={{ width: "272.5px" }} /> + </Link> + </div> </Header> - <Description> - <Link to={props.href} className="text"> {/*add link to learningObject*/} - <span> + <Link to={props.href} className="text" style={{ height: '45px' }}> {/*add link to learningObject*/} + <Title> {props.title} - </span> + </Title> </Link> - { props.published && <Rating - name="customized-empty" - value={props.rating} - precision={0.5} - style={{color:"#666"}} - emptyIcon={<StarBorderIcon fontSize="inherit" />} + name="customized-empty" + value={props.rating} + readOnly + style={{ color: "#666" }} + emptyIcon={<StarBorderIcon fontSize="inherit" />} /> } - <Footer> <Type> {GetIconByName(label)} <span>{label}</span> </Type> - { props.published && <LikeCounter> - <span>{props.likeCount}</span> + <span>{likesCount}</span> <ButtonNoWidth onClick={handleLike}> - <FavoriteIcon style={{color : liked ? "red" : "#666" }}/> + <FavoriteIcon style={{ color: liked ? "red" : "#666" }} /> </ButtonNoWidth> </LikeCounter> } @@ -173,16 +177,16 @@ export default function ResourceCardFunction (props) { { props.published && <CardReaFooter> - <div style={{display : "flex", height : "100%"}}> + <div style={{ display: "flex", height: "100%" }}> <ButtonGuardarColecao thumb={props.thumbnail} title={props.title} recursoId={props.id} - /> + /> </div> <ResourceCardOptions learningObjectId={props.id} - downloadableLink = {props.downloadableLink} + downloadableLink={props.downloadableLink} thumb={props.thumbnail} title={props.title} - /> + /> </CardReaFooter> } </CardDiv> @@ -190,27 +194,34 @@ export default function ResourceCardFunction (props) { ) } /*---------- USED IN SLIDE DIV ONLY -----------*/ -export const TagContainer = styled.div` - display : flex; - flex-direction : row; - width : 100%; - overflow : hidden; - flex : 2; - height : 120px; +export const HeaderContainer = styled(Grid)` + +` +export const TagContainer = styled(Grid)` + margin-top: 0.5em; + height : 120px ; + overflow-y : hidden; + ${'' /* border : 2px solid red; */} span { + word-wrap: break-word; background-color : #fff; - height : 20px; + display : flex; + justify-content : center; + align-items : center; + height : 22px; + tet-align : center; + margin: 3px; + -webkit-box-direction: normal; overflow : hidden; - margin : 2px; - padding : 3px 8px; + padding : 1px 8px; border-radius : 10px; color : #666; font-size : 11px; } ` -export const EnviadoPor = styled.div` +export const EnviadoPor = styled(Grid)` display : inline-block; padding-left : 10px; overflow : hidden; @@ -218,19 +229,21 @@ export const EnviadoPor = styled.div` padding-right : 1em; p { - text-overflow : ellipsis; - overflow : hidden; - white-space : nowrap; margin : 0; + display: -webkit-box; + -webkit-line-clamp: 1; + -webkit-box-orient: vertical; + overflow: hidden; } ` -const AvatarDiv = styled.div` +export const AvatarDiv = styled(Grid)` vertical-align : middle; border : 0; - + width : 40px; + height : 40px; img { - height : 40px; - width : 40px; + max-height: 100%; + max-width: 100%; border : 0; vertical-align : middle; border-radius : 50%; @@ -239,12 +252,9 @@ const AvatarDiv = styled.div` const SlideContentDiv = styled.div` background-color : #ff9226; - padding : 10px; - width : 100%; - height : 100%; - position : absolute; - display : flex; - flex-direction : column; + ${'' /* padding : 10px; */} + width : 272.5px; + height : 189px; ` /*--------------------------------------------*/ @@ -319,6 +329,7 @@ export const Footer = styled.div` display : flex; flex-direction : row; justify-content : space-between; + margin-top : 5px; ` const Description = styled.div` @@ -333,16 +344,13 @@ const Description = styled.div` text-decoration : none !important; color : inherit; } - - .title { - text-overflow : ellipsis; - overflow : hidden; - margin-bottom : 10px; - font-size : 1.2em; - line-height : 1.1; - max-height : 46px; - color : #666; - } +` +const Title = styled.span` + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; + color : #666; ` export const Header = styled.div` @@ -350,13 +358,17 @@ export const Header = styled.div` flex : 2; position : relative; overflow : hidden; + + a { + text-decoration : none !important; + } ` export const CardReaDiv = styled.div` display : flex; flex-direction : column; height : 320px; - width : 272.5px; + ${'' /* width : 272.5px; */} margin : 0 auto; .img-cover { @@ -367,7 +379,7 @@ export const CardReaDiv = styled.div` display : block; background-position : center; background-size : cover; - width : 100%; + ${'' /* width : 100%; */} } ` @@ -383,7 +395,7 @@ export const StyledCard = styled(Card)` max-height : 380px; margin-top : 10px; margin-bottom : 10px; - max-width : 345px; + ${'' /* max-width : 345px; */} border-radius : 0; box-shadow : 0 0 5px 0 rgba(0,0,0,.25); ` diff --git a/src/Components/ResourceCardOptions.js b/src/Components/ResourceCardOptions.js index 53d401f0e2659ccd84189205998aaf0901ab7218..44bc52df18fd48f3deeeae344a8457ff06e6a8b6 100644 --- a/src/Components/ResourceCardOptions.js +++ b/src/Components/ResourceCardOptions.js @@ -16,8 +16,8 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useContext, useState} from 'react'; -import {Store} from '../Store.js' +import React, { useContext, useState } from 'react'; +import { Store } from '../Store.js' import styled from 'styled-components' import Button from '@material-ui/core/Button'; import Menu from '@material-ui/core/Menu'; @@ -26,20 +26,23 @@ import MenuItem from '@material-ui/core/MenuItem'; import MoreVertIcon from '@material-ui/icons/MoreVert'; import OpenIcon from '@material-ui/icons/OpenInNew'; import ReportIcon from '@material-ui/icons/Error'; -import axios from 'axios' -import {apiUrl} from '../env'; -import {getAxiosConfig} from './HelperFunctions/getAxiosConfig' import ReportModal from './ReportModal.js' -import {Link} from 'react-router-dom' +import { Link } from 'react-router-dom' import DownloadIcon from '@material-ui/icons/CloudDownload'; import ShareIcon from '@material-ui/icons/Share'; import AddIcon from '@material-ui/icons/CreateNewFolder'; import GuardarModal from './GuardarModal' import ShareModal from './ShareModal' import SnackbarComponent from './SnackbarComponent' - -export default function ResourceCardOptions (props) { - const {state} = useContext(Store) +import OpenInBrowserIcon from '@material-ui/icons/OpenInBrowser'; +import Tooltip from '@material-ui/core/Tooltip'; +import SignUpModal from './SignUpModal' +import LoginModal from './LoginModal.js' +import Snackbar from '@material-ui/core/Snackbar'; +import MuiAlert from '@material-ui/lab/Alert'; + +export default function ResourceCardOptions(props) { + const { state } = useContext(Store) const [anchorEl, setAnchorEl] = React.useState(null); function handleClick(event) { @@ -53,18 +56,18 @@ export default function ResourceCardOptions (props) { const [reportModal, toggleReportModal] = useState(false) const handleModalReportar = (value) => { toggleReportModal(value) - {/*if (state.currentUser.id) { - toggleReportModal(!reportModal) - } - else { - toggleLoginModal(true) - }*/} + // {/*if (state.currentUser.id) { + // toggleReportModal(!reportModal) + // } + // else { + // toggleLoginModal(true) + // }*/} } const [saveToCol, toggleSave] = useState(false) const handleGuardar = () => { - if(state.currentUser.id === '') { - console.log('abrir login modal'); + if (!state.currentUser.id) { + handleLogin(); } else { toggleSave(true); @@ -81,8 +84,8 @@ export default function ResourceCardOptions (props) { const [shareOpen, toggleShare] = useState(false) const handleShare = () => { - if(state.currentUser.id === '') { - console.log('abrir login modal'); + if (!state.currentUser.id) { + handleLogin() } else { toggleShare(true); @@ -90,65 +93,109 @@ export default function ResourceCardOptions (props) { handleClose() } const getShareablePageLink = () => { - return (window.location.href + "/recurso/" + props.learningObjectId) + return (window.origin + "/recurso/" + props.learningObjectId) + } + + const handleSignUp = () => { + setSignUp(!signUpOpen) + } + + const handleLogin = () => { + setLogin(!loginOpen) + } + + function Alert(props) { + return <MuiAlert elevation={6} variant="filled" {...props} />; + } + + function toggleLoginSnackbar(reason) { + if (reason === 'clickaway') { + return; + } + handleSuccessfulLogin(false); } const [snackbarOpen, toggleSnackbar] = useState(false) + const [signUpOpen, setSignUp] = useState(false) + const [loginOpen, setLogin] = useState(false) + const [successfulLoginOpen, handleSuccessfulLogin] = useState(false) return ( - <React.Fragment> - <ReportModal open={reportModal} handleClose={() => handleModalReportar(false)} - form="recurso" complainableId={props.learningObjectId} - complainableType={"LearningObject"} - {...props} - /> - <GuardarModal open={saveToCol} handleClose={() => {toggleSave(false)}} - thumb={props.thumb} title={props.title} recursoId={props.learningObjectId} - /> - <ShareModal open={shareOpen} handleClose={() => {toggleShare(false)}} - thumb={props.thumb} title={props.title} link={getShareablePageLink()} - /> - <SnackbarComponent snackbarOpen={snackbarOpen} severity={"info"} handleClose={() => {toggleSnackbar(false)}} text={"Baixando o Recurso... Lembre-se de relatar sua experiência após o uso do Recurso!"} - /> - <div style={{fontSize: "12px", display : "flex", flexDirection : "column", justifyContent : "center"}}> - <ButtonNoWidth aria-controls="simple-menu" aria-haspopup="true" onClick={handleClick} style={{color : "#666"}}> - <MoreVertIcon style={{color : "#666"}}/> - </ButtonNoWidth> - <Menu - id="simple-menu" - anchorEl={anchorEl} - keepMounted - open={Boolean(anchorEl)} - onClose={handleClose} - > - <StyledMenuItem onClick={handleClose}> - <Link to={"/recurso/" + props.learningObjectId}> - <ListItemIcon><OpenIcon /></ListItemIcon>Abrir - </Link> - </StyledMenuItem> - - { - props.downloadableLink && - <StyledMenuItem onClick={() => {enableDownload(); handleClose()}}> - <ListItemIcon><DownloadIcon /></ListItemIcon>Baixar - </StyledMenuItem> - } - - <StyledMenuItem onClick={handleShare}> - <ListItemIcon><ShareIcon /></ListItemIcon>Compartilhar - </StyledMenuItem> - - <StyledMenuItem onClick={handleGuardar}> - <ListItemIcon><AddIcon /></ListItemIcon>Guardar - </StyledMenuItem> - - <StyledMenuItem onClick={() => {handleModalReportar(true); handleClose()}}> - <ListItemIcon><ReportIcon /></ListItemIcon>Reportar - </StyledMenuItem> - </Menu> - </div> - </React.Fragment> - ); + <> + + <React.Fragment> + <ReportModal open={reportModal} handleClose={() => handleModalReportar(false)} + form="recurso" complainableId={props.learningObjectId} + complainableType={"LearningObject"} + {...props} + /> + <GuardarModal open={saveToCol} handleClose={() => { toggleSave(false) }} + thumb={props.thumb} title={props.title} recursoId={props.learningObjectId} + /> + <ShareModal open={shareOpen} handleClose={() => { toggleShare(false) }} + thumb={props.thumb} title={props.title} link={getShareablePageLink()} + /> + <SnackbarComponent snackbarOpen={snackbarOpen} severity={"info"} handleClose={() => { toggleSnackbar(false) }} text={"Baixando o Recurso... Lembre-se de relatar sua experiência após o uso do Recurso!"} + /> + <SignUpModal open={signUpOpen} handleClose={handleSignUp} openLogin={handleLogin} + /> + <LoginModal open={loginOpen} handleClose={() => setLogin(false)} openSignUp={handleSignUp} + openSnackbar={() => { handleSuccessfulLogin(true) }} + /> + <Snackbar open={successfulLoginOpen} autoHideDuration={1000} onClose={toggleLoginSnackbar} + anchorOrigin={{ vertical: 'top', horizontal: 'center' }} + > + <Alert severity="success" style={{ backgroundColor: "#00acc1" }}>Você está conectado(a)!</Alert> + </Snackbar> + <div style={{ fontSize: "12px", display: "flex", flexDirection: "column", justifyContent: "center" }}> + <ButtonNoWidth aria-controls="simple-menu" aria-haspopup="true" onClick={handleClick} style={{ color: "#666" }}> + <MoreVertIcon style={{ color: "#666" }} /> + </ButtonNoWidth> + <Menu + id="simple-menu" + anchorEl={anchorEl} + keepMounted + open={Boolean(anchorEl)} + onClose={handleClose} + > + <Tooltip title="Não preserva filtro" arrow> + <StyledMenuItem onClick={handleClose}> + <Link to={"/recurso/" + props.learningObjectId}> + <ListItemIcon><OpenIcon /></ListItemIcon>Abrir + </Link> + </StyledMenuItem> + </Tooltip> + + <Tooltip title="Preserva filtro" arrow> + <StyledMenuItem onClick={() => window.open("/recurso/" + props.learningObjectId, "_blank")}> + <ListItemIcon><OpenInBrowserIcon /></ListItemIcon> Abrir em nova guia + </StyledMenuItem> + </Tooltip> + + { + props.downloadableLink && + <StyledMenuItem onClick={() => { enableDownload(); handleClose() }}> + <ListItemIcon><DownloadIcon /></ListItemIcon>Baixar + </StyledMenuItem> + } + + <StyledMenuItem onClick={handleShare}> + <ListItemIcon><ShareIcon /></ListItemIcon>Compartilhar + </StyledMenuItem> + + <StyledMenuItem onClick={handleGuardar}> + <ListItemIcon><AddIcon /></ListItemIcon>Guardar + </StyledMenuItem> + + <StyledMenuItem onClick={() => { handleModalReportar(true); handleClose() }}> + <ListItemIcon><ReportIcon /></ListItemIcon>Reportar + </StyledMenuItem> + + </Menu> + </div> + </React.Fragment> + </> + ); } const ButtonNoWidth = styled(Button)` diff --git a/src/Components/ResourceList.js b/src/Components/ResourceList.js new file mode 100644 index 0000000000000000000000000000000000000000..79d0936ac7ea15277dc989882dc63ae29364495d --- /dev/null +++ b/src/Components/ResourceList.js @@ -0,0 +1,189 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + +import React, { useState, useEffect } from 'react'; +import { Grid } from '@material-ui/core'; +import styled from 'styled-components'; +import axios from 'axios'; +import Button from '@material-ui/core/Button'; +import CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank'; +import CheckBoxIcon from '@material-ui/icons/CheckBox'; +import GetAppIcon from '@material-ui/icons/GetApp'; +import ResourceCardFunction from './ResourceCardFunction.js'; +import FloatingDownloadButton from './FloatingDownloadButton.js'; +import Snackbar from '@material-ui/core/Snackbar'; +import MuiAlert from '@material-ui/lab/Alert'; +import { apiUrl } from '../env.js'; + +function Alert(props) { + return <MuiAlert elevation={6} variant="filled" {...props} />; +} + + +export default function ResourceList(props) { + + const [selected, setSelected] = useState(Array.apply( + null, { length: props.resources.length }).map(i => false)); + const [selectable, setSelectable] = useState(false); + const [download_url, setDownloadUrl] = useState(''); + const [snackbar_open, setSnackbarOpen] = useState(false); + + const updateSelected = (index) => { + let new_selected = selected.slice(); + new_selected[index] = !new_selected[index]; + setSelected(new_selected); + } + + const checkBoxIcon = (s) => { + if (s) + return <CheckBoxIcon />; + else + return <CheckBoxOutlineBlankIcon />; + } + + const handleDownloadSelection = () => { + // const selected_resources = props.resources.filter(resource => selected[props.resources.indexOf(resource)]); + setSnackbarOpen(true); + } + + useEffect(() => { + if (selectable) { + var resources = [] + let i = 0; + while (i < props.resources.length) { + if (selected[i]) + resources.push({ "type": "LearningObject", "id": props.resources[i].id }); + i++; + } + const body = { + "package": { + "object": resources + } + }; + if (resources.length) + axios + .post(apiUrl + '/package', body) + .catch(err => { + if (err.response && err.response.status === 302) { + setDownloadUrl(apiUrl.slice().replace('/v1', '') + '/' + err.response.data.url); + } + }); + } + }, [selected, selectable]); + console.log("CARD >>", props.resources) + return ( + <ResourceListContainer> + <Grid container direction="row" justify="space-around" alignItems="center"> + <Grid item> + <Title> + {props.resources.length ? + props.resources.length + " recurso" + (props.resources.length === 1 ? "" : "s") + : "Carregando coleção"} + </Title> + </Grid> + <Grid item> + <Button color="primary" onClick={() => setSelectable(!selectable)}> + <PanelButtonText> + {selectable ? "Desativar" : "Ativar"} seleção + </PanelButtonText> + </Button> + </Grid> + <Grid item> + <UnstyledAnchor href={download_url}> + <Button + color="primary" + variant="outlined" + startIcon={<GetAppIcon fontSize="large" />} + onClick={handleDownloadSelection} + > + <PanelButtonText>baixar seleção</PanelButtonText> + </Button> + </UnstyledAnchor> + </Grid> + </Grid> + <Grid container direction="row" justify="flex-start" alignItems="center"> + {props.resources.map((card) => { + return ( + <ResourceGrid item key={card.title}> + <ResourceCardFunction + avatar={card.avatar} + id={card.id} + thumbnail={card.thumbnail} + type={card.type ? card.type : "Outros"} + title={card.title} + published={card.state === "published" ? true : false} + likeCount={card.likeCount} + liked={card.liked} + rating={card.rating} + author={card.publisher} + tags={card.tags} + href={"/recurso/" + card.id} + downloadableLink={card.downloadableLink} + /> + {selectable ? + (<SelectButton + variant="outline" + color="primary" + startIcon={checkBoxIcon(selected[props.resources.indexOf(card)])} + onClick={() => updateSelected(props.resources.indexOf(card))} + > + Selecionar + </SelectButton>) + : + <span></span>} + + </ResourceGrid> + ); + })} + </Grid> + <Snackbar + open={snackbar_open} + autoHideDuration={6000} + onClose={() => setSnackbarOpen(false)} + anchorOrigin={{ vertical: 'top', horizontal: 'right' }} + > + <Alert onClose={() => setSnackbarOpen(false)} severity="info"> + Os recursos serão baixados + </Alert> + </Snackbar> + <FloatingDownloadButton url={download_url} empty={selected.indexOf(true) === -1} /> + </ResourceListContainer> + ); +} + +const ResourceListContainer = styled.div` + margin-left: 20; + margin-right: 20; +` +const Title = styled.p` + color: rgb(102, 102, 102); + font-size: 2em; + font-weigth: 300; +` +const SelectButton = styled(Button)` + width: 100%; +` +const PanelButtonText = styled.span` + font-weight: 900; +` +const ResourceGrid = styled(Grid)` + padding-right: 7px; +` +const UnstyledAnchor = styled.a` + text-decoration: none !important; +` diff --git a/src/Components/ResourcePageComponents/CommentForm.js b/src/Components/ResourcePageComponents/CommentForm.js index efbf0a0349ad1184ac616bd738faffa5abfba7a0..0b1c38ba693b98b03c689f18035a6f81478d9cd9 100644 --- a/src/Components/ResourcePageComponents/CommentForm.js +++ b/src/Components/ResourcePageComponents/CommentForm.js @@ -1,14 +1,12 @@ import React, {useState} from 'react' import styled from 'styled-components' import Rating from '@material-ui/lab/Rating'; -import StarBorderIcon from '@material-ui/icons/StarBorder'; import StarIcon from '@material-ui/icons/Star'; import TextField from "@material-ui/core/TextField"; import { Button } from '@material-ui/core'; -import axios from 'axios' -import {apiUrl} from '../../env'; import EditIcon from '@material-ui/icons/Edit'; import Grid from '@material-ui/core/Grid'; +import {postRequest} from '../HelperFunctions/getAxiosConfig' export default function CommentForm (props) { const [rating, setRating] = useState({ @@ -28,22 +26,19 @@ export default function CommentForm (props) { const [attemptedSubmit, setAttempt] = useState(false) + function handleSuccess (data) { + props.handleSnackbar(1) + props.rerenderCallback() + } const handleSubmit = (e) => { e.preventDefault() const finalRating = rating const finalComment = comment - if (!(finalRating.error || finalComment.error)) { - let config = { - headers : { - 'Accept': 'application/json', - 'Content-Type': 'application/json', - 'Access-Token': sessionStorage.getItem('@portalmec/accessToken'), - 'Client': sessionStorage.getItem('@portalmec/clientToken'), - 'Uid': sessionStorage.getItem('@portalmec/uid'), - } - } + let type = props.recurso ? 'learning_objects' : 'collections' + const url = `/${type}/${props.recursoId}/reviews` + let payload = { "review" : { "description" : finalComment.value, @@ -55,25 +50,14 @@ export default function CommentForm (props) { ] } } - let type = props.recurso ? 'learning_objects/' : 'collections/' - console.log(payload) - axios.post( (`${apiUrl}/` + type + props.recursoId + '/reviews'), payload, config - ).then((response) => { - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - console.log(response.data); - props.handleSnackbar(1); - props.rerenderCallback()}, - (error) => {console.log(error)}) + + postRequest(url, payload, handleSuccess, (error) => {console.log(error)}) } else { setAttempt(true) } } - let windowWidth = window.innerWidth - return ( <StyledForm onSubmit={handleSubmit}> <label htmlFor="avaliacao-estrelas" className="start-label"> @@ -93,77 +77,35 @@ export default function CommentForm (props) { <div className="star-alert" style={attemptedSubmit ? {visibility : "visible"} : {visibility : "hidden" }}>{props.recurso ? "Avalie se o recurso foi útil." : "Avalie se esta coleção foi útil."}</div> <Grid container> - { - windowWidth > 990 ? - ( - <> - <Grid item xs={10}> - <StyledTextField - colecao={!props.recurso} - value={comment.value} - multiline - rows="5" - error={comment.error} - label={props.recurso ? "Escreva aqui a sua experiência com este Recurso" : "Escreva aqui a sua experiência com esta Coleção"} - onChange={e => handleChange(e)} - required={true} - help = {comment.error ? (props.recurso ? "Escreva aqui a sua experiência com este Recurso" : "Escreva aqui a sua experiência com esta Coleção") : ''} - /> - </Grid> - <Grid item xs={2}> - <div style={{height : "100%", display : "flex", flexDirection : "column", justifyContent : "flex-end"}}> - { - props.recurso ? - ( - <OrangeButton type="submit">Publicar</OrangeButton> - ) - : - ( - <PurpleButton type="submit"><EditIcon/>Enviar</PurpleButton> - ) - } - </div> - </Grid> + <Grid item xs={12} md={9}> + <StyledTextField + colecao={!props.recurso} + value={comment.value} + multiline + rows="5" + error={comment.error} + label={props.recurso ? "Escreva aqui a sua experiência com este Recurso" : "Escreva aqui a sua experiência com esta Coleção"} + onChange={e => handleChange(e)} + required={true} + help = {comment.error ? (props.recurso ? "Escreva aqui a sua experiência com este Recurso" : "Escreva aqui a sua experiência com esta Coleção") : ''} + /> + </Grid> + <Grid item xs={12} md={3}> + <div style={{height : "100%", display : "flex", flexDirection : "column", justifyContent : "flex-end"}}> + { + props.recurso ? + ( + <OrangeButton type="submit">Publicar</OrangeButton> + ) + : + ( + <PurpleButton type="submit"><EditIcon/>Enviar</PurpleButton> + ) + } + </div> + </Grid> - <div className="campos-obrigatorios">* Campos obrigatórios.</div> - </> - ) - : - ( - <> - <Grid item xs={12}> - <StyledTextField - colecao={!props.recurso} - value={comment.value} - multiline - rows="5" - error={comment.error} - label={props.recurso ? "Escreva aqui a sua experiência com este Recurso" : "Escreva aqui a sua experiência com esta Coleção"} - onChange={e => handleChange(e)} - required={true} - help = {comment.error ? (props.recurso ? "Escreva aqui a sua experiência com este Recurso" : "Escreva aqui a sua experiência com esta Coleção") : ''} - /> - </Grid> - <Grid item xs={12}> - <div style={{paddingTop : "18px", display : "flex", justifyContent : "space-between"}}> - <div className="campos-obrigatorios">* Campos obrigatórios.</div> - <div style={{width : "40%"}}> - { - props.recurso ? - ( - <OrangeButton type="submit">Publicar</OrangeButton> - ) - : - ( - <PurpleButton type="submit"><EditIcon/>Enviar</PurpleButton> - ) - } - </div> - </div> - </Grid> - </> - ) - } + <div className="campos-obrigatorios">* Campos obrigatórios.</div> </Grid > </StyledForm> ) @@ -221,9 +163,6 @@ const StyledForm = styled.form` display : flex; flex-direction : column; text-align : start; - @media screen and (max-width : 990px) { - padding-left : 15px; - } .start-label { font-size : 14px; diff --git a/src/Components/ResourcePageComponents/CommentsArea.js b/src/Components/ResourcePageComponents/CommentsArea.js index 924a690434497aa0f7e133ff4ddec765310d5566..10a9482f73b5e49ac3e7089453cee29378fca290 100644 --- a/src/Components/ResourcePageComponents/CommentsArea.js +++ b/src/Components/ResourcePageComponents/CommentsArea.js @@ -23,10 +23,10 @@ import Grid from '@material-ui/core/Grid'; import { Button } from '@material-ui/core'; import ExitToAppIcon from '@material-ui/icons/ExitToApp'; import Comentarios from '../../img/comentarios.png' -import {apiUrl, apiDomain} from '../../env'; +import {apiDomain} from '../../env'; import CommentForm from './CommentForm.js' -import axios from 'axios' import Comment from '../Comment.js' +import {getRequest} from '../HelperFunctions/getAxiosConfig' export default function CommentsArea (props) { const {state} = useContext(Store) @@ -34,15 +34,14 @@ export default function CommentsArea (props) { const [gambiarra, setState] = useState(0) const forceUpdate = () => {setState(gambiarra + 1)} + function handleSuccess (data) { + setComentarios(data.sort((a, b) => a.updated_at > b.updated_at ? -1 : 1)) + } + useEffect( () => { - axios.get( (`${apiUrl}/learning_objects/` + props.recursoId + '/reviews') - ).then( (response) => { - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - console.log(response) - setComentarios(response.data.sort((a, b) => a.updated_at > b.updated_at ? -1 : 1)) - }, (error) => {console.log(error)}) + const url = `/learning_objects/${props.recursoId}/reviews` + + getRequest(url, handleSuccess, (error) => {console.log(error)}) }, [gambiarra]) return ( @@ -55,7 +54,7 @@ export default function CommentsArea (props) { <h3>Conte sua experiência com o Recurso</h3> <Grid container style={{paddingTop : "20px"}}> <Grid item xs={2} style={{paddingLeft : "15px", paddingRight : "15px"}}> - <img src={apiDomain + state.currentUser.userAvatar} className="minha-imagem" alt="user avatar"/> + <img src={apiDomain + state.currentUser.avatar} className="minha-imagem" alt="user avatar"/> </Grid> <Grid item xs={10}> <CommentForm @@ -86,7 +85,7 @@ export default function CommentsArea (props) { comentarios.length !== 0 ? ( <ComentariosBox> - <h3>{comentarios.length} {comentarios.length != 1 ? 'Relatos' : 'Relato'} sobre o uso do Recurso</h3> + <h3>{comentarios.length} {comentarios.length !== 1 ? 'Relatos' : 'Relato'} sobre o uso do Recurso</h3> { comentarios.map( comentario => <div className="comentario-template" key={comentario.id}> @@ -114,7 +113,7 @@ export default function CommentsArea (props) { ( <Grid item xs={12}> <LogInToComment> - <img src={Comentarios} /> + <img alt="" src={Comentarios} /> <span className="span-laranja">Compartilhe sua experiência com a Rede!</span> <AoRelatar> Ao relatar sua experiência de uso do Recurso você estará auxiliando professores de todo país. @@ -183,12 +182,18 @@ const GrayContainer = styled.div` display : flex; flex-direction : column; justify-content : space-between; +<<<<<<< HEAD font-size : 14px; padding-bottom : 20px; @media screen and (min-width : 990px) { padding-right : 15px; padding-left : 15px; } +======= + padding-right : 15px; + padding-left : 15px; + padding-bottom : 20px; +>>>>>>> fead909286087ce07b01b25f6d8f46f74dc494c8 h3 { font-family : 'Roboto Light','Roboto Regular',Roboto; diff --git a/src/Components/ResourcePageComponents/Footer.js b/src/Components/ResourcePageComponents/Footer.js index ea2253c4718394b629ae4603ce7d1645d3142d43..a0fcbcdab1c5ded02d56b0d1e94f2aa8018d4087 100644 --- a/src/Components/ResourcePageComponents/Footer.js +++ b/src/Components/ResourcePageComponents/Footer.js @@ -26,9 +26,7 @@ import ShareIcon from '@material-ui/icons/Share'; import FolderIcon from '@material-ui/icons/Folder'; import GetAppIcon from '@material-ui/icons/GetApp'; import CallMadeIcon from '@material-ui/icons/CallMade'; -import {Link} from 'react-router-dom' import ReportModal from '../ReportModal.js' -import ReportRecursoForm from '../ReportRecursoForm.js' import ShareModal from '../ShareModal.js' import GuardarModal from '../GuardarModal.js' import RedirectModal from '../RedirectModal' diff --git a/src/Components/ResourcePageComponents/Sobre.js b/src/Components/ResourcePageComponents/Sobre.js index 1b4bfa627f4d5d8d4b8b2c612c607845c706b4c7..7cf58bf7c28f6f1a67ad359dbcd39c6b3e41347c 100644 --- a/src/Components/ResourcePageComponents/Sobre.js +++ b/src/Components/ResourcePageComponents/Sobre.js @@ -22,7 +22,6 @@ import styled from 'styled-components' import Grid from '@material-ui/core/Grid'; import {Link} from 'react-router-dom' import {NoIcon} from '../ContactButtons/FollowButton.js' -import MoreVertIcon from '@material-ui/icons/MoreVert'; import Collapse from '@material-ui/core/Collapse'; import SdCardIcon from '@material-ui/icons/SdCard'; import TranslateIcon from '@material-ui/icons/Translate'; @@ -198,7 +197,7 @@ export default function Sobre (props) { <div style={{paddingTop : "0.75em", display : "flex", justifyContent : "center"}}> { - (props.id != state.currentUser.id) && + (props.id !== state.currentUser.id) && <> <NoIcon followableID={props.id}/> <ContactCardOptions followableID={props.id}/> @@ -271,7 +270,6 @@ const SobreDiv = styled.div` .tags-container { padding : 0; width : 100%; - display : flex; flex-direction : row; align-items : center; font-size : .8em; diff --git a/src/Components/ResourcePageComponents/TextoObjeto.js b/src/Components/ResourcePageComponents/TextoObjeto.js index 5c7c400f5a279838b28a7c11b4a3aa34b72caa1e..1554cc9ebd70387fd72cb155f749232133f1b5c0 100644 --- a/src/Components/ResourcePageComponents/TextoObjeto.js +++ b/src/Components/ResourcePageComponents/TextoObjeto.js @@ -29,9 +29,7 @@ import Button from '@material-ui/core/Button'; import {Link, Redirect} from 'react-router-dom' import Alert from '../Alert.js'; import Snackbar from '@material-ui/core/Snackbar'; -import {getAxiosConfig} from '../HelperFunctions/getAxiosConfig' -import axios from 'axios' -import {apiUrl, apiDomain} from '../../env'; +import {deleteRequest} from '../HelperFunctions/getAxiosConfig' export default function TextoObjeto (props) { const {state} = useContext(Store) @@ -52,6 +50,7 @@ export default function TextoObjeto (props) { else { outrasTem.push(subject.name) } + return undefined }) setOutrasTem(outrasTem.join(' - ')) setCompCurr(compCurr.join(' - ')) @@ -80,25 +79,17 @@ export default function TextoObjeto (props) { const [snackbarOpen, toggleSnackbar] = useState(false) const [publisherDeletedObject, toggleDeleted] = useState(false) + function handleSuccess (data) { + toggleSnackbar(true) + toggleDeleted(true) + } const handleDelete = () => { - let config = getAxiosConfig() - axios.delete((`${apiUrl}/learning_objects/` + props.recursoId), config).then( - (response) => { - toggleSnackbar(true) - console.log(response.data) - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - toggleDeleted(true) - }, - (error) => { - console.log(error) - } - ) + const url = `/learning_objects/${props.recursoId}` + deleteRequest(url, handleSuccess, (error) => {console.log(error)}) } const checkAccessLevel = (levelToCheck) => { - if (state.currentUser.id != '') { + if (state.currentUser.id !== '') { return(checkUserRole(levelToCheck)) } else { diff --git a/src/Components/ResourcePageComponents/VideoPlayer.js b/src/Components/ResourcePageComponents/VideoPlayer.js index 35e3846f6ea03a5015cf94121b69e4c3f2546180..940917df9190d882df8c4d5f77798cbe04b4bb93 100644 --- a/src/Components/ResourcePageComponents/VideoPlayer.js +++ b/src/Components/ResourcePageComponents/VideoPlayer.js @@ -20,23 +20,25 @@ import React from 'react' import styled from 'styled-components' function GetEmbeddedLink (link) { - if (link.indexOf("youtube") != -1) { //plain youtebe.com/ link - if(link.indexOf("embed/") != -1) { //if it's already an embedded link, return it + var embed = undefined + var link_id = undefined + if (link.indexOf("youtube") !== -1) { //plain youtebe.com/ link + if(link.indexOf("embed/") !== -1) { //if it's already an embedded link, return it return link } link = link.split("&")[0] //else remove features and other queries - var link = link.split("v=")[1] //get video id - var embed = "https://www.youtube.com/embed/" + link; //create embedded link + link_id = link.split("v=")[1] //get video id + embed = "https://www.youtube.com/embed/" + link_id; //create embedded link } - else if (link.indexOf("youtu.be") != -1) { //if it's a youtu.be link + else if (link.indexOf("youtu.be") !== -1) { //if it's a youtu.be link link = link.split("&")[0].split("?")[0] //remove queries and features if existent - link = link.split(".be/")[1] //get video id - var embed = "https://www.youtube.com/embed/" + link; //create embedded link + link_id = link.split(".be/")[1] //get video id + embed = "https://www.youtube.com/embed/" + link_id; //create embedded link } - else if (link.indexOf("vimeo") != -1) { //if the 13th character = o (vimeo videos) - link = link.split("?")[0].split("/") - console.log(link) //key # = from 19th character on - var embed = "https://player.vimeo.com/video/" + link.pop(); //Add vimeo link before key # + else if (link.indexOf("vimeo") !== -1) { //if the 13th character = o (vimeo videos) + link_id = link.split("?")[0].split("/") + console.log(link_id) //key # = from 19th character on + embed = "https://player.vimeo.com/video/" + link_id.pop(); //Add vimeo link before key # } return embed } @@ -51,6 +53,7 @@ export default function VideoPlayer (props) { ( <VideoContainer> <iframe + title="Video Player" src={GetEmbeddedLink(props.link)} frameBorder="0" allowFullScreen className="video" /> diff --git a/src/Components/SearchExpansionPanel/ExpansionPanel.css b/src/Components/SearchExpansionPanel/ExpansionPanel.css new file mode 100644 index 0000000000000000000000000000000000000000..f97d0f5758cf640c3153e4667c95627fea39a888 --- /dev/null +++ b/src/Components/SearchExpansionPanel/ExpansionPanel.css @@ -0,0 +1,14 @@ +.MuiAccordionActions-root{ + display: block !important; +} +.MuiListItemIcon-root{ + min-width: 30px !important; +} + +.MuiListItem-secondaryAction { + padding-right: 0px !important; +} + +.MuiListItem-gutters { + padding-left: 10px !important; +} \ No newline at end of file diff --git a/src/Components/SearchExpansionPanel/SearchEPCompCurriculum.js b/src/Components/SearchExpansionPanel/SearchEPCompCurriculum.js index d55d6e63579e5b74ff3e57e09469478edcc654b8..180eaeef90d4ec92d3c6fa367cb0eb22489d3ef9 100644 --- a/src/Components/SearchExpansionPanel/SearchEPCompCurriculum.js +++ b/src/Components/SearchExpansionPanel/SearchEPCompCurriculum.js @@ -17,7 +17,7 @@ const useStyles = makeStyles(theme => ({ } })); -export default function SearchEPCompCurriculum() { +export default function SearchEPCompCurriculum(props) { const classes = useStyles(); const [checked, setChecked] = React.useState([0]); @@ -31,7 +31,16 @@ export default function SearchEPCompCurriculum() { newChecked.splice(currentIndex, 1); } + let filterString = ""; + setChecked(newChecked); + for(let i = 0; i < newChecked.length; i++){ + if(newChecked[i] !== 0){ + filterString = filterString + `&subjects[]=${newChecked[i]}` + console.log(filterString) + } + } + props.onChange("LearningObject", filterString) }; const filtrosComponente = [ { exemplo: "Arte", value: "3" }, diff --git a/src/Components/SearchExpansionPanel/SearchEPIdiomas.js b/src/Components/SearchExpansionPanel/SearchEPIdiomas.js index a9426aec66f0c41fca8c30a99cab47f81591dd4e..e9bcacf38c6cbd138fb2e6c59cc52e53c3e5fce3 100644 --- a/src/Components/SearchExpansionPanel/SearchEPIdiomas.js +++ b/src/Components/SearchExpansionPanel/SearchEPIdiomas.js @@ -17,7 +17,7 @@ const useStyles = makeStyles(theme => ({ } })); -export default function SearchEPIdiomas() { +export default function SearchEPIdiomas(props) { const classes = useStyles(); const [checked, setChecked] = React.useState([0]); @@ -32,6 +32,15 @@ export default function SearchEPIdiomas() { } setChecked(newChecked); + let filterString = ""; + + for(let i = 0; i < newChecked.length; i++){ + if(newChecked[i] !== 0){ + filterString = filterString + `&languages[]=${newChecked[i]}` + console.log(filterString) + } + } + props.onChange("LearningObject", filterString) }; const filtrosIdiomas = [ { value: "5", exemplo: "Alemão" }, diff --git a/src/Components/SearchExpansionPanel/SearchEPTiposRec.js b/src/Components/SearchExpansionPanel/SearchEPTiposRec.js index 0d36afff0599d418b38b9c03592afb0615046352..8dc4fcf6782641ca5bee2916a75c75050f6f298c 100644 --- a/src/Components/SearchExpansionPanel/SearchEPTiposRec.js +++ b/src/Components/SearchExpansionPanel/SearchEPTiposRec.js @@ -17,7 +17,7 @@ const useStyles = makeStyles(theme => ({ } })); -export default function SearchEPTiposRec() { +export default function SearchEPTiposRec(props) { const classes = useStyles(); const [checked, setChecked] = React.useState([0]); @@ -31,7 +31,16 @@ export default function SearchEPTiposRec() { newChecked.splice(currentIndex, 1); } + let filterString = ""; + setChecked(newChecked); + for(let i = 0; i < newChecked.length; i++){ + if(newChecked[i] !== 0){ + filterString = filterString + `&object_types[]=${newChecked[i]}` + console.log(filterString) + } + } + props.onChange("LearningObject", filterString) }; const filtrosTipos = [ { value: "5", exemplo: "Animação" }, diff --git a/src/Components/SearchExpansionPanel/SearchExpansionPanel.js b/src/Components/SearchExpansionPanel/SearchExpansionPanel.js index 32c9b72eb11b94bbea425e674aff8168e9718c0b..ca65cb10c67872ac3d7e44c0b0f560b5cfa32a0a 100644 --- a/src/Components/SearchExpansionPanel/SearchExpansionPanel.js +++ b/src/Components/SearchExpansionPanel/SearchExpansionPanel.js @@ -1,20 +1,26 @@ -import React from "react"; +import React, { useState } from "react"; import { withStyles } from "@material-ui/core/styles"; -import MuiExpansionPanel from "@material-ui/core/ExpansionPanel"; -import MuiExpansionPanelSummary from "@material-ui/core/ExpansionPanelSummary"; -import MuiExpansionPanelDetails from "@material-ui/core/ExpansionPanelDetails"; +import MuiExpansionPanel from "@material-ui/core/Accordion"; +import MuiExpansionPanelSummary from "@material-ui/core/AccordionSummary"; +import MuiExpansionPanelDetails from "@material-ui/core/AccordionActions"; import Typography from "@material-ui/core/Typography"; import ExpandMoreIcon from "@material-ui/icons/ExpandMore"; import SearchEPCompCurriculum from "./SearchEPCompCurriculum"; import SearchEPTiposRec from "./SearchEPTiposRec"; import SearchEPEtapasEns from "./SesrchEPEtapasEns"; import SearchEPIdiomas from "./SearchEPIdiomas"; +import { TextField } from "@material-ui/core"; +import Grid from '@material-ui/core/Grid'; +import CircularProgress from '@material-ui/core/CircularProgress'; + +import './ExpansionPanel.css' + const ExpansionPanel = withStyles({ root: { border: "1px solid rgba(0, 0, 0, .125)", boxShadow: "none", - '.MuiButtonBase-root' : { - paddingInline:"0 !important" + '.MuiButtonBase-root': { + paddingInline: "0 !important" }, "&:not(:last-child)": { borderBottom: 0 @@ -35,7 +41,7 @@ const ExpansionPanelSummary = withStyles({ marginBottom: -1, minHeight: 56, backgroundColor: "#fff", - + "&$expanded": { minHeight: 56, @@ -58,11 +64,23 @@ const TesteTypography = withStyles({ const ExpansionPanelDetails = withStyles(theme => ({ root: { - padding: theme.spacing(2) + // padding: theme.spacing(2) } }))(MuiExpansionPanelDetails); -export default function SearchExpansionPanel() { +export default function SearchExpansionPanel(props) { + const [keyWords, setKeyWords] = useState(""); + + const onKeyPressed = (e) => { + const filterString = "&tags[]=" + keyWords + if (e.key === "Enter") + props.onChange("LearningObject", filterString) + } + + const HandleChangeText = (e) => { + setKeyWords(e.target.value); + } + return ( <div> <link @@ -75,32 +93,47 @@ export default function SearchExpansionPanel() { aria-controls="panel1d-content" id="panel1d-header" > - <Typography - style={{ - fontSize: "18px", - textTransform: "uppercase", - fontWeight: "500" - }} + <Grid + container + direction="row" + justify="space-between" > - Filtros - </Typography> + <Grid item > + <Typography + style={{ + fontSize: "18px", + textTransform: "uppercase", + fontWeight: "500", + }} + > + Filtros + </Typography> + </Grid> + <Grid item> + { + props.onFiltering ? <CircularProgress size={24} color="secondary" /> : null + } + </Grid> + </Grid> </ExpansionPanelSummary> </ExpansionPanel> + <ExpansionPanel square> <ExpansionPanelSummary - expandIcon ={<ExpandMoreIcon/>} - + expandIcon={<ExpandMoreIcon />} + aria-controls="panel2d-content" id="panel2d-header" > <TesteTypography>Componentes Curriculares</TesteTypography> </ExpansionPanelSummary> <ExpansionPanelDetails> - <Typography> - <SearchEPCompCurriculum /> - </Typography> + <div> + <SearchEPCompCurriculum onChange={props.onChange} /> + </div> </ExpansionPanelDetails> </ExpansionPanel> + <ExpansionPanel square> <ExpansionPanelSummary expandIcon={<ExpandMoreIcon />} @@ -110,9 +143,10 @@ export default function SearchExpansionPanel() { <Typography>Tipos de Recurso</Typography> </ExpansionPanelSummary> <ExpansionPanelDetails> - <SearchEPTiposRec /> + <SearchEPTiposRec onChange={props.onChange} /> </ExpansionPanelDetails> </ExpansionPanel> + <ExpansionPanel square> <ExpansionPanelSummary aria-controls="panel4d-content" @@ -122,9 +156,10 @@ export default function SearchExpansionPanel() { <Typography>Etapas de Ensino</Typography> </ExpansionPanelSummary> <ExpansionPanelDetails> - <SearchEPEtapasEns /> + <SearchEPEtapasEns onChange={props.onChange} /> </ExpansionPanelDetails> </ExpansionPanel> + <ExpansionPanel square> <ExpansionPanelSummary aria-controls="panel5d-content" @@ -134,9 +169,10 @@ export default function SearchExpansionPanel() { <Typography>Idiomas</Typography> </ExpansionPanelSummary> <ExpansionPanelDetails> - <SearchEPIdiomas /> + <SearchEPIdiomas onChange={props.onChange} /> </ExpansionPanelDetails> </ExpansionPanel> + <ExpansionPanel square> <ExpansionPanelSummary aria-controls="panel6d-content" @@ -146,12 +182,14 @@ export default function SearchExpansionPanel() { <Typography>Palavra-Chave</Typography> </ExpansionPanelSummary> <ExpansionPanelDetails> - <Typography> - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse - malesuada lacus ex, sit amet blandit leo lobortis eget. Lorem ipsum - dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada - lacus ex, sit amet blandit leo lobortis eget. - </Typography> + <TextField + label="Palavra chave + ENTER" + id="outlined-margin-dense" + margin="dense" + variant="outlined" + onChange={e => HandleChangeText(e)} + onKeyDown={e => onKeyPressed(e)} + /> </ExpansionPanelDetails> </ExpansionPanel> </div> diff --git a/src/Components/SearchExpansionPanel/SesrchEPEtapasEns.js b/src/Components/SearchExpansionPanel/SesrchEPEtapasEns.js index b0241d3221d414adcde34ed7fb60afa2467ea421..b08fdb680ae4e0e7be65c4c327adf8b34b96b39c 100644 --- a/src/Components/SearchExpansionPanel/SesrchEPEtapasEns.js +++ b/src/Components/SearchExpansionPanel/SesrchEPEtapasEns.js @@ -17,7 +17,7 @@ const useStyles = makeStyles(theme => ({ } })); -export default function SearchEPEtapasEns() { +export default function SearchEPEtapasEns(props) { const classes = useStyles(); const [checked, setChecked] = React.useState([0]); @@ -32,6 +32,17 @@ export default function SearchEPEtapasEns() { } setChecked(newChecked); + let filterString = ""; + + for(let i = 0; i < newChecked.length; i++){ + if(newChecked[i] !== 0){ + filterString = filterString + `&educational_stages[]=${newChecked[i]}` + } + } + if(filterString) + props.onChange("LearningObject", filterString) + else + props.onChange("LearningObject", "") }; const filtrosEtapas = [ { value: "1", exemplo: "Educação Infantil" }, diff --git a/src/Components/SearchSection.js b/src/Components/SearchSection.js index c82035cc368fb52601ce32dc3ebb4cae30d5a9c5..228d72b41c9762d19fc62fe0d73676ed36fc643a 100644 --- a/src/Components/SearchSection.js +++ b/src/Components/SearchSection.js @@ -16,13 +16,14 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {Component} from 'react'; +import React, {Component} from 'react'; import '../App.css'; import banner from '../img/bannerBusca.jpg'; // import SearchBar from './SearchBar'; import {Row} from 'react-grid-system'; import {MdInfoOutline} from "react-icons/md" import { FaRegPlayCircle} from "react-icons/fa"; +import ModalVideoApresentacao from "./ModalVideoApresentacao.js" const bannerStyle={ width: "100%", @@ -55,12 +56,18 @@ class SearchSection extends Component{ constructor(props){ super(props); this.state={ - color: "#ff7f00" + color: "#ff7f00", + modalOpen : false };} + toggleModal = () => { + this.setState({modalOpen : !this.state.modalOpen}) + } render(){ return( + <React.Fragment> + <ModalVideoApresentacao open={this.state.modalOpen} handleClose={this.toggleModal}/> <div style={bannerStyle}> <div style={titleStyle}> <h2>Plataforma MEC de Recursos Educacionais Digitais</h2> @@ -72,15 +79,18 @@ class SearchSection extends Component{ <SearchBar/> </Container> */} <div style={{paddingBottom: "100px", color: "white"}}> - <a href="sobre" style={{color:"#fff",textDecoration: "none", outline:"none"}}><MdInfoOutline size="24px" style={{verticalAlign: "middle"}} />SOBRE A PLATAFORMA</a> - <a href="#apresentacao" style={{color:"#fff",textDecoration: "none"}}> <FaRegPlayCircle size="20px" style={{verticalAlign: "middle"}} />VÍDEO DE APRESENTAÇÃO</a> + <a href="sobre" style={{color:"#fff",textDecoration: "none", outline:"none", paddingRight : "10px"}}><MdInfoOutline size="24px" style={{verticalAlign: "middle", paddingRight : "5px"}} />SOBRE A PLATAFORMA</a> + <span onClick={this.toggleModal} style={{cursor : "pointer"}}> + <FaRegPlayCircle size="20px" style={{verticalAlign: "middle", paddingRight : "5px"}}/>VÍDEO DE APRESENTAÇÃO + </span> </div> - <Row justify="center"> + <Row justify="center" style={{marginLeft:0, marginRight:0}}> <button style={{...buttonStyle, ...{backgroundColor: "#ff7f00",fontSize:"1.14em", outline:"none"}}} onClick={()=> {this.props.function("Recursos")}}>Recursos Educacionais Digitais</button> <button style={{...buttonStyle, ...{backgroundColor: "#e81f4f",fontSize:"1.14em", outline:"none"}}} onClick={()=> {this.props.function("Materiais")}}>Materiais de Formação</button> <button style={{...buttonStyle, ...{backgroundColor: "#673ab7",fontSize:"1.14em", outline:"none"}}} onClick={()=> {this.props.function("Colecoes")}}>Coleções dos Usuários</button> </Row> </div> + </React.Fragment> ); } } diff --git a/src/Components/ShareModal.js b/src/Components/ShareModal.js index 1f3b771286cd3f95c331295e9691277914e11842..93eb4828efc78e5cf0b8216caa8297d3c5c4331c 100644 --- a/src/Components/ShareModal.js +++ b/src/Components/ShareModal.js @@ -22,9 +22,6 @@ import Modal from '@material-ui/core/Modal'; import Backdrop from '@material-ui/core/Backdrop'; import Fade from '@material-ui/core/Fade'; import styled from 'styled-components' -import SignUpContainer from './SignUpContainerFunction.js' -import {Store} from '../Store.js' -import axios from 'axios' import {apiDomain} from '../env'; import Grid from '@material-ui/core/Grid'; import Facebook from '../img/facebook.svg' @@ -33,11 +30,14 @@ import LinkIcon from '../img/link_icon.svg' import CloseModalButton from './CloseModalButton.js' export default function ReportModal (props) { - const refContainer = useRef(props.link); - - function copyToClipboard(e) { - let copyText = document.getElementById('p-text') - console.log(copyText) + const textAreaRef = useRef(props.link); + + const copyToClipboard = (e) => { + textAreaRef.current.select(); + document.execCommand('copy'); + // This is just personal preference. + // I prefer to not show the whole text area selected. + e.target.focus(); }; return ( @@ -73,34 +73,40 @@ export default function ReportModal (props) { {/*Share to facebook*/} <Grid item xs={4}> - <a + <StyledLink href={"https://www.facebook.com/sharer/sharer.php?u=" + props.link} + rel="noreferrer" target="_blank"> <ShareButton> <img src={Facebook} alt="facebook-logo"/> <p>FACEBOOK</p> </ShareButton> - </a> + </StyledLink> </Grid> {/*Share to Twitter*/} <Grid item xs={4}> - <a + <StyledLink href={"https://www.twitter.com/intent/tweet?url=" + props.link} + rel="noreferrer" target="_blank"> <ShareButton> <img src={Twitter} alt="twitter-logo"/> <p>TWITTER</p> </ShareButton> - </a> + </StyledLink> </Grid> {/*Get shareable link*/} <Grid item xs={4}> + { + document.queryCommandSupported('copy') && <ShareButton onClick={copyToClipboard}> <img src={LinkIcon} alt="link-icon"/> - <p id="p-text" value={props.link}>COPIAR LINK</p> + <p>COPIAR LINK</p> + <textarea ref={textAreaRef} value={props.link} readOnly style={{height: "0", position: "absolute",zIndex: "-1"}}/> </ShareButton> + } </Grid> </Grid> </ShareInfo> @@ -201,16 +207,6 @@ const Header = styled.div` } ` -const StyledCloseModalButton = styled(Button)` - display : inline-block; - position : relative; - float : right !important; - margin-right : -8px !important; - background : transparent !important; - min-width: 0 !important; - width : 40px; -` - const StyledModal = styled(Modal)` .djXaxP{ margin : 0 !important; @@ -246,3 +242,6 @@ const Container = styled.div` height : 100%; } ` +const StyledLink = styled.a` + text-decoration : none; +` \ No newline at end of file diff --git a/src/Components/SignUpContainer.js b/src/Components/SignUpContainer.js deleted file mode 100644 index 9d01f58daf46303a7b3967d3eb8adc5d2e7e9ec0..0000000000000000000000000000000000000000 --- a/src/Components/SignUpContainer.js +++ /dev/null @@ -1,326 +0,0 @@ -/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre -Departamento de Informatica - Universidade Federal do Parana - -This file is part of Plataforma Integrada MEC. - -Plataforma Integrada MEC is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -Plataforma Integrada MEC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ - -import React, {Component} from "react"; -import GoogleLogin from 'react-google-login' -import { Button } from '@material-ui/core'; -//import FacebookLogin from 'react-facebook-login'; -import CloseIcon from '@material-ui/icons/Close'; -import styled from 'styled-components' -import {device} from './device.js' -import FormInput from "./FormInput.js" -import {StyledCloseModalButton, DialogContentDiv, DialogHeaderStyled, SocialConnectDiv, StyledGoogleLoginButton, H3Div} from './LoginContainer.js' -const responseGoogle = (response) => { - console.log(response); -} - -const responseFacebook = (response) => { - console.log(response); -} - -var Recaptcha = require('react-recaptcha') - -//alterar funcao do callback -var callback = function () { - console.log('Done!!!!'); -}; - -function validateUserInfo (name, email, password) { - const errors = [] - - if(name.lenght === 0 ) { - errors.push({name : "name", msg : "Faltou preencher seu nome completo."}) - } - if(email.length === 0) { - errors.push({name : "email", msg : "Faltou preencher seu e-mail."}) - } - else if ( (email.split("").filter(x => x === "@").length !== 1) || (email.indexOf(".") === -1) ){ - errors.push({name : "email", msg : "Insira um endereço de email válido."}) - errors.push({name : "email", msg : "Por exemplo: seunome@gmail.com, seunome@hotmail.com"}) - } - if(password.length === 0) { - errors.push({ name : "password", msg : "Faltou definir uma senha."}) - } - - return errors -} - -class SignUpContainer extends Component { - constructor (props) { - super(props); - - this.state = { - name: "", - email: "", - password: "", - - errors : [] - }; - }; - - switchModal = (e) => { - e.preventDefault() - this.props.handleClose() - this.props.openLogin() - }; - - handleChange = e => { - this.setState({[e.target.name]: e.target.value}) - - }; - - onSubmit = (e) => { - //on submit we should prevent the page from refreshing - e.preventDefault(); //though this is arguable - const { name, email, password } = this.state; - const errors = validateUserInfo(name, email, password) - console.log(this.state) - if ( errors.length < 1) { - //pass user info to Store.js and clear all text fields - this.props.handleLoginInfo(this.state) - this.setState({ - name: "", - email: "", - password: "" - }) - } - else { - this.setState({errors}) - } - - } - - render () { - const { errors } = this.state; - return ( - <ContainerStyled > - <DialogHeaderStyled> - <span style={{width:"32px"}}/> - <H2Styled> Cadastrar-se - </H2Styled> - <StyledCloseModalButton onClick={this.props.handleClose} > - <CloseIcon /> - </StyledCloseModalButton> - </DialogHeaderStyled> - - <DialogContentDiv> - <SocialConnectDiv> - <StyledGoogleLoginButton - clientId="658977310896-knrl3gka66fldh83dao2rhgbblmd4un9.apps.googleusercontent.com" - onSuccess={responseGoogle} - onFailure={responseGoogle} - cookiePolicy={'single_host_origin'} - > - <span style={{textTransform:"none", fontSize:"13px"}}>Usando o Google</span> - </StyledGoogleLoginButton> - </SocialConnectDiv> - - <H3Div> - <H3Styled> - <RightSideStrikedH3/> - <span style={{verticalAlign:"middle"}}>ou</span> - <LeftSideStrikedH3/> - </H3Styled> - </H3Div> - - <form ref="form" onSubmit={this.onSubmit}> - {errors.map(error => ( - <p key={error.name}>Error: {error.msg}</p> - ))} - <FormInput - inputType={"text"} - name={"name"} - value={this.state.name} - placeholder={"Nome Completo"} - handleChange={e => this.handleChange(e)} - required={true} - /> - <br/> - <FormInput - inputType={"text"} - name={"email"} - value={this.state.email} - placeholder={"E-mail"} - handleChange={e => this.handleChange(e)} - required={true} - /> - <br/> - <FormInput - inputType={"password"} - name={"password"} - value={this.state.password} - placeholder={"Senha"} - handleChange={e => this.handleChange(e)} - required={true} - /> - <br/> - <Recaptcha - sitekey="6LcyFr8UAAAAAOd0Po6rmZC1D_nYik8nLCAkNKsc" - size="normal" - render="explicit" - onloadCallback={callback} - /> - <ConfirmContainerStyled> - <StyledSignUpButton type="submit" variant="contained"> - <span - style={{paddingLeft:"16px", paddingRight:"16px", borderRadius:"3px", boxSizing:"border-box", - fontFamily:"Roboto, sans serif", fontWeight:"500", color:"#fff"}} - > - CADASTRAR - </span> - </StyledSignUpButton> - </ConfirmContainerStyled> - </form> - - <TermosDeUsoStyled> - <p>Ao se cadastrar, você está aceitando os Termos de Uso e de Política - de Privacidade. <a href="./">Ler Termos</a>.</p> - </TermosDeUsoStyled> - - <DialogFooterStyled> - <span style={{textAlign:"center", fontSize: "14px"}}>Já possui cadastro? <StyledAnchor href="" onClick={e => this.switchModal(e)}>ENTRAR</StyledAnchor></span> - </DialogFooterStyled> - </DialogContentDiv> - </ContainerStyled> - ) - } -} - -export default SignUpContainer - -const ContainerStyled = styled.div` - box-sizing : border-box; - background-color : white; - max-width : none; - align : center; - display : flex; - flex-direction : column; - min-width : 450px; - - max-height : none; - position : relative; - padding : 10px; - @media ${device.mobileM} { - width : 100%; - height : 100%; - } -` - -const DialogFooterStyled = styled.div` - box-sizing : border-box; - font-family : 'Roboto', sans serif; - margin : 20px -20px; - padding-top : 20px; - border-top : 1px #e5e5e5 solid; - justify-content : center; - text-align : center; - line-height : 1.42857143 -` - -const TermosDeUsoStyled = styled.div` - font-family: 'Roboto', sans serif, 'Helvetica Neue', Helvetica, Arial, sans-serif; - color : #666; - font-size : 13px; - margin : 0 0 10px; - max-width : 350px; - margin-top : 10px; - text-align : start; -` - -const H2Styled = styled.h2` - align-self : center; - color : #666; - font-size : 26px; - font-weight : lighter; - justify-content: space-between; - font-family: 'Roboto', sans serif, 'Helvetica Neue', Helvetica, Arial, sans-serif !important; - text-align: center; - letter-spacing: .005em; -` - -const H3Styled = styled.h3` - overflow : hidden; - text-align : center; - font-size : 14px; - color : #666; - margin : 10px 0; -` -const RightSideStrikedH3 = styled.div` - display : inline-block; - border-bottom: 1px dotted #666; - vertical-align : middle; - font-weight : 500; - margin-right : 5px; - width : 45%; -` - -const LeftSideStrikedH3 = styled.div` - display : inline-block; - border-bottom: 1px dotted #666; - vertical-align : middle; - font-weight : 500; - margin-left : 5px; - width : 45%; -` - -const StyledAnchor = styled.a` - color : #00bcd4; - text-decoration : none; -` -//const StyledCloseModalButton = styled(Button)` -// display : inline-block; -// position : relative; -// float : right !important; -// margin-right : -8px; -// background : transparent; -// min-width: 0 !important; -// width : 40px; -//` - -const ConfirmContainerStyled = styled.div` - display : flex; - margin-top : 10px; - align-items : center; - justify-content : center; - box-sizing : border-box; - font-size : 13px; -` - -const StyledSignUpButton = styled(Button)` - background-color: #00bcd4 !important; - box-shadow : none !important; - outline: none !important; - border : 0 !important; - overflow : hidden !important; - width : 50% !important; - display : inline-block !important; - font-family : 'Roboto', sans serif !important; - font-size: 14px !important; - height : 36px !important; - align-items : center !important; - border-radius: 3px !important; - align-self : 50% !important; - :hover { - background-color : #00acc1 !important; - } -` - -const StyledRecaptcha = styled(Recaptcha)` - display : flex !important; - justify-content : center !important; -` diff --git a/src/Components/SignUpContainerFunction.js b/src/Components/SignUpContainerFunction.js index 44e3df95450417562ead91717e0abd5a7134d65c..d336d3417c5075122c4090f03be9695458746620 100644 --- a/src/Components/SignUpContainerFunction.js +++ b/src/Components/SignUpContainerFunction.js @@ -17,22 +17,25 @@ You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ import React, {useState} from "react"; -import GoogleLogin from 'react-google-login' import { Button } from '@material-ui/core'; //import FacebookLogin from 'react-facebook-login'; import CloseIcon from '@material-ui/icons/Close'; import styled from 'styled-components' import {device} from './device.js' import FormInput from "./FormInput.js" -import {StyledCloseModalButton, DialogContentDiv, DialogHeaderStyled, SocialConnectDiv, StyledGoogleLoginButton, H3Div} from './LoginContainer.js' -import ValidateUserInput from '../Components/FormValidationFunction.js' - -var Recaptcha = require('react-recaptcha') - -var callback = function () { - console.log('Done!!!!'); -}; - +import {StyledCloseModalButton, DialogContentDiv, DialogHeaderStyled, SocialConnectDiv, H3Div} from './LoginContainerFunction.js' +import {apiUrl} from '../env.js' +import {GoogleLoginButton} from './LoginContainerFunction' +import ValidateUserInput from './HelperFunctions/FormValidationFunction.js' +import GoogleLogo from "../img/logo_google.svg" + +async function handleGoogleAttempt () { + console.log("handleGoogleAttempt") + let request_url = ( + `${apiUrl}/omniauth/google_oauth2?auth_origin_url=` + window.location.href + '&omniauth_window_type=sameWindow&resource_class=User' + ) + window.location.replace(request_url) +} export default function SignUpContainer (props) { const [formNome, setNome] = useState( { @@ -99,10 +102,6 @@ export default function SignUpContainer (props) { }) } - const responseGoogle = (response) => { - console.log(response); - } - const switchModal = (e) => { e.preventDefault() props.handleClose() @@ -132,14 +131,10 @@ export default function SignUpContainer (props) { <DialogContentDiv> <SocialConnectDiv> - <StyledGoogleLoginButton - clientId="658977310896-knrl3gka66fldh83dao2rhgbblmd4un9.apps.googleusercontent.com" - onSuccess={responseGoogle} - onFailure={responseGoogle} - cookiePolicy={'single_host_origin'} - > - <span style={{textTransform:"none", fontSize:"13px"}}>Usando o Google</span> - </StyledGoogleLoginButton> + <GoogleLoginButton onClick={handleGoogleAttempt}> + <img src={GoogleLogo} alt="google-logo" className="google-logo"/> + <span>Usando o Google</span> + </GoogleLoginButton> </SocialConnectDiv> <H3Div> @@ -169,7 +164,7 @@ export default function SignUpContainer (props) { handleChange={e => handleChange(e, 'email')} required={true} error={formEmail.key} - help = {formEmail.key ? (formEmail.value.length == 0 ? "Faltou preencher seu e-mail." : <span>Insira um endereço de e-mail válido.<br/>Por exemplo: seunome@gmail.com, seunome@hotmail.com</span>) : ""} + help = {formEmail.key ? (formEmail.value.length === 0 ? "Faltou preencher seu e-mail." : <span>Insira um endereço de e-mail válido.<br/>Por exemplo: seunome@gmail.com, seunome@hotmail.com</span>) : ""} /> <br/> <FormInput @@ -180,15 +175,9 @@ export default function SignUpContainer (props) { handleChange={e => handleChange(e, 'password')} required={true} error={formSenha.key} - help = {formSenha.key ? (formSenha.value.length == 0 ? "Faltou digitar sua senha." : "A senha precisa ter no mínimo 8 caracteres.") : ""} + help = {formSenha.key ? (formSenha.value.length === 0 ? "Faltou digitar sua senha." : "A senha precisa ter no mínimo 8 caracteres.") : ""} /> <br/> - <Recaptcha - sitekey="6LcyFr8UAAAAAOd0Po6rmZC1D_nYik8nLCAkNKsc" - size="normal" - render="explicit" - onloadCallback={callback} - /> <ConfirmContainerStyled> <StyledSignUpButton type="submit" variant="contained"> <span @@ -228,7 +217,10 @@ const ContainerStyled = styled.div` padding : 10px; @media ${device.mobileM} { width : 100%; + min-width : unset; height : 100%; + min-width : unset !important; + } ` @@ -277,7 +269,7 @@ const RightSideStrikedH3 = styled.div` vertical-align : middle; font-weight : 500; margin-right : 5px; - width : 45%; + width : 44%; ` const LeftSideStrikedH3 = styled.div` @@ -286,7 +278,7 @@ const LeftSideStrikedH3 = styled.div` vertical-align : middle; font-weight : 500; margin-left : 5px; - width : 45%; + width : 44%; ` const StyledAnchor = styled.a` @@ -330,8 +322,3 @@ const StyledSignUpButton = styled(Button)` background-color : #00acc1 !important; } ` - -const StyledRecaptcha = styled(Recaptcha)` - display : flex !important; - justify-content : center !important; -` diff --git a/src/Components/SignUpModal.js b/src/Components/SignUpModal.js index b4c156af213fcc92dd57daa0996ce4a40d8381b6..d3ed47c79a2b85273ff94601d99092d6e52bbacc 100644 --- a/src/Components/SignUpModal.js +++ b/src/Components/SignUpModal.js @@ -16,40 +16,28 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ import React, {useContext} from 'react'; -import { makeStyles } from '@material-ui/styles'; -import { Button } from '@material-ui/core'; import Modal from '@material-ui/core/Modal'; import Backdrop from '@material-ui/core/Backdrop'; import Fade from '@material-ui/core/Fade'; import styled from 'styled-components' import SignUpContainer from './SignUpContainerFunction.js' import {Store} from '../Store.js' -import axios from 'axios' -import {apiUrl} from '../env'; - -const StyledModalSignUp = styled(Modal)` - .djXaxP{ - margin : 0 !important; - } - - display : flex; - align-items: center; - justify-content : center; - text-align : center; - padding : 10px !important; - border-radius : 4px; - -` - - +import {authentication} from './HelperFunctions/getAxiosConfig' export default function SignUpModal (props) { const { state, dispatch } = useContext(Store) + function handleSuccess (data) { + dispatch ({ + type: 'USER_SIGNED_UP', + userLoggedIn: !state.userIsLoggedIn, + user: data.data + }) + props.handleClose() + } const handleLoginInfo = (newLogin) => { - {/*console.log(state.currentUser)*/} - axios.post(`${apiUrl}/auth`, - { + const url = `/auth` + const payload = { name : newLogin.name, email: newLogin.email, password : newLogin.password, @@ -57,42 +45,15 @@ export default function SignUpModal (props) { terms_of_service:true, avatar: "" } - ).then( (response) => { - dispatch ( { - type: 'USER_SIGNED_UP', - userLoggedIn: !state.userIsLoggedIn, - login: { - id : response.data.id, - username : response.data.name, - email : response.data.email, - accessToken : response.headers['access-token'], - clientToken : response.headers.client, - userAvatar : response.data.avatar_file_name, - userCover : response.data.cover_file_name - } - } - ) - localStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - localStorage.setItem('@portalmec/clientToken', response.headers.client,) - localStorage.setItem('@portalmec/id', response.data.data.id) - localStorage.setItem('@portalmec/username', response.data.data.name) - localStorage.setItem('@portalmec/uid', response.data.data.uid) - console.log(state.currentUser) - props.handleClose() - }, (error) => { - console.log(':(') - } - ) + authentication(url, payload, handleSuccess, (error) => {console.log(error)}) } - //useEffect(()=>{console.log(state.currentUser)},[state.currentUser]) - return ( <StyledModalSignUp aria-labelledby="transition-modal-title" aria-describedby="transition-modal-description" open={props.open} - + centered="true" onClose={props.handleClose} closeAfterTransition @@ -111,3 +72,17 @@ export default function SignUpModal (props) { </StyledModalSignUp> ) } + +const StyledModalSignUp = styled(Modal)` + .djXaxP{ + margin : 0 !important; + } + + display : flex; + align-items: center; + justify-content : center; + text-align : center; + padding : 10px !important; + border-radius : 4px; + +` diff --git a/src/Components/StatsBar.js b/src/Components/StatsBar.js index 0572d3f89199ec0096cfb582b681888cf02e9168..0cdde4942b065244271cb8e5c82f44e0e96d36d2 100644 --- a/src/Components/StatsBar.js +++ b/src/Components/StatsBar.js @@ -18,6 +18,8 @@ along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/> import React, {Component} from 'react'; import {Col,Row, Container} from 'react-grid-system'; +import { apiUrl } from "../env"; +import axios from "axios"; import mapaBrasil from '../img/mapa-brasil-line-icon.svg'; const brasilStyle={ backgroundColor: "#00bcd4", @@ -41,6 +43,21 @@ const statistcStyle={ }; class StatsBar extends Component{ + constructor(props){ + super(props) + this.state ={ + available_resources: 0, + month_publications:0, + month_downloads:0 + } + } + componentDidMount(){ + // https://api.portalmec.c3sl.ufpr.br/v1/statistics + axios.get(`${apiUrl}/statistics`).then((res) => { + this.setState({available_resources:res.data.count, month_publications:res.data.month_publications, month_downloads:res.data.month_downloads}) + }) + } + render(){ return( <div style={brasilStyle}> @@ -50,7 +67,7 @@ class StatsBar extends Component{ <img src={mapaBrasil} height="83px" alt="mapa do brasil"/> <span style={statistcStyle}> <span style={numberStyle}> - 31061 + {this.state.available_resources} </span> <span> Recursos disponíveis @@ -62,13 +79,13 @@ class StatsBar extends Component{ ESSE MÊS: <span style={statistcStyle}> <span style={numberStyle}> - 10 + {this.state.month_downloads} </span> Baixados </span> <span style={statistcStyle}> <span style={numberStyle}> - 1 + {this.state.month_publications} </span> Publicados </span> diff --git a/src/Components/Stepper.js b/src/Components/Stepper.js index c550c2d94f110930e42ea057d6e47d737ab12353..b1315b9844bdd5726e5b7589c1adf6be80d87417 100644 --- a/src/Components/Stepper.js +++ b/src/Components/Stepper.js @@ -1,4 +1,4 @@ -import React, {useState} from 'react' +import React from 'react' import styled from 'styled-components' export default function Stepper (props) { diff --git a/src/Components/StoreGuide.js b/src/Components/StoreGuide.js index a4b0f509b11a3c8ab590e397c1fe07e9ba616c5c..f3f22b5695349341eaab3a7bb80bd3c0a7875749 100644 --- a/src/Components/StoreGuide.js +++ b/src/Components/StoreGuide.js @@ -15,12 +15,11 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useState, useContext} from 'react'; +import React from 'react'; import styled from 'styled-components'; import Grid from '@material-ui/core/Grid'; import Card from '@material-ui/core/Card'; import CardContent from '@material-ui/core/CardContent'; -import { Typography } from '@material-ui/core'; const StoreTitle = styled.h1` margin-top: 0; @@ -68,7 +67,7 @@ export default function ItemStoreContainer (props) { As seções da loja dividem os itens por <strong>categoria</strong>. <ul> <li> - Itens adquiridos <strong>somente por conquistas</strong> não aparecem + Itens adquiridos <strong>somente por conquistas</strong> não aparecem na loja (exceto pelos que você já tem); </li> <li> diff --git a/src/Components/TabPanels/Breadcrumbs.js b/src/Components/TabPanels/Breadcrumbs.js index 00d547825993a8dd803b6d3a7f89617e71fd2714..1d208986d7bd89b210da95806d101796301a36d9 100644 --- a/src/Components/TabPanels/Breadcrumbs.js +++ b/src/Components/TabPanels/Breadcrumbs.js @@ -1,3 +1,22 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + + import React from 'react' import styled from 'styled-components' import Breadcrumbs from '@material-ui/core/Breadcrumbs'; @@ -12,8 +31,8 @@ export default function CustomizedBreadcrumbs (props) { Página Inicial </Link> { - props.values.map( (value) => - <span> + props.values.map( (value, i) => + <span key={i}> {value} </span> ) diff --git a/src/Components/TabPanels/PanelComponents/NoContent.js b/src/Components/TabPanels/PanelComponents/NoContent.js index 60c8d76d0e2e952467399bb766ab3e46ddcc2ac1..ef129ecef30c18abc9ab58d501330ab8b778678f 100644 --- a/src/Components/TabPanels/PanelComponents/NoContent.js +++ b/src/Components/TabPanels/PanelComponents/NoContent.js @@ -51,8 +51,8 @@ export const DivTextoNoPublications = styled.div` padding-right : 15px; ` -{/*const DivConteudoNaoPublicado = styled.div` - position : relative; - top : 50%; - transform : translateY(-50%); -`*/} +// {/*const DivConteudoNaoPublicado = styled.div` +// position : relative; +// top : 50%; +// transform : translateY(-50%); +// `*/} diff --git a/src/Components/TabPanels/PanelComponents/TemplateColecao.js b/src/Components/TabPanels/PanelComponents/TemplateColecao.js index dfb193fc5a5db0774c39c7df8095153eedc36c59..3b1e029ae45caa45f28068cd95693796a6331a86 100644 --- a/src/Components/TabPanels/PanelComponents/TemplateColecao.js +++ b/src/Components/TabPanels/PanelComponents/TemplateColecao.js @@ -21,17 +21,18 @@ import Grid from '@material-ui/core/Grid'; import NoContent from './NoContent.js' import CollectionCardFunction from '../../CollectionCardFunction.js' import Title from './PanelTitle.js' -import {WhiteContainer, StyledGrid} from '../StyledComponents.js' -import {ButtonsAreaColecao} from './ButtonsArea' +import { WhiteContainer, StyledGrid } from '../StyledComponents.js' +import { ButtonsAreaColecao } from './ButtonsArea' -export default function PanelTemplateColecao (props) { +export default function PanelTemplateColecao(props) { const RenderFollowedColCard = (card, followerBoolean) => { if (followerBoolean) { return ( <CollectionCardFunction - name={card.followable.name} - rating={card.followable.score} + name={card.name} + collections={card.followable.collection_items} + rating={card.followable.review_average} type={card.followable.object_type} description={card.followable.description} author={card.followable.owner.name} @@ -43,27 +44,27 @@ export default function PanelTemplateColecao (props) { followed={card.followable.followed} privacy={card.followable.privacy} id={card.followable.id} - /> + tags={card.followable.tags} + /> ) } else { return ( <CollectionCardFunction - name={card.name} - rating={card.score} - type={card.object_type} - description={card.description} - author={card.owner.name} - avatar={card.owner.avatar} - authorID={card.owner.id} - thumbnails={card.items_thumbnails} - likeCount={card.likes_count} - privacy={card.privacy} - liked={card.liked} - followed={card.followed} - tags={card.tags} - id={card.id} - /> + name={card.name} + tags={card.tags} + rating={card.review_average} + id={card.id} + author={card.owner.name} + description={card.description} + thumbnails={card.items_thumbnails} + avatar={card.owner.avatar} + likeCount={card.likes_count} + followed={card.followed} + liked={card.liked} + collections={card.collection_items} + authorID={card.owner.id} + /> ) } } @@ -78,24 +79,21 @@ export default function PanelTemplateColecao (props) { { props.length === 0 ? ( - [ - <NoContent text={props.noContentText}/> - ] + <NoContent text={props.noContentText}/> ) : ( - [ <React.Fragment> - <StyledGrid container spacing={1} style={{paddingLeft : "30px", paddingRight : "15px"}}> - { - props.sliceArr.map( (card) => - <Grid item md={3} xs={12} key={card.id}> - {RenderFollowedColCard(card, props.followed)} - </Grid> - ) - } - </StyledGrid> + <StyledGrid container spacing={1} style={{ paddingLeft: "30px", paddingRight: "15px" }}> + { + props.sliceArr.map((card) => + <Grid item md={3} xs={12} key={card.id}> + {RenderFollowedColCard(card, props.followed)} + </Grid> + ) + } + </StyledGrid> <ButtonsAreaColecao sliceLength={props.sliceArr.length} @@ -104,7 +102,6 @@ export default function PanelTemplateColecao (props) { showAll={() => props.showAll()} /> </React.Fragment> - ] ) } diff --git a/src/Components/TabPanels/PanelComponents/TemplateCuradoria.js b/src/Components/TabPanels/PanelComponents/TemplateCuradoria.js index 132b96efa8ba381fa3ad1eb5cdfc0fb66611965f..28390ab44fedca9c8e18c95af860496f2317ca55 100644 --- a/src/Components/TabPanels/PanelComponents/TemplateCuradoria.js +++ b/src/Components/TabPanels/PanelComponents/TemplateCuradoria.js @@ -21,10 +21,11 @@ import Grid from '@material-ui/core/Grid'; import NoContent from './NoContent.js' import ResourceCardFunction from '../../ResourceCardFunction.js' import Title from './PanelTitle.js' -import {WhiteContainer, StyledGrid} from '../StyledComponents.js' -import {ButtonsAreaRecurso} from './ButtonsArea' +import { WhiteContainer, StyledGrid } from '../StyledComponents.js' +import { ButtonsAreaRecurso } from './ButtonsArea' -export default function Template (props) { +export default function Template(props) { + console.log(props.sliceArr); return ( <WhiteContainer> <Title @@ -34,44 +35,48 @@ export default function Template (props) { { props.length === 0 ? - ( - [ - <NoContent text={props.noContentText}/> - ] - ) - : - ( - [ - <React.Fragment> - <StyledGrid container spacing={1} style={{paddingLeft : "30px", paddingRight : "15px"}}> - { - props.sliceArr.map( (card) => - <Grid item md={3} xs={12} key={card.id}> - <ResourceCardFunction - id={card.learning_object.id} - avatar = {card.submitter.avatar} - thumbnail = {card.learning_object.thumbnail} - type = {card.learning_object.object_type ? card.learning_object.object_type : "Outros"} - title={card.learning_object.name} - published={false} - tags={card.educational_stages} - href={"/recurso/" + card.learning_object.id} - downloadableLink={card.default_attachment_location} - /> - </Grid> - ) - } - </StyledGrid> + ( + [ + <NoContent text={props.noContentText} /> + ] + ) + : + ( + [ + <React.Fragment> + <StyledGrid container spacing={1} style={{ paddingLeft: "30px", paddingRight: "15px" }}> + { + props.sliceArr.map((card) => + <Grid item md={3} xs={12} key={card.id}> + <ResourceCardFunction + avatar={card.submitter.avatar} + id={card.learning_object.id} + thumbnail={card.learning_object.thumbnail} + type={card.learning_object.object_type ? card.learning_object.object_type : "Outros"} + title={card.learning_object.name} + published={false} + likeCount={card.learning_object.likes_count} + liked={card.learning_object.liked} + rating={card.learning_object.review_average} + author={card.submitter.name} + tags={card.learning_object.tags} + href={"/recurso/" + card.learning_object.id} + downloadableLink={card.default_attachment_location} + /> + </Grid> + ) + } + </StyledGrid> - <ButtonsAreaRecurso - sliceLength={props.sliceArr.length} - length={props.length} - showMore={() => props.showMore()} - showAll={() => props.showAll()} - /> - </React.Fragment> - ] - ) + <ButtonsAreaRecurso + sliceLength={props.sliceArr.length} + length={props.length} + showMore={() => props.showMore()} + showAll={() => props.showAll()} + /> + </React.Fragment> + ] + ) } </WhiteContainer> diff --git a/src/Components/TabPanels/PanelComponents/TemplateRecurso.js b/src/Components/TabPanels/PanelComponents/TemplateRecurso.js index 6d46e423e6c596efbff5a2725d7ba5d8bb26feab..7fe23657690955daee2580a278001f1605b9c7e0 100644 --- a/src/Components/TabPanels/PanelComponents/TemplateRecurso.js +++ b/src/Components/TabPanels/PanelComponents/TemplateRecurso.js @@ -21,10 +21,10 @@ import Grid from '@material-ui/core/Grid'; import NoContent from './NoContent.js' import ResourceCardFunction from '../../ResourceCardFunction.js' import Title from './PanelTitle.js' -import {WhiteContainer, StyledGrid} from '../StyledComponents.js' -import {ButtonsAreaRecurso} from './ButtonsArea' +import { WhiteContainer, StyledGrid } from '../StyledComponents.js' +import { ButtonsAreaRecurso } from './ButtonsArea' -export default function Template (props) { +export default function Template(props) { return ( <WhiteContainer> <Title @@ -34,48 +34,49 @@ export default function Template (props) { { props.length === 0 ? - ( - [ - <NoContent text={props.noContentText}/> - ] - ) - : - ( - [ - <React.Fragment> - <StyledGrid container spacing={1} style={{paddingLeft : "30px", paddingRight : "15px"}}> - { - props.slice.map( (card) => - <Grid item md={3} xs={12} key={card.id}> - <ResourceCardFunction - avatar = {card.publisher.avatar} - id={card.id} - thumbnail = {card.thumbnail} - type = {card.object_type !== null? card.object_type : "Outros"} - title={card.name} - published={card.state === "published" ? true : false} - likeCount={card.likes_count} - liked={card.liked} - rating={card.review_average} - tags={card.educational_stages} - href={"/recurso/" + card.id} - downloadableLink={card.default_attachment_location} + ( + [ + <NoContent text={props.noContentText} /> + ] + ) + : + ( + [ + <React.Fragment> + <StyledGrid container spacing={1} style={{ paddingLeft: "30px", paddingRight: "15px" }}> + { + props.slice.map((card) => + <Grid item md={3} xs={12} key={card.id}> + <ResourceCardFunction + avatar={card.publisher.avatar} + id={card.id} + thumbnail={card.thumbnail} + type={card.object_type ? card.object_type : "Outros"} + title={card.name} + published={card.state === "published" ? true : false} + likeCount={card.likes_count} + liked={card.liked} + rating={card.review_average} + author={card.publisher.name} + tags={card.tags} + href={"/recurso/" + card.id} + downloadableLink={card.default_attachment_location} - /> - </Grid> - ) - } - </StyledGrid> + /> + </Grid> + ) + } + </StyledGrid> - <ButtonsAreaRecurso - sliceLength={props.slice.length} - length={props.length} - showMore={() => props.showMore()} - showAll={() => props.showAll()} - /> - </React.Fragment> - ] - ) + <ButtonsAreaRecurso + sliceLength={props.slice.length} + length={props.length} + showMore={() => props.showMore()} + showAll={() => props.showAll()} + /> + </React.Fragment> + ] + ) } </WhiteContainer> diff --git a/src/Components/TabPanels/PanelComponents/TemplateRede.js b/src/Components/TabPanels/PanelComponents/TemplateRede.js index b4ded29ef208c343697b8828481bf517abacd27c..e92a49db31b72e4b5d89a91f4e26658c520ba66a 100644 --- a/src/Components/TabPanels/PanelComponents/TemplateRede.js +++ b/src/Components/TabPanels/PanelComponents/TemplateRede.js @@ -13,8 +13,8 @@ export default function PanelTemplateRede (props) { return ( <ContactCard name = {card.follower.name} - avatar = {card.follower.avatar ? apiDomain + card.follower.avatar : null} - cover={card.follower.cover ? apiDomain + card.follower.cover : null} + avatar = {card.follower.avatar !== undefined && card.follower.avatar !== ""? apiDomain + card.follower.avatar : null} + cover={card.follower.cover !== undefined && card.follower.cover !== "" ? apiDomain + card.follower.cover : null} numCollections = {card.follower.collections_count} numLearningObjects = {card.follower.learning_objects_count} follow_count={card.follower.follows_count} @@ -28,8 +28,8 @@ export default function PanelTemplateRede (props) { return ( <ContactCard name = {card.followable.name} - avatar = {card.followable.avatar ? apiDomain + '/' + card.followable.avatar : null} - cover={apiDomain + card.followable.cover} + avatar = {card.followable.avatar !== undefined && card.followable.avatar !== "" ? apiDomain + '/' + card.followable.avatar : null} + cover={card.followable.cover !== undefined && card.followable.cover !== "" ? apiDomain + card.followable.cover : null} numCollections = {card.followable.collections_count} numLearningObjects = {card.followable.learning_objects_count} follow_count={card.followable.follows_count} diff --git a/src/Components/TabPanels/PublicUserPageTabs/LastCollections.js b/src/Components/TabPanels/PublicUserPageTabs/LastCollections.js index 495a5e2df68e3dc2892fc0813db88bfa9fab7593..553b9788dc860e290de3b72bf1acdfd7e06b1730 100644 --- a/src/Components/TabPanels/PublicUserPageTabs/LastCollections.js +++ b/src/Components/TabPanels/PublicUserPageTabs/LastCollections.js @@ -1,11 +1,29 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + import React from 'react' import Grid from '@material-ui/core/Grid'; -import {HeaderGrid, StyledGrid} from '../StyledComponents.js' -import {NoContent} from './TabInicio.js' +import { HeaderGrid, StyledGrid } from '../StyledComponents.js' +import { NoContent } from './TabInicio.js' import CollectionCardFunction from '../../CollectionCardFunction.js' import NoCol from '../../../img/Pagina_vazia_colecao.png' -export default function LastCols (props) { +export default function LastCols(props) { return ( <React.Fragment> <HeaderGrid container> @@ -16,46 +34,48 @@ export default function LastCols (props) { { - props.count == 0 || props.collections.length == 0? - ( - [ - <Grid container> - <Grid item xs={12}> - <NoContent - image={NoCol} - text1={props.username + " ainda não disponibilizou nenhuma coleção."} - text2={"Quando disponibilizar, elas aparecerão aqui."} - /> + props.count === 0 || props.collections.length === 0 ? + ( + [ + <Grid container> + <Grid item xs={12}> + <NoContent + image={NoCol} + text1={props.username + " ainda não disponibilizou nenhuma coleção."} + text2={"Quando disponibilizar, elas aparecerão aqui."} + /> + </Grid> </Grid> - </Grid> - ] - ) - : - ( - [ - <StyledGrid container spacing={1} style={{paddingLeft : "0.5em"}}> - { - props.collections.slice(0,4).map( (card) => - <Grid item md={3} xs={12} key={card.id}> - <CollectionCardFunction - name={card.name} - rating={card.score} - type={card.object_type} - description={card.description} - author={card.owner.name} - avatar={card.owner.avatar} - thumbnails={card.items_thumbnails} - likeCount={card.likes_count} - liked={card.liked} - followed={card.followed} - tags={card.tags} - /> - </Grid> - ) - } - </StyledGrid> - ] - ) + ] + ) + : + ( + [ + <StyledGrid container spacing={1} style={{ paddingLeft: "0.5em" }}> + { + props.collections.slice(0, 4).map((card) => + <Grid item md={3} xs={12} key={card.id}> + <CollectionCardFunction + name={card.name} + tags={card.tags} + rating={card.review_average} + id={card.id} + author={card.owner.name} + description={card.description} + thumbnails={card.items_thumbnails} + avatar={card.owner.avatar} + likeCount={card.likes_count} + followed={card.followed} + liked={card.liked} + collections={card.collection_items} + authorID={card.owner.id} + /> + </Grid> + ) + } + </StyledGrid> + ] + ) } </React.Fragment> ) diff --git a/src/Components/TabPanels/PublicUserPageTabs/LastLearnObj.js b/src/Components/TabPanels/PublicUserPageTabs/LastLearnObj.js index d1c3b1315e2a13da178548ceb5259e4bc47f2a63..705faa8d77e70cdeee8b6bbf4ea9e65ead1313fc 100644 --- a/src/Components/TabPanels/PublicUserPageTabs/LastLearnObj.js +++ b/src/Components/TabPanels/PublicUserPageTabs/LastLearnObj.js @@ -1,18 +1,36 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + import React from 'react' import Grid from '@material-ui/core/Grid'; import ResourceCardFunction from '../../ResourceCardFunction.js' import NoPub from '../../../img/Pagina_vazia_Sem_publicar.png' -import {HeaderGrid, StyledGrid} from '../StyledComponents.js' -import {NoContent} from './TabInicio.js' +import { HeaderGrid, StyledGrid } from '../StyledComponents.js' +import { NoContent } from './TabInicio.js' -export default function LastLearnObjs (props) { +export default function LastLearnObjs(props) { return ( <React.Fragment> <HeaderGrid container> <Grid item xs={9}> <h3>Últimos Recursos Publicados</h3> </Grid> - <Grid item xs={3} style={{textAlign : "end"}}> + <Grid item xs={3} style={{ textAlign: "end" }}> {props.count > 4 && <span> VER MAIS @@ -22,48 +40,49 @@ export default function LastLearnObjs (props) { </HeaderGrid> { - props.count == 0 ? - ( - [ - <Grid container> - <Grid item xs={12}> - <NoContent - image={NoPub} - text1={props.username + " ainda não disponibilizou nenhum recurso."} - text2={"Quando disponibilizar, eles aparecerão aqui."} - /> + props.count === 0 ? + ( + [ + <Grid container> + <Grid item xs={12}> + <NoContent + image={NoPub} + text1={props.username + " ainda não disponibilizou nenhum recurso."} + text2={"Quando disponibilizar, eles aparecerão aqui."} + /> + </Grid> </Grid> - </Grid> - ] - ) - : - ( - [ - <StyledGrid container spacing={1} style={{paddingLeft : "0.5em"}}> - { - props.learningObjs.slice(0,4).map( (card) => - <Grid item md={3} xs={12} key={card.id}> - <ResourceCardFunction - avatar = {card.publisher.avatar} - id={card.id} - thumbnail = {card.thumbnail} - type = {card.object_type !== null? card.object_type : "Outros"} - title={card.name} - published={card.state === "published" ? true : false} - likeCount={card.likes_count} - liked={card.liked} - rating={card.review_average} - tags={card.educational_stages} - href={"/recurso/" + card.id} - downloadableLink={card.default_attachment_location} + ] + ) + : + ( + [ + <StyledGrid container spacing={1} style={{ paddingLeft: "0.5em" }}> + { + props.learningObjs.slice(0, 4).map((card) => + <Grid item md={3} xs={12} key={card.id}> + <ResourceCardFunction + avatar={card.publisher.avatar} + id={card.id} + thumbnail={card.thumbnail} + type={card.object_type ? card.object_type : "Outros"} + title={card.name} + published={card.state === "published" ? true : false} + likeCount={card.likes_count} + liked={card.liked} + rating={card.review_average} + author={card.publisher.name} + tags={card.tags} + href={"/recurso/" + card.id} + downloadableLink={card.default_attachment_location} - /> - </Grid> - ) - } - </StyledGrid> - ] - ) + /> + </Grid> + ) + } + </StyledGrid> + ] + ) } </React.Fragment> ) diff --git a/src/Components/TabPanels/PublicUserPageTabs/TabColecoes.js b/src/Components/TabPanels/PublicUserPageTabs/TabColecoes.js index 2ab49230b9c737d3468b9645cf9786fd29e07510..2b81757d34ee93379d60a8165bac6f6f31216f2e 100644 --- a/src/Components/TabPanels/PublicUserPageTabs/TabColecoes.js +++ b/src/Components/TabPanels/PublicUserPageTabs/TabColecoes.js @@ -1,18 +1,35 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + import React, {useState, useEffect} from 'react' -import styled from 'styled-components' import {HeaderGrid, ContainerStyled, Carregados} from '../StyledComponents.js' import Grid from '@material-ui/core/Grid'; import CollectionCardFunction from '../../CollectionCardFunction.js' -import {ButtonMostrarMaisColecao} from '../PanelComponents/ButtonsArea.js' +import { ButtonMostrarMaisColecao } from '../PanelComponents/ButtonsArea.js' -export default function TabRecursos (props) { +export default function TabRecursos(props) { const [arr, setArr] = useState([]) const [colsSlice, setSlice] = useState([]) - const handleSlice = (newArr) => {setSlice(newArr)} + const handleSlice = (newArr) => { setSlice(newArr) } - useEffect( () => { + useEffect(() => { setArr(props.collections) - setSlice(props.collections.slice(0,4)) + setSlice(props.collections.slice(0, 4)) }, []) const showMore = (quantity) => { @@ -21,30 +38,32 @@ export default function TabRecursos (props) { } return ( - <ContainerStyled style={{flexDirection : "column"}}> + <ContainerStyled style={{ flexDirection: "column" }}> <HeaderGrid container> <Grid item xs={12}> - <h3>Coleções públicas <b style={{fontWeight:"500"}}>({props.count})</b></h3> + <h3>Coleções públicas <b style={{ fontWeight: "500" }}>({props.count})</b></h3> </Grid> </HeaderGrid> - <Grid container spacing={1} style={{paddingLeft : "0.5em"}}> + <Grid container spacing={1} style={{ paddingLeft: "0.5em" }}> { - colsSlice.map( (card) => + colsSlice.map((card) => <Grid item md={3} xs={12} key={card.id}> <CollectionCardFunction name={card.name} - rating={card.score} - type={card.object_type} - description={card.description} + tags={card.tags} + rating={card.review_average} + id={card.id} author={card.owner.name} - avatar={card.owner.avatar} + description={card.description} thumbnails={card.items_thumbnails} + avatar={card.owner.avatar} likeCount={card.likes_count} - liked={card.liked} followed={card.followed} - tags={card.tags} + liked={card.liked} + collections={card.collection_items} + authorID={card.owner.id} /> </Grid> ) @@ -52,19 +71,19 @@ export default function TabRecursos (props) { </Grid> <Carregados> - <p style={{margin:"0 0 10px", fontSize:"14px"}}> + <p style={{ margin: "0 0 10px", fontSize: "14px" }}> Carregados {colsSlice.length} de {arr.length} </p> { props.count > 5 && <React.Fragment> - <ButtonMostrarMaisColecao onClick={() => {showMore(4)}}> - <span style={{color:"#fff", fontSize:"14px", fontWeight:"500"}}>MOSTRAR MAIS 4</span> + <ButtonMostrarMaisColecao onClick={() => { showMore(4) }}> + <span style={{ color: "#fff", fontSize: "14px", fontWeight: "500" }}>MOSTRAR MAIS 4</span> </ButtonMostrarMaisColecao> - <ButtonMostrarMaisColecao onClick={() => {showMore(20)}}> - <span style={{color:"#fff", fontSize:"14px", fontWeight:"500"}}>MOSTRAR MAIS 20</span> + <ButtonMostrarMaisColecao onClick={() => { showMore(20) }}> + <span style={{ color: "#fff", fontSize: "14px", fontWeight: "500" }}>MOSTRAR MAIS 20</span> </ButtonMostrarMaisColecao> </React.Fragment> } diff --git a/src/Components/TabPanels/PublicUserPageTabs/TabInicio.js b/src/Components/TabPanels/PublicUserPageTabs/TabInicio.js index f0febf175a58638dde9ae48b71810da80bb62255..0663a44c4412e545429c7b560bf9eb2ca9e88126 100644 --- a/src/Components/TabPanels/PublicUserPageTabs/TabInicio.js +++ b/src/Components/TabPanels/PublicUserPageTabs/TabInicio.js @@ -1,3 +1,21 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + import React from 'react' import styled from 'styled-components' import UserDescription from './UserDescription.js' @@ -32,7 +50,7 @@ export function NoContent (props) { return ( <NoContentContainer> <div style={{paddingTop : "1em"}}> - <img src={props.image} style={{width : "130px", verticalAlign : "middle", border : "0"}}/> + <img alt="" src={props.image} style={{width : "130px", verticalAlign : "middle", border : "0"}}/> <h3> {props.text1} </h3> @@ -54,7 +72,7 @@ export default function TabInicio (props) { <UserDescription text={props.user.description}/> } { - props.user.learning_objects_count == 0 && props.user.collections_count == 0 ? + props.user.learning_objects_count === 0 && props.user.collections_count === 0 ? ( [ <ContainerStyled> diff --git a/src/Components/TabPanels/PublicUserPageTabs/TabRecursos.js b/src/Components/TabPanels/PublicUserPageTabs/TabRecursos.js index ce445d9ad57aa2b6627018314a45741b23ad1b5b..bf677ebd921dd7f91ffe469a49c4800686843191 100644 --- a/src/Components/TabPanels/PublicUserPageTabs/TabRecursos.js +++ b/src/Components/TabPanels/PublicUserPageTabs/TabRecursos.js @@ -1,51 +1,83 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + import React, {useState, useEffect} from 'react' -import styled from 'styled-components' import {HeaderGrid, ContainerStyled, Carregados} from '../StyledComponents.js' import Grid from '@material-ui/core/Grid'; import ResourceCardFunction from '../../ResourceCardFunction.js' import {ButtonMostrarMaisRecurso} from '../PanelComponents/ButtonsArea' +import {getRequest} from '../../HelperFunctions/getAxiosConfig' -export default function TabRecursos (props) { +export default function TabRecursos(props) { const [arr, setArr] = useState([]) const [objsSlice, setSlice] = useState([]) - const handleSlice = (newArr) => {setSlice(newArr)} + const handleSlice = (newArr) => { setSlice(newArr) } - useEffect( () => { + useEffect(() => { setArr(props.learningObjs) - setSlice(props.learningObjs.slice(0,4)) + setSlice(props.learningObjs.slice(0, 4)) }, []) + function handleSuccess (data) { + setArr(data) + setSlice(data) + } const showMore = (quantity) => { var sliceLength = objsSlice.length - handleSlice(arr.slice(0, sliceLength + quantity)) + var newLength = sliceLength + quantity + + if (newLength > 12) { + const url = `/users/${props.id}/learning_objects?limit=${newLength}$offset=4` + getRequest(url,handleSuccess,(error) => {console.log(error)}) + } + else { + handleSlice(arr.slice(0, sliceLength + quantity)) + } + } return ( - <ContainerStyled style={{flexDirection : "column"}}> + <ContainerStyled style={{ flexDirection: "column" }}> <HeaderGrid container> <Grid item xs={12}> - <h3>Recursos Publicados <b style={{fontWeight:"500"}}>({props.count})</b></h3> + <h3>Recursos Publicados <b style={{ fontWeight: "500" }}>({props.count})</b></h3> </Grid> </HeaderGrid> - <Grid container spacing={1} style={{paddingLeft : "0.5em"}}> + <Grid container spacing={1} style={{ paddingLeft: "0.5em" }}> { - objsSlice.map( (card) => + objsSlice.map((card) => <Grid item md={3} xs={12} key={card.id}> <ResourceCardFunction - avatar = {card.publisher.avatar} + avatar={card.publisher.avatar} id={card.id} - thumbnail = {card.thumbnail} - type = {card.object_type ? card.object_type : "Outros"} + thumbnail={card.thumbnail} + type={card.object_type ? card.object_type : "Outros"} title={card.name} published={card.state === "published" ? true : false} likeCount={card.likes_count} liked={card.liked} rating={card.review_average} - tags={card.educational_stages} + author={card.publisher.name} + tags={card.tags} + href={"/recurso/" + card.id} downloadableLink={card.default_attachment_location} - /> </Grid> ) @@ -53,19 +85,19 @@ export default function TabRecursos (props) { </Grid> <Carregados> - <p style={{margin:"0 0 10px", fontSize:"14px"}}> + <p style={{ margin: "0 0 10px", fontSize: "14px" }}> Carregados {objsSlice.length} de {arr.length} </p> { props.count > 5 && <React.Fragment> - <ButtonMostrarMaisRecurso onClick={() => {showMore(4)}}> - <span style={{color:"#fff", fontSize:"14px", fontWeight:"500"}}>MOSTRAR MAIS 4</span> + <ButtonMostrarMaisRecurso onClick={() => { showMore(4) }}> + <span style={{ color: "#fff", fontSize: "14px", fontWeight: "500" }}>MOSTRAR MAIS 4</span> </ButtonMostrarMaisRecurso> - <ButtonMostrarMaisRecurso onClick={() => {showMore(20)}}> - <span style={{color:"#fff", fontSize:"14px", fontWeight:"500"}}>MOSTRAR MAIS 20</span> + <ButtonMostrarMaisRecurso onClick={() => { showMore(20) }}> + <span style={{ color: "#fff", fontSize: "14px", fontWeight: "500" }}>MOSTRAR MAIS 20</span> </ButtonMostrarMaisRecurso> </React.Fragment> } diff --git a/src/Components/TabPanels/PublicUserPageTabs/TabRede.js b/src/Components/TabPanels/PublicUserPageTabs/TabRede.js index ac1d3a0694d125c1beb4131f8ad9ebc02819772e..c173dc195d4000acbeda628ffbbef127d1934339 100644 --- a/src/Components/TabPanels/PublicUserPageTabs/TabRede.js +++ b/src/Components/TabPanels/PublicUserPageTabs/TabRede.js @@ -1,20 +1,24 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + import React, {useState, useEffect} from 'react' -import axios from 'axios' -import {apiUrl, apiDomain} from '../../../env'; import PanelTemplateRede from '../PanelComponents/TemplateRede.js' - -const getConfig = () => { - let config = { - headers : { - 'Accept': 'application/json', - 'Content-Type':'application/json', - 'Access-Token': sessionStorage.getItem('@portalmec/accessToken'), - 'Client': sessionStorage.getItem('@portalmec/clientToken'), - 'Uid': sessionStorage.getItem('@portalmec/uid') - } - } - return config -} +import {fetchAllRequest} from '../../HelperFunctions/getAxiosConfig' export default function TabRede (props) { const [followers, setFollowers] = useState([]) @@ -34,26 +38,19 @@ export default function TabRede (props) { } const showAllFollowing = () => {setFollowingSlice(following)} + function handleSuccess (responseArr) { + setFollowers(responseArr[0]) + setFollowersSlice(responseArr[0].slice(0,4)) + + setFollowing(responseArr[1]) + setFollowingSlice(responseArr[1].slice(0,4)) + } + useEffect( () => { - axios.all([ - axios.get((`${apiUrl}/users/` + props.id + '/followers'), getConfig()), - axios.get((`${apiUrl}/users/` + props.id + '/following/User'), getConfig()) - ]) - .then( (responseArr) => { - console.log('responseArr Rede: ', responseArr) - if (responseArr[0].headers['access-token']) { - sessionStorage.setItem('@portalmec/accessToken', responseArr[0].headers['access-token']) - } - setFollowers(responseArr[0].data) - setFollowersSlice(responseArr[0].data.slice(0,4)) - setFollowing(responseArr[1].data) - setFollowingSlice(responseArr[1].data.slice(0,4)) - }, - (error) => { - console.log('error while running axios all') - } - ) + const urls = [`/users/${props.id}/followers`, `/users/${props.id}/following/User`] + + fetchAllRequest(urls, handleSuccess, (error) => {console.log(error)}) }, []) return ( diff --git a/src/Components/TabPanels/PublicUserPageTabs/UserDescription.js b/src/Components/TabPanels/PublicUserPageTabs/UserDescription.js index 495e60e37f549d330c9281f2f86c71d73590367f..4fcc273f0a0b3e8ed984f1d831488d8002a978dd 100644 --- a/src/Components/TabPanels/PublicUserPageTabs/UserDescription.js +++ b/src/Components/TabPanels/PublicUserPageTabs/UserDescription.js @@ -1,3 +1,21 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + import React from 'react' import styled from 'styled-components' diff --git a/src/Components/TabPanels/StyledComponents.js b/src/Components/TabPanels/StyledComponents.js index 2570be1d40a302c096a4432e8feede85b95f3685..d77966a39660501c93ccc687a52056cd301b1eb2 100644 --- a/src/Components/TabPanels/StyledComponents.js +++ b/src/Components/TabPanels/StyledComponents.js @@ -16,13 +16,12 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React from 'react' import styled from 'styled-components' import Grid from '@material-ui/core/Grid'; import Tabs from '@material-ui/core/Tabs'; import { Container } from 'react-grid-system' -{/* COMPONENTS USED IN ALL TABS */} +// {/* COMPONENTS USED IN ALL TABS */} export const ContainerDivStyled = styled.div` /*No portal atual: "container nopad box"*/ @@ -185,11 +184,11 @@ export const UserProfileInfoDiv = styled.div` ` export const CheckTeacherDiv = styled.div` - @media screen and (min-width: 500px) { - padding-top : 10px; - padding-left : 250px; - margin-bottom : -10px; - } + padding-top : 10px; + padding-left : 250px; + margin-bottom : -10px; + display : absolute; + p { margin : 0 0 10px; font-family: Roboto; @@ -207,9 +206,6 @@ export const CheckTeacherDiv = styled.div` } } } - @media screen and (max-width: 499px) { - display : none; - } ` export const StyledTabs = styled(Tabs)` diff --git a/src/Components/TabPanels/TabPanelStatusEConquistas.js b/src/Components/TabPanels/TabPanelStatusEConquistas.js index 00a3a1f234162ecfb29633818e7a5f1497a34c12..d9e0c20762cb1387ee0ab460f27fe5aeffd2dc07 100644 --- a/src/Components/TabPanels/TabPanelStatusEConquistas.js +++ b/src/Components/TabPanels/TabPanelStatusEConquistas.js @@ -1,12 +1,27 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + + import React, {useContext, useState, useEffect} from 'react' import { Store } from '../../Store.js' import styled from 'styled-components' -import { Container } from 'react-grid-system' import Paper from '@material-ui/core/Paper'; -import Button from '@material-ui/core/Button'; import {ContainerDivStyled} from './StyledComponents.js' -import LoadingSpinner from '../LoadingSpinner.js' -import PaginaVaziaColecao from '../../img/Pagina_vazia_colecao.png' import axios from 'axios' import {apiUrl} from '../../env'; import LevelDescriptionCard from '../LevelDescriptionCard.js' @@ -14,11 +29,17 @@ import AchievementDescriptionCard from '../AchievementDescriptionCard.js' import { Grid } from '@material-ui/core' export default function TabPanelStatusEConquistas (props) { + // eslint-disable-next-line const [achievements, setAchievements] = useState([]); + // eslint-disable-next-line const [level, setLevel] = useState(0); + // eslint-disable-next-line const [xp, setXP] = useState(0); + // eslint-disable-next-line const [coins, setCoins] = useState(0); + // eslint-disable-next-line const [barSize, setBarSize] = useState(0); + // eslint-disable-next-line const [xpToNextLevel, setXpToNextLevel] = useState(0); const { state } = useContext(Store) @@ -66,7 +87,7 @@ export default function TabPanelStatusEConquistas (props) { src={a.imgsrc} requirements={a.requirements} /> - + </Grid> )} )} diff --git a/src/Components/TabPanels/UserPageTabs/ContainerRedeVazia.js b/src/Components/TabPanels/UserPageTabs/ContainerRedeVazia.js index 6d746d03a3a671996886376b606646904b345283..6d15099126be1f6637d77c754b1b21ddcb97284b 100644 --- a/src/Components/TabPanels/UserPageTabs/ContainerRedeVazia.js +++ b/src/Components/TabPanels/UserPageTabs/ContainerRedeVazia.js @@ -16,13 +16,11 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useContext, useState, useEffect} from 'react' +import React from 'react' import styled from 'styled-components' -import { Container } from 'react-grid-system' import NoRede1 from '../../../img/no-rede-1.png' import NoRede2 from '../../../img/no-rede-2.png' import NoRede3 from '../../../img/no-rede-3.png' -import Paper from '@material-ui/core/Paper'; import TabRedeImgDiv from './TabRedeImgDiv.js' import {WhiteContainer} from '../StyledComponents.js' import Grid from '@material-ui/core/Grid'; @@ -58,14 +56,6 @@ export default function ContainerRedeVazia (props) { ) } -const DivColumns = styled.div` - display : flex; - flex-direction : row; - aling-items : space-between - padding-right : 15px; - padding-left : 15px -` - const StyledHr = styled.hr` margin-top : 20px; margin-bottom : 20px; diff --git a/src/Components/TabPanels/UserPageTabs/ModalExcluirConta.js b/src/Components/TabPanels/UserPageTabs/ModalExcluirConta.js new file mode 100644 index 0000000000000000000000000000000000000000..1d4410498bd71d489e4d8ccd9a3284bb8f890662 --- /dev/null +++ b/src/Components/TabPanels/UserPageTabs/ModalExcluirConta.js @@ -0,0 +1,213 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + +import React, {useContext, useState} from 'react'; +import {Store} from '../../../Store.js' +import { Button } from '@material-ui/core'; +import Modal from '@material-ui/core/Modal'; +import Backdrop from '@material-ui/core/Backdrop'; +import Fade from '@material-ui/core/Fade'; +import styled from 'styled-components' +import CloseIcon from '@material-ui/icons/Close'; +import ExcluirAvatar from '../../../img/Excluir.png' +import GreyButton from '../../GreyButton' +import FormInput from '../../FormInput' +import {Link} from 'react-router-dom' +import SnackbarComponent from '../../SnackbarComponent.js' +import {deleteRequest} from '../../HelperFunctions/getAxiosConfig' + +function CloseModalButton (props) { + return ( + <StyledCloseModalButton onClick={props.handleClose}> + <CloseIcon/> + </StyledCloseModalButton> + ) +} + +export default function ModalExcluirConta (props) { + const {state, dispatch} = useContext(Store) + + const [formEmail, setEmail] = useState( + { + key : false, + value : "", + } + ) + const handleChange = (e) => { + const userInput = e.target.value + let flag = !(userInput === state.currentUser.email) + + setEmail({...formEmail, + key : flag, + value : userInput + }) + } + + const [snackbarOpen, toggleSnackbar] = useState(false) + + const deletedAccountText = `A conta ${state.currentUser.email} foi deletada com sucesso` + + function handleSuccess (data) { + toggleSnackbar(true) + dispatch({ + type: "USER_DELETED_ACCOUNT", + }); + props.handleClose() + } + const deleteAccount = () => { + const url = `/auth` + deleteRequest(url, handleSuccess, (error) => {console.log(error)}) + } + + return ( + <React.Fragment> + <SnackbarComponent snackbarOpen={snackbarOpen} severity={"info"} handleClose={() => {toggleSnackbar(false)}} text={deletedAccountText}/> + <StyledModal + aria-labelledby="transition-modal-title" + aria-describedby="transition-modal-description" + open={props.open} + centered="true" + onClose={props.handleClose} + closeAfterTransition + BackdropComponent={Backdrop} + BackdropProps={{ + timeout: 500, + }} + > + <Fade in={props.open}> + <Container> + <Header> + <span style={{width:"32px"}}/> + <h2>Excluir a Conta Definitivamente</h2> + <CloseModalButton handleClose={props.handleClose}/> + </Header> + <Content> + <div style={{display : "flex", flexDirection : "column", color : "#666", textAlign : "left"}}> + <div style={{display : "flex", flexDirection : "row", margin : "0 30px", justifyContent : "center", alignContent : "center"}}> + <div style={{height : "90px", position : "relative"}}> + <img src={ExcluirAvatar} alt="excluir-avatar" style={{height : "inherit", objectFit : "contain", verticalAlign : "middle"}}/> + </div> + <p style={{paddingLeft : "10px"}}>Você é muito importante para a rede, ficaríamos felizes se você ficasse. Quer contar o que aconteceu? Talvez possamos ajudar. <StyledLink to="/contato">Entre em contato.</StyledLink></p> + </div> + <p style={{marginTop : "20px"}}> + Saiba que a exclusão da conta removerá o seu perfil permanentemente. Se você publicou algum recurso, ele ainda ficará disponível para os usuários da plataforma. + </p> + <p style={{marginTop : "20px"}}> + É necessário que você digite seu e-mail para confirmar a exclusão: + </p> + <FormInput + inputType={"text"} + name={"email"} + value={formEmail.value} + placeholder={"Digite seu e-mail de cadastro"} + handleChange={e => handleChange(e)} + required={true} + error = {formEmail.key} + help = {formEmail.key ? ( formEmail.value.length === 0 ? "Faltou preencher seu e-mail." : "O e-mail deve ser o mesmo no qual você cadastrou esta conta") : ""} + /> + <div style={{display : "flex", flexDirection : "row", justifyContent : "space-evenly", paddingTop : "15px"}}> + <GreyButton callback={props.handleClose} text={"Cancelar"}/> + <RedButton disabled={formEmail.key} onClick = {() => {deleteAccount()}}>EXCLUIR PERMANENTEMENTE</RedButton> + </div> + </div> + </Content> + </Container> + </Fade> + </StyledModal> + </React.Fragment> + ) +} + +const RedButton = styled(Button)` + background-color : rgb(230,60,60) !important; + color : #fff !important; + font-weight : bolder; + box-shadow : 0 2px 5px 0 rgba(0,0,0,.26) !important; +` + +const Content = styled.div` + padding : 20px 30px; + +` + +const Header = styled.div` + display : flex; + flex-direction : row; + padding : 10px 26px 0 26px; + align-items : center; + justify-content : space-between; + height : 64px; + + h2 { + font-size : 26px; + font-weight : lighter; + color : #666 + } +` + +const StyledCloseModalButton = styled(Button)` + display : inline-block; + position : relative; + float : right !important; + margin-right : -8px !important; + background : transparent !important; + min-width: 0 !important; + width : 40px; +` + +const StyledModal = styled(Modal)` + .djXaxP{ + margin : 0 !important; + } + display : flex; + align-items: center; + justify-content : center; + text-align : center; + padding : 10px !important; + max-width : none; + max-height : none; +` + +const Container = styled.div` + box-sizing : border-box; + box-shadow : 0 7px 8px -4px rgba(0,0,0,.2),0 13px 19px 2px rgba(0,0,0,.14),0 5px 24px 4px rgba(0,0,0,.12); + background-color : white; + align : center; + display : flex; + flex-direction : column; + min-width : 240px; + max-height : none; + position : relative; + padding : 10px; + border-radius : 4px; + + @media screen and (min-width : 700px) { + max-width : 600px; + max-height : 600px; + } + + @media screen and (max-width : 699px) { + overflow-y : scroll; + width : 100%; + height : 100%; + } +` +const StyledLink = styled(Link)` + text-decoration : none !important; + color : #00bcd4 !important; +` diff --git a/src/Components/TabPanels/UserPageTabs/PanelAtividades.js b/src/Components/TabPanels/UserPageTabs/PanelAtividades.js index 38080f38f5e14aec7ff2768d86d3b945b4186843..d43ce0da3f4f9023da4def6794f69cadf3195c3e 100644 --- a/src/Components/TabPanels/UserPageTabs/PanelAtividades.js +++ b/src/Components/TabPanels/UserPageTabs/PanelAtividades.js @@ -16,17 +16,16 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useContext, useState, useEffect} from 'react' +import React, {useState, useEffect} from 'react' import styled from 'styled-components' -import { Container } from 'react-grid-system' import Paper from '@material-ui/core/Paper'; import Button from '@material-ui/core/Button'; -import axios from 'axios' -import {apiUrl, apiDomain} from '../../../env'; +import {apiDomain} from '../../../env'; import Bolo from '../../../img/Bolo.png' import LoadingSpinner from '../../LoadingSpinner.js' import ActivityListItem from '../../ActivityListItem.js' import List from '@material-ui/core/List'; +import {getRequest} from '../../HelperFunctions/getAxiosConfig.js' export default function TabPanelAtividades (props) { const [loading, handleLoading] = useState(true) @@ -40,25 +39,18 @@ export default function TabPanelAtividades (props) { setNotificationsSlice(notifications.slice(0, sliceLength + offset)) } - useEffect( () => { - axios.get(`${apiUrl}/feed?offset=0&limit=30`, props.config) - .then( (response) => { - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } + function handleSuccess (data) { + setNotifications(data) + setNotificationsSlice(data.slice(0,30)) + setLength(data.length) - console.log('atividades response: ', response) - setNotifications(response.data) - setNotificationsSlice(response.data.slice(0,30)) - setLength(response.data.length) + handleLoading(false) + } + useEffect( () => { + const url = `/feed?offset=0&limit=30` + getRequest(url, handleSuccess, (error) => {console.log(error)}) - handleLoading(false) - }, - (error) => { - console.log('error while running getNotifications') - } - ) }, []) return ( @@ -83,9 +75,9 @@ export default function TabPanelAtividades (props) { [ <div> { - notificatonsLength == 0 ? + notificatonsLength === 0 ? ( - [ + <NoNotificationsDiv> <div> <div> @@ -99,15 +91,16 @@ export default function TabPanelAtividades (props) { </p> </div> </NoNotificationsDiv> - ] + ) : ( - [ <> + <> <List height={400} width={300}> { notificationsSlice.map( (notification) => <ActivityListItem + onMenuBar={false} avatar = {notification.owner.avatar ? apiDomain + notification.owner.avatar : null} activity = {notification.activity} actionType = {notification.trackable_type} @@ -124,7 +117,6 @@ export default function TabPanelAtividades (props) { <LoadMoreButton onClick={() => {showMore(20)}}><span>CARREGAR MAIS 20</span></LoadMoreButton> <span style={{fontSize:"14px", color : "#666"}}>Mostrando {notificationsSlice.length} de {notificatonsLength}</span> </> - ] ) } </div> @@ -225,11 +217,3 @@ const DivTitulo = styled.div` margin : 0; border-bottom: 1px solid #eee; ` - -const ContainerDivStyled = styled.div` - max-width : 1140px; - margin-left : auto; - margin-right : auto; - margin-left : 20em; - background-color: #fff; -` diff --git a/src/Components/TabPanels/UserPageTabs/PanelColecoes.js b/src/Components/TabPanels/UserPageTabs/PanelColecoes.js index f7883396f3359173d24eace08e1826429bdd8210..a6ec0c91cf89e1e6fd8ee9afed41d9c250be1d1a 100644 --- a/src/Components/TabPanels/UserPageTabs/PanelColecoes.js +++ b/src/Components/TabPanels/UserPageTabs/PanelColecoes.js @@ -16,24 +16,22 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useState, useEffect} from 'react' +import React, { useState, useEffect } from 'react' import styled from 'styled-components' import Grid from '@material-ui/core/Grid'; import LoadingSpinner from '../../LoadingSpinner.js' -import axios from 'axios' -import {apiUrl} from '../../../env'; import PanelTemplateColecao from '../PanelComponents/TemplateColecao.js' import PaginaVaziaColecao from '../../../img/Pagina_vazia_colecao.png' - import NoContent from '../PanelComponents/NoContent.js' -import {WhiteContainer, StyledGrid} from '../StyledComponents.js' +import { WhiteContainer, StyledGrid } from '../StyledComponents.js' import CreateNewFolderIcon from '@material-ui/icons/CreateNewFolder'; import Title from '../PanelComponents/PanelTitle.js' import CollectionCardFunction from '../../CollectionCardFunction.js' -import {ButtonsAreaColecao} from '../PanelComponents/ButtonsArea' +import { ButtonsAreaColecao } from '../PanelComponents/ButtonsArea' import CriarColecaoModal from '../../CriarColecaoModal.js' +import {fetchAllRequest} from '../../HelperFunctions/getAxiosConfig' -export default function TabPanelColecoes (props) { +export default function TabPanelColecoes(props) { const [loading, handleLoading] = useState(true) const [userCollections, setUserCollections] = useState([]) @@ -42,33 +40,21 @@ export default function TabPanelColecoes (props) { const [followedCollections, setFollowedCollections] = useState([]) const [followedCollectionsSlice, setFollowedCollectionsSlice] = useState([]) - const getInfo = () => { - axios.all([ - axios.get((`${apiUrl}/users/` + props.id + '/collections'), props.config), - axios.get((`${apiUrl}/users/` + props.id + '/following/Collection'), props.config), - ]) - .then( (responseArr) => { - console.log('responseArr Colecoes: ', responseArr) - if (responseArr[1].headers['access-token']) { - sessionStorage.setItem('@portalmec/accessToken', responseArr[1].headers['access-token']) - } - - handleLoading(false) - setUserCollections(responseArr[0].data) - setUserCollectionsSlice(responseArr[0].data.slice(0,3)) + function handleSuccess (responseArr) { + handleLoading(false) + setUserCollections(responseArr[0]) + setUserCollectionsSlice(responseArr[0].slice(0,3)) - setFollowedCollections(responseArr[1].data) - setFollowedCollectionsSlice(responseArr[1].data.slice(0,4)) + setFollowedCollections(responseArr[1]) + setFollowedCollectionsSlice(responseArr[1].slice(0,4)) + } - }, - (error) => { - handleLoading(false) - console.log('error while running axios all') - } - ) + const getInfo = () => { + const urls = [`/users/${props.id}/collections`, `/users/${props.id}/following/Collection`] + fetchAllRequest(urls, handleSuccess, (error) => {console.log(error)}) } - useEffect( () => { + useEffect(() => { getInfo() }, []) @@ -77,86 +63,86 @@ export default function TabPanelColecoes (props) { setUserCollectionsSlice(userCollections.slice(0, sliceLength + 4)) } - const showAllUserCollections = () => {setUserCollectionsSlice(userCollections)} + const showAllUserCollections = () => { setUserCollectionsSlice(userCollections) } const showMoreFollowedCollections = () => { var sliceLength = followedCollectionsSlice.length setFollowedCollectionsSlice(followedCollections.slice(0, sliceLength + 4)) } - const showAllFollowedCollections = () => {setFollowedCollectionsSlice(followedCollections)} + const showAllFollowedCollections = () => { setFollowedCollectionsSlice(followedCollections) } return ( <> - { - loading ? - ( - <LoadingSpinner text={'CARREGANDO COLEÇÕES'}/> - - ) - : - ( - [ - <React.Fragment> - <Tentativa - title={"Minhas Coleções"} - length={userCollections.length} - noContentText={ - <div> - <img src={PaginaVaziaColecao} alt="PaginaVaziaColecao" style={{height:"150px",width:"150px", verticalAlign:"middle", border:"0"}}/> - <br/> - <span style={{fontFamily:"Roboto", fontWeight:"lighter", fontSize:"24px"}}> - Criamos a sua primeira Coleção! + { + loading ? + ( + <LoadingSpinner text={'CARREGANDO COLEÇÕES'} /> + + ) + : + ( + [ + <React.Fragment> + <Tentativa + title={"Minhas Coleções"} + length={userCollections.length} + noContentText={ + <div> + <img src={PaginaVaziaColecao} alt="PaginaVaziaColecao" style={{ height: "150px", width: "150px", verticalAlign: "middle", border: "0" }} /> + <br /> + <span style={{ fontFamily: "Roboto", fontWeight: "lighter", fontSize: "24px" }}> + Criamos a sua primeira Coleção! </span> - <p style={{fontFamily:"Roboto", fontSize:"16px", margin:"10px 0 0", fontWeight : "normal"}}> - Adicione nela recursos que você queira acessar mais tarde. - <br/> + <p style={{ fontFamily: "Roboto", fontSize: "16px", margin: "10px 0 0", fontWeight: "normal" }}> + Adicione nela recursos que você queira acessar mais tarde. + <br /> Crie novas coleções clicando no cartão roxo "Criar Colecão". </p> - </div> - } - sliceArr={userCollectionsSlice} - showMore={showMoreUserCollections} - showAll={showAllUserCollections} - callback={getInfo} - /> - - <PanelTemplateColecao - title={"Coleções que eu sigo"} - length={followedCollections.length} - noContentText={"Você ainda não segue nenhuma coleção."} - sliceArr={followedCollectionsSlice} - showMore={showMoreFollowedCollections} - showAll={showAllFollowedCollections} - followed={true} - /> - </React.Fragment> - ] - ) - } + </div> + } + sliceArr={userCollectionsSlice} + showMore={showMoreUserCollections} + showAll={showAllUserCollections} + callback={getInfo} + /> + + <PanelTemplateColecao + title={"Coleções que eu sigo"} + length={followedCollections.length} + noContentText={"Você ainda não segue nenhuma coleção."} + sliceArr={followedCollectionsSlice} + showMore={showMoreFollowedCollections} + showAll={showAllFollowedCollections} + followed={true} + /> + </React.Fragment> + ] + ) + } </> ) } -function Tentativa (props) { +function Tentativa(props) { const [modalOpen, toggleModal] = useState(false) - const handleModal = () => {toggleModal(!modalOpen)}; + const handleModal = () => { toggleModal(!modalOpen) }; return ( <WhiteContainer> - <CriarColecaoModal open={modalOpen} handleClose={() => {handleModal(); props.callback()}}/> + <CriarColecaoModal open={modalOpen} handleClose={() => { handleModal(); props.callback() }} /> <Title title={props.title} length={props.length} /> - <StyledGrid container spacing={1} style={{paddingLeft : "30px", paddingRight : "15px"}}> + <StyledGrid container spacing={1} style={{ paddingLeft: "30px", paddingRight: "15px" }}> <Grid item md={3} xs={12}> - <CardDiv onClick={()=>{handleModal()}}> - <div style={{backgroundColor:"#673ab7", height:"250px", display:"flex", justifyContent:"center", alignItems:"center"}}> - <CreateNewFolderIcon style={{color:"#fff", fontSize:"70px"}}/> - <p style={{fontSize:"16px", margin:"0 0 10px", color : "#fff"}}> + <CardDiv onClick={() => { handleModal() }}> + <div style={{ backgroundColor: "#673ab7", height: "250px", display: "flex", justifyContent: "center", alignItems: "center" }}> + <CreateNewFolderIcon style={{ color: "#fff", fontSize: "70px" }} /> + <p style={{ fontSize: "16px", margin: "0 0 10px", color: "#fff" }}> CRIAR COLEÇÃO </p> </div> @@ -165,53 +151,52 @@ function Tentativa (props) { { props.length === 0 ? - ( - [ - <Grid item lg={6} md={4} sm={6} xs={12}> - <NoContent text={props.noContentText}/> - </Grid> - ] - ) - : - ( - [ - <React.Fragment> - { - props.sliceArr.map( (card) => - <Grid item md={3} xs={12} key={card.id}> - <CollectionCardFunction - name={card.name} - rating={card.score} - type={card.object_type} - description={card.description} - author={card.owner.name} - avatar={card.owner.avatar} - authorID={card.owner.id} - thumbnails={card.items_thumbnails} - likeCount={card.likes_count} - liked={card.liked} - followed={card.followed} - tags={card.tags} - privacy={card.privacy} - id={card.id} - /> + ( + [ + <Grid item lg={6} md={4} sm={6} xs={12}> + <NoContent text={props.noContentText} /> </Grid> - ) - } - </React.Fragment> - ] - ) - } - </StyledGrid> - { - props.length > 0 && - <ButtonsAreaColecao - sliceLength={props.sliceArr.length} - length={props.length} - showMore={() => props.showMore()} - showAll={() => props.showAll()} - /> + ] + ) + : + ( + [ + <React.Fragment> + { + props.sliceArr.map((card) => + <Grid item md={3} xs={12} key={card.id}> + <CollectionCardFunction + name={card.name} + tags={card.tags} + rating={card.review_average} + id={card.id} + author={card.owner.name} + description={card.description} + thumbnails={card.items_thumbnails} + avatar={card.owner.avatar} + likeCount={card.likes_count} + followed={card.followed} + liked={card.liked} + collections={card.collection_items} + authorID={card.owner.id} + /> + </Grid> + ) + } + </React.Fragment> + ] + ) } + </StyledGrid> + { + props.length > 0 && + <ButtonsAreaColecao + sliceLength={props.sliceArr.length} + length={props.length} + showMore={() => props.showMore()} + showAll={() => props.showAll()} + /> + } </WhiteContainer> ) } diff --git a/src/Components/TabPanels/UserPageTabs/PanelCuradoria.js b/src/Components/TabPanels/UserPageTabs/PanelCuradoria.js index 4e58cd17c41842a5f32d4306488e57410ead2529..796bee8acd0ae4dcf601ff3ebcbd1253199e80cd 100644 --- a/src/Components/TabPanels/UserPageTabs/PanelCuradoria.js +++ b/src/Components/TabPanels/UserPageTabs/PanelCuradoria.js @@ -17,11 +17,9 @@ You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ import React, {useState, useEffect} from 'react' -import styled from 'styled-components' -import axios from 'axios' -import {apiUrl} from '../../../env'; import LoadingSpinner from '../../LoadingSpinner.js' import TemplateCuradoria from '../PanelComponents/TemplateCuradoria.js' +import {getRequest} from '../../HelperFunctions/getAxiosConfig' export default function TabPanelCuradoria (props) { const [loading, handleLoading] = useState(true) @@ -36,19 +34,15 @@ export default function TabPanelCuradoria (props) { const showAllSubmissions = () => {setSubmissionsSlice(submissions)} + function handleSuccess (data) { + handleLoading(false) + setSubmissions(data) + setSubmissionsSlice(data.slice(0,4)) + } useEffect( () => { - axios.get( (`${apiUrl}/users/` + props.id + '/submissions?offset=0&status=submitted'), props.config) - .then(response => { - console.log(response) - if (response.headers['access-token']) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - - handleLoading(false) - setSubmissions(response.data) - setSubmissionsSlice(response.data.slice(0,4)) + const url = `/users/${props.id}/submissions?offset=0&status=submitted` - }, error => {console.log('error while running ComponentDidMout on TabPanelCuradoria')}) + getRequest(url, handleSuccess, (error) => {console.log(error)}) }, []) return ( diff --git a/src/Components/TabPanels/UserPageTabs/PanelEditarPerfil.js b/src/Components/TabPanels/UserPageTabs/PanelEditarPerfil.js index 07a5751e3a40ddb7942c8a20ea412a4b97bbf3d5..ce61ebca4117fedbbce05de52d8133c7fc6293ef 100644 --- a/src/Components/TabPanels/UserPageTabs/PanelEditarPerfil.js +++ b/src/Components/TabPanels/UserPageTabs/PanelEditarPerfil.js @@ -25,12 +25,13 @@ import IconButton from '@material-ui/core/IconButton'; import PhotoCamera from '@material-ui/icons/PhotoCamera'; import Tooltip from '@material-ui/core/Tooltip'; import FormInput from "../../FormInput.js" -import ValidateUserInput from '../../FormValidationFunction.js' +import ValidateUserInput from '../../HelperFunctions/FormValidationFunction.js' import {apiDomain} from '../../../env.js' - +import ModalAlterarCover from '../../ModalAlterarCover/ModalAlterarCover.js' export default function TabPanelEditarPerfil (props) { - const {state, dispatch} = useContext(Store) + // eslint-disable-next-line + const {state} = useContext(Store) const [hoverAlterarFoto, handleAlterarFoto] = React.useState(false) const [formNome, setNome] = useState({ @@ -47,9 +48,16 @@ export default function TabPanelEditarPerfil (props) { handleAlterarFoto(!hoverAlterarFoto) } + const [tempCover, setTempCover] = useState('') + + const [open, toggleOpen] = useState(false) + const controlModal = () => {toggleOpen(!open)} + const updateCover = (selectorFiles) => { - console.log(selectorFiles) - console.log(selectorFiles[0].name) + const objectURL = URL.createObjectURL(selectorFiles[0]) + console.log(objectURL) + setTempCover(objectURL) + controlModal() } const handleChange = (e, type) => { @@ -61,14 +69,14 @@ export default function TabPanelEditarPerfil (props) { key : flag, value : userInput }) - console.log(formNome) + } else if (type === 'aboutMe') { setAboutMe({...formAboutMe, key : flag, value : userInput, }) - console.log(formAboutMe) + } } @@ -86,80 +94,88 @@ export default function TabPanelEditarPerfil (props) { const handleSubmit = (e) => { e.preventDefault() - const info = {nome : formNome.value, aboutMe : formAboutMe.value} + const info = {user : {name : formNome.value, description : formAboutMe.value, email : sessionStorage.getItem('@portalmec/uid')}} const flagNome = formNome.key const flagAboutMe = formAboutMe.key if (!(flagNome || flagAboutMe)) { - console.log(info) + props.updateUserInfo(info) limpaCamposForm() } } return ( - <div className="card-config"> - <h1 style={{fontWeight:"300"}}>Editar Perfil </h1> - <div className='content-div'> - <div style={{padding:"0", display:"flex", flexDirection:"column"}}> - <HeaderContainer> - <div style={{position:"relative", height:"100%"}}> - <img src={`${apiDomain}` + state.currentUser.userCover} alt="user cover avatar" style={{width:"100%", height:"100%", objectFit:"cover"}}/> - <input accept="image/*" style = {{display:"none"}} id="icon-button-file" type="file" onChange={(e) => updateCover(e.target.files)}/> - <label htmlFor="icon-button-file"> - <Tooltip title={<span style={{fontSize:"14px", overflow:"hidden", transition:"all .5s ease"}}>ALTERAR CAPA</span>} placement="left"> - <IconButton style={{position:"absolute",right:"0",top:"0",color:"#fff"}}color="primary" aria-label="upload picture" component="span"> - <PhotoCamera /> - </IconButton> - </Tooltip> - </label> - </div> - <ProfileAvatarDiv onMouseEnter={handleHoverAlterarFoto} onMouseLeave={handleHoverAlterarFoto}> - <img src={`${apiDomain}` + state.currentUser.userAvatar} alt = "user avatar" style={{border:"0", verticalAlign:"middle"}}/> - <ChangeAvatarDiv style={ {display : hoverAlterarFoto ? 'flex' : 'none'}}> - <span>Alterar Foto</span> - </ChangeAvatarDiv> - </ProfileAvatarDiv> - </HeaderContainer> - <br/> - <br/> - <br/> - <br/> - </div> + <React.Fragment> + <ModalAlterarCover + open = {open} + handleClose={controlModal} + cover={tempCover} + id={state.currentUser.id} + /> + <div className="card-config"> + <h1 style={{fontWeight:"300"}}>Editar Perfil </h1> + <div className='content-div'> + <div style={{padding:"0", display:"flex", flexDirection:"column"}}> + <HeaderContainer> + <div style={{position:"relative", height:"100%"}}> + <img src={`${apiDomain}` + state.currentUser.cover} alt="user cover avatar" style={{width:"100%", height:"100%", objectFit:"cover"}}/> + <input accept="image/*" style = {{display:"none"}} id="icon-button-file" type="file" onChange={(e) => updateCover(e.target.files)}/> + <label htmlFor="icon-button-file"> + <Tooltip title={<span style={{fontSize:"14px", overflow:"hidden", transition:"all .5s ease"}}>ALTERAR CAPA</span>} placement="left"> + <IconButton style={{position:"absolute",right:"0",top:"0",color:"#fff"}}color="primary" aria-label="upload picture" component="span"> + <PhotoCamera /> + </IconButton> + </Tooltip> + </label> + </div> + <ProfileAvatarDiv onMouseEnter={handleHoverAlterarFoto} onMouseLeave={handleHoverAlterarFoto}> + <img src={`${apiDomain}` + state.currentUser.avatar} alt = "user avatar" style={{border:"0", verticalAlign:"middle"}}/> + <ChangeAvatarDiv style={ {display : hoverAlterarFoto ? 'flex' : 'none'}}> + <span>Alterar Foto</span> + </ChangeAvatarDiv> + </ProfileAvatarDiv> + </HeaderContainer> + <br/> + <br/> + <br/> + <br/> + </div> - <div style={{paddingTop:"90px"}}> - <div style={{display:"flex", flexDirection:"row"}}> - <form onSubmit={e => handleSubmit(e)}> - <FormInput - inputType={"text"} - name={"Nome Completo"} - value={formNome.value} - placeholder={"Nome Completo"} - handleChange={e => handleChange(e, 'username')} - required={true} - error={formNome.key} - /> - <FormInput - inputType={"text"} - name={"Sobre Mim"} - value={formAboutMe.value} - multi = {true} - rows="3" - rowsMax = "3" - error={formAboutMe.key} - placeholder={"Sobre Mim"} - handleChange={e => handleChange(e, 'aboutMe')} - required={false} - help = {formAboutMe.value.length + '/160'} - /> - </form> + <div style={{paddingTop:"90px"}}> + <div style={{display:"flex", flexDirection:"row"}}> + <form onSubmit={e => handleSubmit(e)}> + <FormInput + inputType={"text"} + name={"Nome Completo"} + value={formNome.value} + placeholder={"Nome Completo"} + handleChange={e => handleChange(e, 'username')} + required={true} + error={formNome.key} + /> + <FormInput + inputType={"text"} + name={"Sobre Mim"} + value={formAboutMe.value} + multi = {true} + rows="3" + rowsMax = "3" + error={formAboutMe.key} + placeholder={"Sobre Mim"} + handleChange={e => handleChange(e, 'aboutMe')} + required={false} + help = {formAboutMe.value.length + '/160'} + /> + </form> + </div> + <ButtonsDiv> + <Link to="perfil" ><ButtonCancelar ><span>CANCELAR</span></ButtonCancelar></Link> + <ButtonConfirmar onClick={e => handleSubmit(e)}><span>SALVAR ALTERAÇÕES</span></ButtonConfirmar> + </ButtonsDiv> </div> - <ButtonsDiv> - <Link to="perfil" ><ButtonCancelar ><span>CANCELAR</span></ButtonCancelar></Link> - <ButtonConfirmar onClick={e => handleSubmit(e)}><span>SALVAR ALTERAÇÕES</span></ButtonConfirmar> - </ButtonsDiv> - </div> - </div > - </div> + </div > + </div> + </React.Fragment> ) } diff --git a/src/Components/TabPanels/UserPageTabs/PanelFavoritos.js b/src/Components/TabPanels/UserPageTabs/PanelFavoritos.js index 838382a372d38a0bbac55a335b4e7a7418403f34..4edaf7482aefccfad045c1a43ed26acdcf4e15f1 100644 --- a/src/Components/TabPanels/UserPageTabs/PanelFavoritos.js +++ b/src/Components/TabPanels/UserPageTabs/PanelFavoritos.js @@ -16,12 +16,11 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useContext, useState, useEffect} from 'react' -import axios from 'axios' -import {apiUrl} from '../../../env'; +import React, {useState, useEffect} from 'react' import LoadingSpinner from '../../LoadingSpinner.js' import Template from '../PanelComponents/TemplateRecurso.js' import PanelTemplateColecao from '../PanelComponents/TemplateColecao.js' +import {fetchAllRequest} from '../../HelperFunctions/getAxiosConfig' export default function TabPanelFavoritos (props) { const [loading, handleLoading] = useState(true) @@ -32,29 +31,21 @@ export default function TabPanelFavoritos (props) { const [likedCollections, setlikedCollections] = useState([]) const [likedCollectionsSlice, setlikedCollectionsSlice] = useState([]) + function handleSuccess (responseArr) { + setlikedLearnObjs(responseArr[0]) + setlikedLearnObjsSlice(responseArr[0].slice(0,4)) + + setlikedCollections(responseArr[1]) + setlikedCollectionsSlice(responseArr[1].slice(0,4)) + + handleLoading(false) + } + useEffect( () => { - axios.all([ - axios.get((`${apiUrl}/users/` + props.id + '/learning_objects/liked'), props.config), - axios.get((`${apiUrl}/users/` + props.id + '/collections/liked'), props.config), - ]) - .then( (responseArr) => { - console.log('responseArr favoritos: ', responseArr) - if (responseArr[0].headers['access-token']) { - sessionStorage.setItem('@portalmec/accessToken', responseArr[0].headers['access-token']) - } - setlikedLearnObjs(responseArr[0].data) - setlikedLearnObjsSlice(responseArr[0].data.slice(0,4)) - - setlikedCollections(responseArr[1].data) - setlikedCollectionsSlice(responseArr[1].data.slice(0,4)) - - handleLoading(false) - }, - (error) => { - handleLoading(false) - console.log('error while running axios all') - } - ) + const urls = [ `/users/${props.id}/learning_objects/liked`, `/users/${props.id}/collections/liked`] + + fetchAllRequest(urls, handleSuccess, (error) => {console.log(error)}) + }, []) const showMoreLikedLearnObj = () => { diff --git a/src/Components/TabPanels/UserPageTabs/PanelGerenciarConta.js b/src/Components/TabPanels/UserPageTabs/PanelGerenciarConta.js index ee09ebe4b676c6ef8cff4013bbe67d82cbd38ef7..0207eb9f2bfe9a7002cb841581fef44b0dab2e41 100644 --- a/src/Components/TabPanels/UserPageTabs/PanelGerenciarConta.js +++ b/src/Components/TabPanels/UserPageTabs/PanelGerenciarConta.js @@ -18,11 +18,11 @@ along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/> import React, {useState} from 'react' import Paper from '@material-ui/core/Paper'; -import Button from '@material-ui/core/Button'; import FormInput from "../../FormInput.js" import {CompletarCadastroButton} from './PanelSolicitarContaProfessor.js' import {ButtonCancelar} from './PanelEditarPerfil.js' -import ValidateUserInput from '../../FormValidationFunction.js' +import ValidateUserInput from '../../HelperFunctions/FormValidationFunction.js' +import ModalExcluirConta from './ModalExcluirConta.js' export default function TabPanelGerenciarConta (props) { const [senhaAtual, setSenhaAtual] = useState( @@ -58,21 +58,18 @@ export default function TabPanelGerenciarConta (props) { key : flag, value : userInput }) - console.log(senhaAtual) } else if(type === 'novaSenha') { setNovaSenha({...novaSenha, key : flag, value : userInput }) - console.log(novaSenha) } else if (type === 'confirmacao'){ setNovaSenhaConfirmacao({...novaSenhaConfirmacao, key : flag, value : userInput }) - console.log(novaSenhaConfirmacao) } } @@ -85,7 +82,6 @@ export default function TabPanelGerenciarConta (props) { value : userInput }) - console.log(novoEmail) } const limpaCamposForm = () => { @@ -109,25 +105,24 @@ export default function TabPanelGerenciarConta (props) { e.preventDefault() if (type === 'senha'){ - if (senhaAtual.value === localStorage.getItem("@portalmec/senha")) { - const login = {senhaAtual : senhaAtual.value, novaSenha : novaSenha.value, novaSenhaConfirmacao : novaSenhaConfirmacao.value} - - if (!(senhaAtual.key || novaSenha.key || novaSenhaConfirmacao.key)) { - console.log(login) - limpaCamposForm() - props.handleSnackbar() - } - } - else { - console.log(localStorage.getItem("@portalmec/senha"), senhaAtual.value) + if (!(senhaAtual.key || novaSenha.key || novaSenhaConfirmacao.key)) { + const info = {user : {password : novaSenha.value}} + props.updateUserPassword(info) + + limpaCamposForm() } } else { - console.log(novoEmail.value) + const info = {user : {email : novoEmail.value}} + + props.updateUserEmail(info) + } } + const [modalExcluir, setModalExcluir] = useState(false) + return ( <> <Paper elevation={3} style= {{width:"100%"}}> @@ -155,7 +150,7 @@ export default function TabPanelGerenciarConta (props) { handleChange={e => handleChangeSenha(e, 'novaSenha')} required={true} error={novaSenha.key} - help={ novaSenha.key ? (novaSenha.value.length == 0 ? "Faltou definir uma nova senha" : "A senha precisa ter no mínimo 8 caracteres.") : ""} + help={ novaSenha.key ? (novaSenha.value.length === 0 ? "Faltou definir uma nova senha" : "A senha precisa ter no mínimo 8 caracteres.") : ""} /> <FormInput inputType={"password"} @@ -210,7 +205,8 @@ export default function TabPanelGerenciarConta (props) { <span style={{margin:"0", display:"flex", justifyContent:"flex-start"}}>Antes de excluir a sua conta, saiba que ela será removida permanentemente.</span> </div> <div style={{margin:"0", display:"flex", justifyContent:"flex-start"}}> - <ButtonCancelar style={{color:'#eb4034'}}>EXCLUIR CONTA</ButtonCancelar> + <ModalExcluirConta open={modalExcluir} handleClose={() => {setModalExcluir(false)}}/> + <ButtonCancelar style={{color:'#eb4034'}} onClick={() => {setModalExcluir(true)}}>EXCLUIR CONTA</ButtonCancelar> </div> </div> </div> diff --git a/src/Components/TabPanels/UserPageTabs/PanelMeusRecursos.js b/src/Components/TabPanels/UserPageTabs/PanelMeusRecursos.js index 3d9c93d09707c27216f21b79fefc1ba8567b7d48..05668209a684f2c82ba2cadf6f7bd53ceb5da893 100644 --- a/src/Components/TabPanels/UserPageTabs/PanelMeusRecursos.js +++ b/src/Components/TabPanels/UserPageTabs/PanelMeusRecursos.js @@ -17,11 +17,10 @@ You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ import React, {useState, useEffect} from 'react' -import axios from 'axios' -import {apiUrl} from '../../../env'; import LoadingSpinner from '../../LoadingSpinner.js' import Template from '../PanelComponents/TemplateRecurso.js' import TemplateCuradoria from '../PanelComponents/TemplateCuradoria.js' +import {fetchAllRequest} from '../../HelperFunctions/getAxiosConfig' export default function TabPanelAtividades (props) { const [loading, handleLoading] = useState(true) @@ -35,34 +34,27 @@ export default function TabPanelAtividades (props) { const [curating, setCurating] = useState([]); const [curatingSlice, setCuratingSlice] = useState([]) + function handleSuccess (responseArr) { + setLearningObjects(responseArr[0]) + setLearningObjectsSlice(responseArr[0].slice(0, 4)) + + setDrafts(responseArr[1]) + setDraftsSlice(responseArr[1].slice(0, 4)) + + setCurating(responseArr[2]) + setCuratingSlice(responseArr[2].slice(0, 4)) + + handleLoading(false) + } + useEffect( () => { - axios.all([ - axios.get((`${apiUrl}/users/` + props.id + '/learning_objects'), props.config), - axios.get((`${apiUrl}/users/` + props.id + '/drafts'), props.config), - axios.get((`${apiUrl}/users/` + props.id + '/submissions?status=submitted'), props.config) - ]) - .then( (responseArr) => { - console.log('responseArr Meus recursos: ', responseArr) - if (responseArr[0].headers['access-token']) { - sessionStorage.setItem('@portalmec/accessToken', responseArr[0].headers['access-token']) - } - - setLearningObjects(responseArr[0].data) - setLearningObjectsSlice(responseArr[0].data.slice(0, 4)) - - setDrafts(responseArr[1].data) - setDraftsSlice(responseArr[1].data.slice(0, 4)) - - setCurating(responseArr[2].data) - setCuratingSlice(responseArr[2].data.slice(0, 4)) - - handleLoading(false) - }, - (error) => { - handleLoading(false) - console.log('error while running axios all') - } - ) + const urls = [ + `/users/${props.id}/learning_objects`, + `/users/${props.id}/drafts`, + `/users/${props.id}/submissions?status=submitted` + ] + + fetchAllRequest(urls, handleSuccess, (error) => {console.log(error)}) }, []) const showMoreLearnObj = () => { diff --git a/src/Components/TabPanels/UserPageTabs/PanelRede.js b/src/Components/TabPanels/UserPageTabs/PanelRede.js index f6d349b9ed274569a5bb33190618680f9c764e56..fdebcbf9f4f2f85af5f39e26046c9af2cc442e71 100644 --- a/src/Components/TabPanels/UserPageTabs/PanelRede.js +++ b/src/Components/TabPanels/UserPageTabs/PanelRede.js @@ -16,12 +16,11 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useContext, useState, useEffect} from 'react' -import axios from 'axios' -import {apiUrl, apiDomain} from '../../../env'; +import React, {useState, useEffect} from 'react' import LoadingSpinner from '../../LoadingSpinner.js' import ContainerRedeVazia from './ContainerRedeVazia.js' import PanelTemplateRede from '../PanelComponents/TemplateRede.js' +import {fetchAllRequest} from '../../HelperFunctions/getAxiosConfig' export default function TabPanelRede (props) { const [loading, handleLoading] = useState(true) @@ -44,32 +43,25 @@ export default function TabPanelRede (props) { } const showAllFollowers = () => {setFollowersSlice(followersList)} + function handleSuccess (responseArr) { + console.log(responseArr) + setFollowing(responseArr[0]) + setFollowingSlice(responseArr[0].slice(0,4)) + + + setFollowers(responseArr[1]) + setFollowersSlice(responseArr[1].slice(0,4)) + + handleLoading(false) + } useEffect( () => { - axios.all([ - axios.get((`${apiUrl}/users/` + props.id + '/following/User'), props.config), - axios.get((`${apiUrl}/users/` + props.id + '/followers'), props.config) - ]) - .then( (responseArr) => { - console.log('responseArr Rede: ', responseArr) - if (responseArr[0].headers['access-token']) { - sessionStorage.setItem('@portalmec/accessToken', responseArr[0].headers['access-token']) - } - - setFollowing(responseArr[0].data) - setFollowingSlice(responseArr[0].data.slice(0,4)) - - - setFollowers(responseArr[1].data) - setFollowersSlice(responseArr[1].data.slice(0,4)) - - handleLoading(false) - }, - (error) => { - handleLoading(false) - console.log('error while running axios all') - } - ) + const urls = [ + `/users/${props.id}/following/User`, + `/users/${props.id}/followers` + ] + + fetchAllRequest(urls, handleSuccess, (error) => {console.log(error)}) }, []) return ( @@ -86,7 +78,7 @@ export default function TabPanelRede (props) { [ <> { - followingList.length == 0 && followersList.length == 0 ? + followingList.length === 0 && followersList.length === 0 ? ( [ <> @@ -96,10 +88,9 @@ export default function TabPanelRede (props) { ) : ( - [ <React.Fragment> <PanelTemplateRede - title={followersList.length == 1 ? "Seguidor" : "Seguidores"} + title={followersList.length === 1 ? "Seguidor" : "Seguidores"} length={followersList.length} sliceArr={followersSlice} showMore={showMoreFollowers} @@ -119,7 +110,6 @@ export default function TabPanelRede (props) { /> </React.Fragment> - ] ) } </> diff --git a/src/Components/TabPanels/UserPageTabs/PanelSolicitarContaProfessor.js b/src/Components/TabPanels/UserPageTabs/PanelSolicitarContaProfessor.js index 83f116f0c9d93cde0edc84f369ad3769c95b5830..3e0fe1c7a7382116d02fbab3aeb0c44423393605 100644 --- a/src/Components/TabPanels/UserPageTabs/PanelSolicitarContaProfessor.js +++ b/src/Components/TabPanels/UserPageTabs/PanelSolicitarContaProfessor.js @@ -26,6 +26,7 @@ import Button from '@material-ui/core/Button'; //Professor em análise (submitter_request = requested) //Professor aceito (submitter_request = accepted) export default function TabPanelSolicitarContaProfessor (props) { + // eslint-disable-next-line const {state, dispatch} = useContext(Store) return ( @@ -34,7 +35,6 @@ export default function TabPanelSolicitarContaProfessor (props) { { state.currentUser.submitter_request === 'default' || state.currentUser.submitter_request === 'rejected' ? ( - [ <div style={{paddingLeft:"100px", paddingRight:"101px"}}> <ImageDiv/> <StyledH2>Você é professor(a) da educação básica e gostaria de colaborar com a Plataforma?</StyledH2> @@ -47,28 +47,21 @@ export default function TabPanelSolicitarContaProfessor (props) { </CompletarCadastroButton> </div> </div> - ] ) : ( - [ <> { state.currentUser.submitter_request === 'requested' ? ( - [ <span>Requested</span> - ] ) : ( - [ <span>Professor</span> - ] ) } </> - ] ) } </div> diff --git a/src/Components/TermsPageContent.js b/src/Components/TermsPageContent.js index 25b597cd86b1d2f5d62f3875c00966189b823731..918e040b626542c98ed6ecd83c739ac7d199ec0b 100644 --- a/src/Components/TermsPageContent.js +++ b/src/Components/TermsPageContent.js @@ -1,16 +1,6 @@ import React from 'react'; import Typography from '@material-ui/core/Typography'; import CardContent from '@material-ui/core/CardContent'; -import styled from 'styled-components' - -const h3Styled = styled.h3` - font-size: 24px; - align-self: center; -` - -const h4Styled = styled.h4` - font-size: 24px; -` export default function TermsPageContent () { return ( diff --git a/src/Components/TopicCard.js b/src/Components/TopicCard.js new file mode 100644 index 0000000000000000000000000000000000000000..7a1e0e0aa094982d0c03aae4958ddf85c7f0a159 --- /dev/null +++ b/src/Components/TopicCard.js @@ -0,0 +1,74 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + +import React from 'react'; +import Card from '@material-ui/core/Card'; +import CardContent from '@material-ui/core/CardContent'; +import CardActions from '@material-ui/core/CardActions'; +import Typography from '@material-ui/core/Typography'; +import styled from 'styled-components'; +import Button from '@material-ui/core/Button'; +import { Link } from 'react-router-dom'; + +export default function MaterialCard(props) { + console.log(props); + const thumb = require(`../../public/${props.topic.img}`) + + return ( + <Card style={{ maxHeight: "100%", maxWidth: "300px" }}> + <img style={{ maxHeight: "100%", maxWidth: "100%" }} src={thumb} alt="thumbnail do recurso" /> + <CardContent style={{ height: "50px" }}> + <Title> + <BoldTitle> + {props.topic.pre_title} + </BoldTitle> + {props.topic.title} + </Title> + </CardContent> + <CardActions style={{ borderTop: "1px solid #e5e5e5", justifyContent: "center" }}> + <StyledLink to={"topico?colecao=" + props.colecao_id + "&topico=" + props.topic.id}> + <Button + color="secondary" + > + Ver módulos + </Button> + </StyledLink> + </CardActions> + </Card > + ) +} + +const Title = styled(Typography)` + font-weight: 500; + color: rgb(102, 102, 102); + font-size: 0.9em; + margin-left: 10px; + margin-right: 10px; + + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; +` +const BoldTitle = styled.span` + font-weight: bold; +` +const StyledLink = styled(Link)` + text-decoration: none !important; + color: inherit !important; +` \ No newline at end of file diff --git a/src/Components/TopicFooter.js b/src/Components/TopicFooter.js new file mode 100644 index 0000000000000000000000000000000000000000..c6ce8ea42ddf97ec278bc6cd63e779b4cd28ec5e --- /dev/null +++ b/src/Components/TopicFooter.js @@ -0,0 +1,59 @@ +import React from 'react'; +import styled from 'styled-components' +import Grid from '@material-ui/core/Grid'; + +export default function TopicFooter(props) { + return ( + <Container> + <Wrapper> + <Grid + container + direction="row" + justify="center" + alignItems="center" + > + <Grid item> + <FormationMaterialImage src={require(`../../public/${props.src}`)}/> + </Grid> + <Grid item> + <Text> + Este {props.topic_name} faz parte do Material de Formação: + <br /> + <strong>{props.colecao_name}</strong> + </Text> + </Grid> + </Grid> + </Wrapper> + </Container> + ); +} + +const Container=styled.div` + margin-top: 15px; + background-color: #e81f4f; + height: auto; + padding: 0; +` +const FormationMaterialImage=styled.img` + width: 300px; + margin-right: 20px; +` +const Text=styled.h2` + font-weight: 100; + text-align: center; + color: #fff; +` +const Wrapper=styled.div` + margin-right : auto; + margin-left : auto; + + @media screen and (max-width: 768px) { + width : 100% !important; + } + @media screen and (min-width: 992px) { + width : 770px; + } + @media screen and (min-width: 1200px) { + width : 970px !important; + } +` diff --git a/src/Components/TopicList.js b/src/Components/TopicList.js new file mode 100644 index 0000000000000000000000000000000000000000..e965adad1b530fbf96d090fa028b1fc83ebad01a --- /dev/null +++ b/src/Components/TopicList.js @@ -0,0 +1,81 @@ +import React, { useState } from 'react'; +import styled from 'styled-components' +import Grid from '@material-ui/core/Grid'; +import Fab from '@material-ui/core/Fab'; +import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; +import ExpandLessIcon from '@material-ui/icons/ExpandLess'; +import TopicCard from './TopicCard.js'; + +export default function TopicList(props) { + const [expanded, setExpanded] = useState(false); + + const handleFabClick = () => { + setExpanded(!expanded); + } + + return ( + <Wrapper> + <Title>Módulos</Title> + <Grid + container + spacing={3} + justify="center" + alignItems="center" + > + {props.topicos.slice(0, (expanded ? -1 : 5)).map((t, index) => { + return ( + <Grid item key={index} md={3}> + <TopicCard topic={t} colecao_id={props.colecao_id} /> + </Grid> + ); + }) + } + </Grid> + {props.topicos.length > 5 ? + <Grid container + direction="column" + justify="flex-start" + alignItems="center" + > + <Grid item> + <Fab size="medium" color="secondary" aria-label="edit" onClick={handleFabClick}> + {expanded ? <ExpandLessIcon /> : <ExpandMoreIcon />} + </Fab> + </Grid> + <Grid item> + <FabText> + {expanded ? "VER MENOS" : "VER TODOS OS MÓDULOS"} + </FabText> + </Grid> + </Grid> + : <div></div> + } + </Wrapper> + ); +} + +const FabText = styled.span` + color: #666; + font-weight: 900; + line-height: 2em; +` +const Title = styled.h1` + font-weight: 100; + margin-left: 30px; + color: rgb(102, 102, 102); +` +const Wrapper = styled.div` + margin-right : auto; + margin-left : auto; + margin-bottom: 30px; + + @media screen and (max-width: 768px) { + width : 100% !important; + } + @media screen and (min-width: 992px) { + width : 770px; + } + @media screen and (min-width: 1200px) { + width : 970px !important; + } +` diff --git a/src/Components/UploadPageComponents/ButtonsDiv.js b/src/Components/UploadPageComponents/ButtonsDiv.js index 8add164e3a46bcef35c155d223f788a682af6c5f..b6aaaa3c829fa41698743a5fe720b9fd82c06148 100644 --- a/src/Components/UploadPageComponents/ButtonsDiv.js +++ b/src/Components/UploadPageComponents/ButtonsDiv.js @@ -18,9 +18,10 @@ along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/> import React, {useState} from 'react' import ModalCancelar from './ModalCancelar.js' -import { GreyButton, OrangeButton, StyledDiv } from './StyledComponents'; +import { GreyButton, OrangeButton } from './StyledComponents'; import Grid from '@material-ui/core/Grid'; import {Redirect} from 'react-router-dom' + export default function ButtonsDiv (props) { const [modalCancelar, toggleModalCancelar] = useState(false) const [redirectTrue, toggleRedirect] = useState(false) diff --git a/src/Components/UploadPageComponents/ChooseLinkSection.js b/src/Components/UploadPageComponents/ChooseLinkSection.js index ef282d1de8b75c8d3b1372fc3fdd38f5aeb6198d..52a14ae21b18fb4c190effa4ba4d9ecfaca6d1f0 100644 --- a/src/Components/UploadPageComponents/ChooseLinkSection.js +++ b/src/Components/UploadPageComponents/ChooseLinkSection.js @@ -17,10 +17,6 @@ You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ import React, {useState} from 'react' -import styled from 'styled-components' -import LinkIcon from '../../img/link_icon.svg' -import { Button } from '@material-ui/core'; -import TextField from '@material-ui/core/TextField'; import UndoIcon from '@material-ui/icons/Undo'; import {WrapperBox, StyledTextField, BlueButton, GrayButton} from './StyledComponents.js' @@ -30,6 +26,7 @@ export default function ChooseLink (props) { const handleLink = (e) => { let userInput = e.target.value const urlRegex = new RegExp( + // eslint-disable-next-line "(?:(?:(?:https?|ftp):\/\/))(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})*(?:[/?#]\S*)?", "i" ) let flag = !(urlRegex.test(userInput)) diff --git a/src/Components/UploadPageComponents/DragAndDrop.tsx b/src/Components/UploadPageComponents/DragAndDrop.tsx deleted file mode 100644 index d416b22257648c2c500ef0cb85150e7acfacae20..0000000000000000000000000000000000000000 --- a/src/Components/UploadPageComponents/DragAndDrop.tsx +++ /dev/null @@ -1,153 +0,0 @@ -/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre -Departamento de Informatica - Universidade Federal do Parana - -This file is part of Plataforma Integrada MEC. - -Plataforma Integrada MEC is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -Plataforma Integrada MEC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ - -import React, {useState, useEffect} from 'react' -import CloudUploadIcon from '@material-ui/icons/CloudUpload'; -import {DottedBox, BlueButton} from './StyledComponents.js'; -import FileToUpload from './FileToUpload' -import {getAxiosConfig} from '../HelperFunctions/getAxiosConfig.js' -import AddAPhotoIcon from '@material-ui/icons/AddAPhoto'; - -type Props = { - draftID : string; -} - -const UploadMediaComponent: React.FC<Props> = ({draftID, children}) => { - const [filesToUpload, setFilesToUpload] = useState<FileToUpload | undefined>(undefined); - - const onFileChange = (e: React.ChangeEvent<HTMLInputElement>) => { - const files: FileList | null = e.target.files; - if(!files) return; - - let fileToUpload: FileToUpload = new FileToUpload(files[0], files[0].name, draftID); - - setFilesToUpload(fileToUpload); - if (fileToUpload != undefined){ - console.log(fileToUpload.uploadFile()) - - } - }; - - return ( - <div className="upload-container"> - <h2 className="upload-title">File Uploader</h2> - <div className="upload-form"> - <form id="file_upload"> - <DottedBox - - > - <AddAPhotoIcon className="icon"/> - <input - type="file" - onChange = {onFileChange} - id="upload-file-thumbnail" - style={{display : "none"}} - /> - <BlueButton> - <label htmlFor="upload-file-thumbnail" style={{width : "inherit", cursor : "pointer"}}> - ESCOLHER IMAGEM - </label> - </BlueButton> - <span style={{marginTop : "6px"}}>Ou arrastar e soltar o arquivo aqui</span> - </DottedBox> - </form> - </div> - </div> - ) -} -UploadMediaComponent.displayName = 'UploadMedia'; -export default UploadMediaComponent; - -{/*<div className="upload-file-select"> - <label htmlFor="file_1">Select files for upload</label> - <input id="file_1" type="file" multiple onChange={onFileChange}/> -</div> - -<div className="upload-file-list"> - {filesToUpload.map((f,i) => <div className="upload-file" key={i}>{f.name} - {f.file.size}bytes</div>)} -</div> - -<div className="upload-submit"> - <input type="submit" value="submit"/> -</div>*/} - -{/* - const [dropDepth, setDropDepth] = useState(0) - const [inDropZone, toggleInDropZone] = useState(false) - const [fileList, setFileList] = useState([]) - - const handleDragEnter = e => { - e.preventDefault(); - e.stopPropagation(); - - setDropDepth(dropDepth + 1) - }; - - const handleDragLeave = e => { - e.preventDefault(); - e.stopPropagation(); - - setDropDepth(dropDepth - 1) - if (dropDepth > 0) - toggleInDropZone(true) - }; - - const handleDragOver = e => { - e.preventDefault(); - e.stopPropagation(); - e.dataTransfer.dropEffect = 'copy'; - toggleInDropZone(true) - }; - - const handleDrop = e => { - e.preventDefault(); - e.stopPropagation(); - let files = [...e.dataTransfer.files] - - if (files && files.length > 0) { - props.acceptFile(files[0]) - } - }; - - const handleUpload = (e, selectorFiles : FileList) => { - e.preventDefault(); - props.acceptFile(selectorFiles[0]) - } - - - <DottedBox - onDrop={e => handleDrop(e)} - onDragOver={e => handleDragOver(e)} - onDragEnter={e => handleDragEnter(e)} - onDragLeave={e => handleDragLeave(e)} - > - <CloudUploadIcon className="icon"/> - <input - type="file" - onChange = {(e) => handleUpload(e, e.target.files)} - id="upload-file" - style={{display : "none"}} - /> - <BlueButton> - <label htmlFor="upload-file" style={{width : "inherit", cursor : "pointer"}}> - ESCOLHER O ARQUIVO - </label> - </BlueButton> - <span style={{marginTop : "6px"}}>Ou arrastar e soltar o arquivo aqui</span> -</DottedBox> - */} diff --git a/src/Components/UploadPageComponents/FileToUpload.ts b/src/Components/UploadPageComponents/FileToUpload.ts index 0fba0fc8204700a5e47bdd98516b8aa474e98133..fddbf404078bdb1eed4d04a666955d63ccdbac87 100644 --- a/src/Components/UploadPageComponents/FileToUpload.ts +++ b/src/Components/UploadPageComponents/FileToUpload.ts @@ -1,3 +1,21 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + export default class FileToUpload { static chunkSize = 262144; readonly request: XMLHttpRequest; diff --git a/src/Components/UploadPageComponents/FileUploadStage.js b/src/Components/UploadPageComponents/FileUploadStage.js index 5419bb3f7ce1dfc0574a3965c32ede36a7fcd425..880ff018ef65d34cdf952b8829dedfd819f647b6 100644 --- a/src/Components/UploadPageComponents/FileUploadStage.js +++ b/src/Components/UploadPageComponents/FileUploadStage.js @@ -21,25 +21,18 @@ import styled from 'styled-components' import {WrapperBox} from './StyledComponents.js' import DoneIcon from '@material-ui/icons/Done'; import DeleteIcon from '@material-ui/icons/Delete'; -import {getAxiosConfig} from '../HelperFunctions/getAxiosConfig.js' -import axios from 'axios' -import {apiUrl} from '../../env'; +import {deleteRequest} from '../HelperFunctions/getAxiosConfig.js' export default function FileUploadStage (props) { const [uploading, toggleUploading] = useState(true) + function handleSuccess (data) { + props.handleNextStage("default") + } const handleDelete = () => { - let config = getAxiosConfig + const url = `/learning_objects/${props.draftID}` - axios.delete( (`${apiUrl}/learning_objects/` + props.draftID), config).then( - (response) => { - console.log(response) - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - props.handleNextStage("default") - }, - (error) => {console.log(error)}) + deleteRequest(url, handleSuccess, (error) => {console.log(error)}) } return ( diff --git a/src/Components/UploadPageComponents/Forms/Autor.js b/src/Components/UploadPageComponents/Forms/Autor.js index c2427708808305757edb1df197161c5909abd9af..30a3535b04fc2f2e4f0790227f4c9f61e8d40bb4 100644 --- a/src/Components/UploadPageComponents/Forms/Autor.js +++ b/src/Components/UploadPageComponents/Forms/Autor.js @@ -21,8 +21,7 @@ import {Store} from '../../../Store.js' import { withStyles } from '@material-ui/core/styles'; import FormControl from '@material-ui/core/FormControl'; -import {StyledTextField, StyledFormLabel, OutroAutorTextField} from '../StyledComponents.js' -import FormHelperText from '@material-ui/core/FormHelperText'; +import { StyledFormLabel, OutroAutorTextField} from '../StyledComponents.js' import RadioGroup from '@material-ui/core/RadioGroup'; import Radio from '@material-ui/core/Radio'; import FormControlLabel from '@material-ui/core/FormControlLabel'; @@ -43,7 +42,7 @@ function Autor (props) { const [outroAutor, setOutroAutor] = useState(props.initialOutroAutor ? props.initialOutroAutor : '') const getAuthor = () => { - return authorValue === "0" ? state.currentUser.username : outroAutor + return authorValue === "0" ? state.currentUser.name : outroAutor } return ( diff --git a/src/Components/UploadPageComponents/Forms/Idioma.js b/src/Components/UploadPageComponents/Forms/Idioma.js index ced59ebd7233165a30cb9dfa6b804633054bb014..7d033a44d9ef18c7ffdd55f5b7894176077d3e7d 100644 --- a/src/Components/UploadPageComponents/Forms/Idioma.js +++ b/src/Components/UploadPageComponents/Forms/Idioma.js @@ -16,12 +16,11 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useState, useEffect} from 'react' +import React, {useState} from 'react' import FormControl from '@material-ui/core/FormControl'; import {StyledFormLabel} from '../StyledComponents.js' import ListItemText from '@material-ui/core/ListItemText'; import Checkbox from '@material-ui/core/Checkbox'; -import Input from '@material-ui/core/Input'; import MenuItem from '@material-ui/core/MenuItem'; import Select from '@material-ui/core/Select'; diff --git a/src/Components/UploadPageComponents/Forms/Keywords.js b/src/Components/UploadPageComponents/Forms/Keywords.js index 238d0b7a42aead95b8f4fcc5778796c05bb7600a..34c7b8ec36103d4eb27f1fbba515f2cd686ffdad 100644 --- a/src/Components/UploadPageComponents/Forms/Keywords.js +++ b/src/Components/UploadPageComponents/Forms/Keywords.js @@ -16,7 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useState, memo, useEffect} from 'react' +import React, {useState, memo} from 'react' import FormControl from '@material-ui/core/FormControl'; import {StyledTextField, StyledFormLabel} from '../StyledComponents.js' import FormHelperText from '@material-ui/core/FormHelperText'; @@ -35,7 +35,7 @@ function Keywords (props) { const handleKeywords = (event) => { let userInput = event.target.value; - if(userInput.indexOf(',') != -1 ) { + if(userInput.indexOf(',') !== -1 ) { if(userInput.length > 1) { handleSetKeywords([...keywords, userInput.split(',')[0]]) } diff --git a/src/Components/UploadPageComponents/Forms/SobreORecurso.js b/src/Components/UploadPageComponents/Forms/SobreORecurso.js index 93ea7daab57031935510a63cf5794039c69fcf6c..ff82f818fac17ad111411b65ba4505dd3215fcc9 100644 --- a/src/Components/UploadPageComponents/Forms/SobreORecurso.js +++ b/src/Components/UploadPageComponents/Forms/SobreORecurso.js @@ -16,7 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useState, memo, useEffect} from 'react' +import React, {useState, memo} from 'react' import FormControl from '@material-ui/core/FormControl'; import {StyledTextField, StyledFormLabel} from '../StyledComponents.js' diff --git a/src/Components/UploadPageComponents/Forms/TipoDeRecurso.js b/src/Components/UploadPageComponents/Forms/TipoDeRecurso.js index 55474c92981e3229868b4b02538a06aa6cd8b9bf..5082742a016e1434fc7b6b1ba13ee25fa5e8e776 100644 --- a/src/Components/UploadPageComponents/Forms/TipoDeRecurso.js +++ b/src/Components/UploadPageComponents/Forms/TipoDeRecurso.js @@ -18,9 +18,8 @@ along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/> import React, {useState, memo} from 'react' import FormControl from '@material-ui/core/FormControl'; -import {StyledRadio, ObjTypeBox, StyledFormLabel} from '../StyledComponents.js' +import {StyledRadio, StyledFormLabel} from '../StyledComponents.js' import RadioGroup from '@material-ui/core/RadioGroup'; -import Radio from '@material-ui/core/Radio'; import FormControlLabel from '@material-ui/core/FormControlLabel'; diff --git a/src/Components/UploadPageComponents/GetIconByName.js b/src/Components/UploadPageComponents/GetIconByName.js index 2d4bb7c6c5fbe268131da5cbbf09acbd9357835c..b5f8e8404126abedb86ef16fac02a25b016c0a71 100644 --- a/src/Components/UploadPageComponents/GetIconByName.js +++ b/src/Components/UploadPageComponents/GetIconByName.js @@ -45,79 +45,54 @@ export function GetSubjectIconByName (subjName) { switch (subjName) { case "Arte": return <Arte className="icon"/> - break; case "Biologia": return <Biologia className="icon"/> - break; case "Ciências da Natureza": return <CienciasNatureza className="icon"/> - break; case "Direitos Humanos": return <DireitosHumanos className="icon"/> - break; case "Educação Ambiental": return <EducacaoAmbiental className="icon"/>; - break; case "Educação do Campo": return <EducacaoCampo className="icon"/>; - break; case "Educação Especial": return <EducacaoEspecial className="icon"/>; - break; case "Educação Física": return <EducacaoFisica className="icon"/>; - break; case "Educação Indígena": return <EducacaoIndigena className="icon"/>; - break; case "Educação Quilombola": return <EducacaoQuilombola className="icon"/>; - break; case "Educação Sexual": return <EducacaoSexual className="icon"/>; - break; case "Ensino Religioso": return <EnsinoReligioso className="icon"/>; - break; case "Filosofia": return <Filosofia className="icon"/>;; - break; case "Física": return <Fisica className="icon"/>; - break; case "Geografia": return <Geografia className="icon"/>; - break; case "História": return <Historia className="icon"/>; - break; case "Informática": return <Informatica className="icon"/>; - break; case "Língua Espanhola": return <LinguaEspanhola className="icon"/>; - break; case "Língua Inglesa": return <LinguaInglesa className="icon"/>; - break; case "Língua Portuguesa": return <LinguaPortuguesa className="icon"/>; - break; case "Matemática": return <Matematica className="icon"/>; - break; case "Outras Línguas": return <OutrasLinguas className="icon"/>; - break; case "Química": return <Quimica className="icon"/>; - break; case "Sociologia": return <Sociologia className="icon"/>; - break; default: return <Outros className="icon"/>; - break; } } @@ -125,43 +100,30 @@ export default function GetIconByName (objName) { switch (objName.toLowerCase()) { case "imagem": return <ImagemIcon className="icon" />; - break; case "mapa": return <MapaIcon className="icon"/>; - break; case "software educacional" : return <SoftwareEducacionalIcon className="icon"/>; - break; case "aplicativo móvel": return <AplicativoMovelIcon className="icon"/>; - break; case "apresentação": return <ApresentacaoIcon className="icon"/>; - break; case "áudio": return <AudioIcon className="icon"/>; - break; case "infográfico": return <InfograficoIcon className="icon"/>; - break; case "jogo": return <JogoIcon className="icon"/>; - break; case "livro digital" : return <LivroDigitalIcon className="icon"/>; - break; case "texto": return <TextoIcon className="icon"/>; - break; case "vídeo": return <VideoIcon className="icon"/>; - break; case "animação": return <AnimacaoIcon className="icon"/>; - break; default: return <OutrosIcon className="icon"/>; - break; } } diff --git a/src/Components/UploadPageComponents/ModalCancelar.js b/src/Components/UploadPageComponents/ModalCancelar.js index 44f17b032ed9e8b67ba0de04fc913c702b8b0db9..9616436b10e683fdb274387b58ff2aed3c8d788b 100644 --- a/src/Components/UploadPageComponents/ModalCancelar.js +++ b/src/Components/UploadPageComponents/ModalCancelar.js @@ -16,45 +16,30 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useState, useEffect} from 'react' +import React from 'react' import { Button } from '@material-ui/core'; import Modal from '@material-ui/core/Modal'; import Backdrop from '@material-ui/core/Backdrop'; import Fade from '@material-ui/core/Fade'; import styled from 'styled-components' -import CloseIcon from '@material-ui/icons/Close'; -import axios from 'axios' -import {apiUrl} from '../../env'; import {Link} from 'react-router-dom' +import {deleteRequest} from '../HelperFunctions/getAxiosConfig.js' export default function ModalCancelar (props) { - const handleDelete = () => { - console.log(props.draftID) - {/*delete the draft*/} - if (props.draftID) { - let config = { - headers : { - 'Accept': 'application/json', - 'Content-Type': 'application/json', - 'Access-Token': sessionStorage.getItem('@portalmec/accessToken'), - 'Client': sessionStorage.getItem('@portalmec/clientToken'), - 'Uid': sessionStorage.getItem('@portalmec/uid'), - } - } - axios.delete( (`${apiUrl}/learning_objects/` + props.draftID), config).then( - (response) => { - console.log(response) - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - }, (error) => {console.log(error)}) - } - {/*close modal*/} + + function handleSuccess (data) { props.handleClose() - {/*change current page to home page*/} console.log('ir pra home') } + const handleDelete = () => { + // {/*delete the draft*/} + if (props.draftID) { + const url = `/learning_objects/${props.draftID}` + + deleteRequest(url, handleSuccess, (error) => {console.log(error)}) + } + } return ( <StyledModal diff --git a/src/Components/UploadPageComponents/PartOne.js b/src/Components/UploadPageComponents/PartOne.js index bd02f792230d6f69971c805b054fc3c137544f29..fbb47cb5b0e325fa01cf5ba7666acd454a398134 100644 --- a/src/Components/UploadPageComponents/PartOne.js +++ b/src/Components/UploadPageComponents/PartOne.js @@ -18,13 +18,7 @@ along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/> import React, {useState, useEffect} from 'react' import Grid from '@material-ui/core/Grid'; -import styled from 'styled-components' -import axios from 'axios' -import {apiUrl, apiDomain} from '../../env'; import ButtonsDiv from './ButtonsDiv.js' -import { makeStyles } from '@material-ui/core/styles'; -import {ObjTypeBox, StyledFormHelperText, OutroAutorTextField, StyledFormLabel, StyledTextField, StyledNativeSelect} from './StyledComponents.js' - import SobreORecurso from './Forms/SobreORecurso.js' import NewTitle from './Forms/NewTitle.js' import Keywords from './Forms/Keywords.js' @@ -32,40 +26,20 @@ import Autor from './Forms/Autor.js' import TipoDeRecurso from './Forms/TipoDeRecurso.js' import Idioma from './Forms/Idioma.js' import {SendInfo} from './SendInfo.js' +import {getRequest} from '../HelperFunctions/getAxiosConfig.js' export default function PartOne (props) { - {/*const [subjects, setSubjects] = useState([])*/} + // {/*const [subjects, setSubjects] = useState([])*/} const [languages, setLanguages] = useState([]) const [objTypes, setObjTypes] = useState([]) + function handleSuccessGetObjTypes (data) { + setObjTypes(data.sort((a, b) => (a.name) > (b.name) ? 1 : -1)) + } useEffect( () => { - {/*get the list of subjects*/} - {/* axios.get(`${apiUrl}/subjects/`).then( - (response) => { - console.log(response.data) - setSubjects(response.data) - }, (error) => { - console.log(error) - } - )*/} - - {/*get the list of object_types*/} - axios.get(`${apiUrl}/object_types/`).then( - (response) => { - setObjTypes(response.data.sort((a, b) => (a.name) > (b.name) ? 1 : -1)) - }, (error) => { - console.log(error) - } - ) - - {/*get the list of languages*/} - axios.get(`${apiUrl}/languages/`).then( - (response) => { - setLanguages(response.data) - }, (error) => { - console.log(error) - } - ) + getRequest(`/object_types/`, handleSuccessGetObjTypes, (error) => {console.log(error)}) + + getRequest(`/languages/`, (data) => {setLanguages(data)}, (error) => {console.log(error)}) }, []) const handleSubmit = () => { diff --git a/src/Components/UploadPageComponents/PartThree.js b/src/Components/UploadPageComponents/PartThree.js index cce31c71977d064486e3f4253e5e9006c6833abd..3b4b6b81ecbda32d0fa721e0ffc059e0c47f4cff 100644 --- a/src/Components/UploadPageComponents/PartThree.js +++ b/src/Components/UploadPageComponents/PartThree.js @@ -20,8 +20,7 @@ import React, {useState, useEffect, useContext} from 'react' import {Store} from '../../Store.js' import Grid from '@material-ui/core/Grid'; import styled from 'styled-components' -import axios from 'axios' -import {apiUrl, apiDomain} from '../../env'; +import {apiDomain} from '../../env'; import Stepper from './Stepper.js' import Rating from '@material-ui/lab/Rating'; import StarBorderIcon from '@material-ui/icons/StarBorder'; @@ -34,12 +33,11 @@ import TranslateIcon from '@material-ui/icons/Translate'; import AssignmentIcon from '@material-ui/icons/Assignment'; import { GrayButton, OrangeButton} from './StyledComponents'; import ModalCancelar from './ModalCancelar.js' -import {getAxiosConfig} from '../HelperFunctions/getAxiosConfig.js' import {getDefaultThumbnail} from '../HelperFunctions/getDefaultThumbnail' +import {getRequest} from '../HelperFunctions/getAxiosConfig.js' export default function PartThree (props) { var moment = require('moment') - const now = moment() const {state} = useContext(Store) const [loading, setLoading] = useState(true) @@ -49,24 +47,22 @@ export default function PartThree (props) { const [description, setDescription] = useState('') const [author, setAuthor] = useState('') + function handleSuccess (data) { + setDraft(data) + /*extract subjects*/ + setSubjects(data.subjects.map((subject)=>(subject.name)).join(', ')) + setTags(data.tags.map(tag => tag.name)) + setDescription(data.description) + setAuthor(data.author) + setLoading(false) + } + useEffect(() => { if (state.currentUser.id !== "") { - const config = getAxiosConfig() - axios.get( (`${apiUrl}/learning_objects/` + props.draftID), config - ).then( (response) => { - console.log(response.data) - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - setDraft(response.data) - - /*extract subjects*/ - setSubjects(response.data.subjects.map((subject)=>(subject.name)).join(', ')) - setTags(response.data.tags.map(tag => tag.name)) - setDescription(response.data.description) - setAuthor(response.data.author) - setLoading(false) - }, (error) => {console.log(error)}) + const url = `/learning_objects/${props.draftID}` + + getRequest(url, handleSuccess, (error) => {console.log(error)}) + } }, [state.currentUser.id]) @@ -74,7 +70,7 @@ export default function PartThree (props) { const [modalCancelar, toggleModalCancelar] = useState(false) const checkAccessLevel = (levelToCheck) => { - if (state.currentUser.id != '') { + if (state.currentUser.id !== '') { return(checkUserRole(levelToCheck)) } } @@ -109,7 +105,7 @@ export default function PartThree (props) { <CaixaContainer> <div> <div className="cabecalho-objeto"> - <img className="img-objeto" + <img alt="" className="img-objeto" src={draft.thumbnail === null ? getDefaultThumbnail(draft.object_type) : apiDomain + draft.thumbnail}/> <div className="texto-objeto"> <h3>{draft.name}</h3> diff --git a/src/Components/UploadPageComponents/PartTwo.js b/src/Components/UploadPageComponents/PartTwo.js index 29374bd7c875625165f5f0a14c02d3284f463539..6ab05cee54ac0f62067fb87aecde4b16e045df1c 100644 --- a/src/Components/UploadPageComponents/PartTwo.js +++ b/src/Components/UploadPageComponents/PartTwo.js @@ -19,8 +19,6 @@ along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/> import React, {useState, useEffect} from 'react' import Grid from '@material-ui/core/Grid'; import styled from 'styled-components' -import axios from 'axios' -import {apiUrl, apiDomain} from '../../env'; import DragAndDropThumbnail from './PartTwoComponents/DragAndDropThumbnail' import EducationalStage from './PartTwoComponents/EducationalStage' import Licenca from './PartTwoComponents/Licenca' @@ -32,9 +30,9 @@ import ButtonsDiv from './ButtonsDiv.js' import SubjectsAndThemes from './PartTwoComponents/SubjectsAndThemes.js' import {SendInfo} from './SendInfo.js' import EditThumbnail from './PartTwoComponents/EditThumbnail.js' -import {getAxiosConfig} from '../HelperFunctions/getAxiosConfig' import DisplayThumbnail from './PartTwoComponents/DisplayThumbnail.js' import CustomCircularProgress from './PartTwoComponents/CustomCircularProgress'; +import {getRequest, putRequest} from '../HelperFunctions/getAxiosConfig.js' export function LoadingDiv () { return ( @@ -49,21 +47,15 @@ export default function PartTwo (props) { const [subjects, setSubjects] = useState([]) const [themes, setThemes] = useState([]) + function handleSuccess (data) { + setSubjects(data.filter(subject => subject.theme === false).sort((a,b) => a.name > b.name ? 1 : -1)) + setThemes(data.filter(subject => subject.theme === true).sort((a,b) => a.name > b.name ? 1 : -1)) + } + useEffect(() => { - axios.get(`${apiUrl}/educational_stages/`).then( - (response) => {console.log(response); - setEduStages(response.data) - }, - (error) => {console.log(error)} - ) - - axios.get(`${apiUrl}/subjects/`).then( - (response) => {console.log(response); - setSubjects(response.data.filter(subject => subject.theme === false).sort((a,b) => a.name > b.name ? 1 : -1)) - setThemes(response.data.filter(subject => subject.theme === true).sort((a,b) => a.name > b.name ? 1 : -1)) - }, - (error) => {console.log(error)} - ) + getRequest(`/educational_stages/`, (data) => {setEduStages(data)}, (error) => {console.log(error)}) + + getRequest(`/subjects/`, handleSuccess, (error) => {console.log(error)}) }, []) @@ -86,23 +78,17 @@ export default function PartTwo (props) { const updateThumb = (newThumbnail) => { setThumbnail(newThumbnail) console.log(thumbnail) - } + const finalizeThumb = () => { setThumbnailStage('uploading') - let config = getAxiosConfig() + + const url = `/learning_objects/${props.draftID}` + let fdThumb = new FormData() fdThumb.set('learning_object[thumbnail]', thumbnail) - axios.put((`${apiUrl}/learning_objects/` + props.draftID), fdThumb, config).then( - (response) => { - setThumbnailStage('done') - console.log(response.data) - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - }, - (error) => {console.log(error)} - ) + + putRequest(url, fdThumb, (data) => {setThumbnailStage('done')}, (error) => {console.log(error)}) } const [thumbnailStage, setThumbnailStage] = useState('default') @@ -111,16 +97,12 @@ export default function PartTwo (props) { switch(thumbnailStage) { case 'uploading': return (<LoadingDiv/>) - break; case 'done': return (<DisplayThumbnail acceptFile={acceptFile} thumbnail={thumbnail}/>) - break; case 'editing': return (<EditThumbnail finalizeThumb={finalizeThumb} tempImgURL={tempUrl} updateThumb={updateThumb}/>) - break; default : return (<DragAndDropThumbnail acceptFile={acceptFile}/>) - break; } } diff --git a/src/Components/UploadPageComponents/PartTwoComponents/CustomCircularProgress.js b/src/Components/UploadPageComponents/PartTwoComponents/CustomCircularProgress.js index 617a8e70b6a022139e4ecd843fa792117a38515c..2164091858560e3cb63f0c43099de40e2606b741 100644 --- a/src/Components/UploadPageComponents/PartTwoComponents/CustomCircularProgress.js +++ b/src/Components/UploadPageComponents/PartTwoComponents/CustomCircularProgress.js @@ -1,3 +1,21 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + import React from 'react'; import { makeStyles } from '@material-ui/core/styles'; import CircularProgress from '@material-ui/core/CircularProgress'; diff --git a/src/Components/UploadPageComponents/PartTwoComponents/DisplayThumbnail.js b/src/Components/UploadPageComponents/PartTwoComponents/DisplayThumbnail.js index cc123a4c47254ea324aa5b6e68df5614e08bd4ac..0c07e151670e4a256ed971abb978dad7b3107c5b 100644 --- a/src/Components/UploadPageComponents/PartTwoComponents/DisplayThumbnail.js +++ b/src/Components/UploadPageComponents/PartTwoComponents/DisplayThumbnail.js @@ -1,3 +1,21 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + import React from 'react' import {StyledFormLabel} from '../StyledComponents.js' import AddAPhotoIcon from '@material-ui/icons/AddAPhoto'; @@ -32,7 +50,7 @@ export default function DisplayThumbnail (props) { <ImagemCarregada container> <Grid item xs={windowWidth > 990 ? 6 : 12}> <div className="img-preview"> - <img src={props.thumbnail}/> + <img alt="" src={props.thumbnail}/> <div className="alterar-imagem"> <input type="file" onChange = {(e) => handleUpload(e, e.target.files)} id="upload-file-thumbnail" style={{display : "none"}} /> diff --git a/src/Components/UploadPageComponents/PartTwoComponents/DragAndDropThumbnail.js b/src/Components/UploadPageComponents/PartTwoComponents/DragAndDropThumbnail.js index f72f957dff64f132f68349fa66249bbbd574a10d..59423e607f7d2395c498a12f7e2a2f6efc5e7e5a 100644 --- a/src/Components/UploadPageComponents/PartTwoComponents/DragAndDropThumbnail.js +++ b/src/Components/UploadPageComponents/PartTwoComponents/DragAndDropThumbnail.js @@ -20,12 +20,12 @@ import React, {useState} from 'react' import {DottedBox, BlueButton} from '../StyledComponents.js'; import AddAPhotoIcon from '@material-ui/icons/AddAPhoto'; import FormControl from '@material-ui/core/FormControl'; -import {StyledTextField, StyledFormLabel, OutroAutorTextField} from '../StyledComponents.js' +import {StyledFormLabel} from '../StyledComponents.js' export default function DragAndDropThumbnail (props) { const [dropDepth, setDropDepth] = useState(0) + // eslint-disable-next-line const [inDropZone, toggleInDropZone] = useState(false) - const [fileList, setFileList] = useState([]) const handleDragEnter = e => { e.preventDefault(); @@ -53,7 +53,6 @@ export default function DragAndDropThumbnail (props) { const handleDrop = e => { e.preventDefault(); e.stopPropagation(); - console.log(files) let files = [...e.dataTransfer.files] if (files && files.length > 0) { props.acceptFile(files) diff --git a/src/Components/UploadPageComponents/PartTwoComponents/EditThumbnail.js b/src/Components/UploadPageComponents/PartTwoComponents/EditThumbnail.js index 35be2ce523737088ba7892dac513b255050d9925..7cce6bf2058f9c6512430053e27d6ed04f479800 100644 --- a/src/Components/UploadPageComponents/PartTwoComponents/EditThumbnail.js +++ b/src/Components/UploadPageComponents/PartTwoComponents/EditThumbnail.js @@ -1,3 +1,21 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + import React, {useState} from 'react' import {StyledFormLabel} from '../StyledComponents.js' import Cropper from '../../Cropper' diff --git a/src/Components/UploadPageComponents/PartTwoComponents/EducationalStage.js b/src/Components/UploadPageComponents/PartTwoComponents/EducationalStage.js index 0935c3aa5a92bed3646f4d1a2e692693543cc12b..96da308ae7eaf9c2eb942033bf707f567649e3ff 100644 --- a/src/Components/UploadPageComponents/PartTwoComponents/EducationalStage.js +++ b/src/Components/UploadPageComponents/PartTwoComponents/EducationalStage.js @@ -16,7 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useState, useEffect} from 'react' +import React, {useState} from 'react' import FormControl from '@material-ui/core/FormControl'; import {StyledFormLabel} from '../StyledComponents.js' import Checkbox from '@material-ui/core/Checkbox'; diff --git a/src/Components/UploadPageComponents/PartTwoComponents/Licenca.js b/src/Components/UploadPageComponents/PartTwoComponents/Licenca.js index 56454430d871c6765abb56a45655d341115231e2..9e8e059aed392a5791d6e11ee8e1b492803585eb 100644 --- a/src/Components/UploadPageComponents/PartTwoComponents/Licenca.js +++ b/src/Components/UploadPageComponents/PartTwoComponents/Licenca.js @@ -16,16 +16,13 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useState, useEffect, memo} from 'react' +import React, {useState, memo} from 'react' import styled from 'styled-components' import FormControl from '@material-ui/core/FormControl'; -import {ObjTypeBox, StyledFormLabel} from '../StyledComponents.js' +import {StyledFormLabel} from '../StyledComponents.js' import RadioGroup from '@material-ui/core/RadioGroup'; import Radio from '@material-ui/core/Radio'; -import {GetSubjectIconByName} from '../GetIconByName.js' import FormControlLabel from '@material-ui/core/FormControlLabel'; -import axios from 'axios' -import {apiUrl, apiDomain} from '../../../env'; function Licenca (props) { diff --git a/src/Components/UploadPageComponents/PartTwoComponents/SubjectsAndThemes.js b/src/Components/UploadPageComponents/PartTwoComponents/SubjectsAndThemes.js index aa50529d1679efd8156892f7f36e99ed684240e2..326dec2320b864be6820e9ec1182db9aa2066688 100644 --- a/src/Components/UploadPageComponents/PartTwoComponents/SubjectsAndThemes.js +++ b/src/Components/UploadPageComponents/PartTwoComponents/SubjectsAndThemes.js @@ -16,15 +16,13 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useState, useEffect, memo} from 'react' +import React, {useState, memo} from 'react' import { makeStyles } from '@material-ui/core/styles'; import FormControl from '@material-ui/core/FormControl'; import {ObjTypeBox, StyledFormLabel} from '../StyledComponents.js' import FormGroup from '@material-ui/core/FormGroup'; import {GetSubjectIconByName} from '../GetIconByName.js' import FormControlLabel from '@material-ui/core/FormControlLabel'; -import axios from 'axios' -import {apiUrl, apiDomain} from '../../../env'; import Checkbox from '@material-ui/core/Checkbox'; import Grid from '@material-ui/core/Grid'; diff --git a/src/Components/UploadPageComponents/ReactFileToUpload.js b/src/Components/UploadPageComponents/ReactFileToUpload.js index d7342d9c1c0b9484c719e1085f2bc43973a81f6c..ffbd6a452bddfe13eb14c996498ca17a897af2de 100644 --- a/src/Components/UploadPageComponents/ReactFileToUpload.js +++ b/src/Components/UploadPageComponents/ReactFileToUpload.js @@ -19,13 +19,13 @@ along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/> import React, {useState, useEffect} from 'react' import CloudUploadIcon from '@material-ui/icons/CloudUpload'; import {DottedBox, BlueButton} from './StyledComponents.js'; -import {getAxiosConfig} from '../HelperFunctions/getAxiosConfig.js' +import {getAxiosConfigFromJSON, updateHeaders} from '../HelperFunctions/getAxiosConfig.js' import AddAPhotoIcon from '@material-ui/icons/AddAPhoto'; import axios from 'axios' import {apiUrl} from '../../env'; export default function ReactFileToUpload (props) { - const [fileToUpload, setFileToUpload] = useState(null); + const [fileToUpload, setFileToUpload] = useState(null); const chunkSize = 262144 const uploadUrl = `${apiUrl}/learning_objects/` + props.draftID + '/chunk' const [fileName, setFileName] = useState(null) @@ -50,7 +50,7 @@ export default function ReactFileToUpload (props) { for (var i = 0; i < total; i++) { let chunk = newFile.slice(currentChunkStartByte, currentChunkFinalByte) - let config = getAxiosConfig() + let config = getAxiosConfigFromJSON() let formData = new FormData() formData.append('_chunkFilename', newFile.name); formData.append('_chunkIdentifier', chunkIdentifier); @@ -65,7 +65,7 @@ export default function ReactFileToUpload (props) { const response = await axios.post(uploadUrl, formData, config); console.log(response) if (response.headers['access-token']) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) + updateHeaders(response.headers) } remainingBytes = newFile.size - currentChunkFinalByte; if (currentChunkFinalByte === newFile.size) { diff --git a/src/Components/UploadPageComponents/SendInfo.js b/src/Components/UploadPageComponents/SendInfo.js index 99d6a2ad0eda450e292fcdd87c77ec1cf2eef267..ebcb1b95f377fe018e3a178716ff7d1621009dba 100644 --- a/src/Components/UploadPageComponents/SendInfo.js +++ b/src/Components/UploadPageComponents/SendInfo.js @@ -1,11 +1,25 @@ -import React, {useContext} from 'react' -import {Store} from '../../Store.js' -import axios from 'axios' -import {apiUrl} from '../../env'; +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + +import {putRequest} from '../HelperFunctions/getAxiosConfig.js' export function SendInfo (fieldName, payload, draftID) { - console.log('fieldName', fieldName, 'payload', payload, 'draftID', draftID) const key = fieldName let value = payload if (key === "tags") { @@ -20,23 +34,8 @@ export function SendInfo (fieldName, payload, draftID) { } } putObject.learning_object[key] = value - console.log(putObject) - let config = { - headers : { - 'Accept': 'application/json', - 'Content-Type': 'application/json', - } - } - config.headers["Access-Token"] = sessionStorage.getItem('@portalmec/accessToken'); - config.headers.Client = sessionStorage.getItem('@portalmec/clientToken') - config.headers.Uid = sessionStorage.getItem('@portalmec/uid') - axios.put((`${apiUrl}/learning_objects/` + draftID), putObject, config). - then( (response) => { - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - console.log(response) - }, (error) => {console.log(error)}) + const url = `/learning_objects/${draftID}` + putRequest(url, putObject, (data) => {console.log(data)}, (error) => {console.log(error)}) } diff --git a/src/Components/UploadPageComponents/Stepper.js b/src/Components/UploadPageComponents/Stepper.js index f67809843a6b64c58808fcd9a655c87705579a92..c1f9d40f55c2e4aafba0c44282ed441077853bf0 100644 --- a/src/Components/UploadPageComponents/Stepper.js +++ b/src/Components/UploadPageComponents/Stepper.js @@ -1,18 +1,30 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + import React from 'react'; import styled from 'styled-components' import PropTypes from 'prop-types'; -import { makeStyles, withStyles } from '@material-ui/core/styles'; +import { makeStyles } from '@material-ui/core/styles'; import clsx from 'clsx'; import Stepper from '@material-ui/core/Stepper'; import Step from '@material-ui/core/Step'; import StepLabel from '@material-ui/core/StepLabel'; import Check from '@material-ui/icons/Check'; -import SettingsIcon from '@material-ui/icons/Settings'; -import GroupAddIcon from '@material-ui/icons/GroupAdd'; -import VideoLabelIcon from '@material-ui/icons/VideoLabel'; -import StepConnector from '@material-ui/core/StepConnector'; -import Button from '@material-ui/core/Button'; -import Typography from '@material-ui/core/Typography'; const useColorlibStepIconStyles = makeStyles({ root: { @@ -73,51 +85,51 @@ ColorlibStepIcon.propTypes = { icon: PropTypes.node, }; -const useStyles = makeStyles((theme) => ({ - root: { - width: '100%', - }, - button: { - marginRight: theme.spacing(1), - }, - instructions: { - marginTop: theme.spacing(1), - marginBottom: theme.spacing(1), - }, -})); +// const useStyles = makeStyles((theme) => ({ +// root: { +// width: '100%', +// }, +// button: { +// marginRight: theme.spacing(1), +// }, +// instructions: { +// marginTop: theme.spacing(1), +// marginBottom: theme.spacing(1), +// }, +// })); function getSteps() { return ['Select campaign settings', 'Create an ad group', 'Create an ad']; } -function getStepContent(step) { - switch (step) { - case 0: - return 'Select campaign settings...'; - case 1: - return 'What is an ad group anyways?'; - case 2: - return 'This is the bit I really care about!'; - default: - return 'Unknown step'; - } -} +// function getStepContent(step) { +// switch (step) { +// case 0: +// return 'Select campaign settings...'; +// case 1: +// return 'What is an ad group anyways?'; +// case 2: +// return 'This is the bit I really care about!'; +// default: +// return 'Unknown step'; +// } +// } export default function CustomizedSteppers(props) { - const classes = useStyles(); + // const classes = useStyles(); const steps = getSteps(); -{/* const handleNext = () => { - setActiveStep((prevActiveStep) => prevActiveStep + 1); - }; +// {/* const handleNext = () => { +// setActiveStep((prevActiveStep) => prevActiveStep + 1); +// }; - const handleBack = () => { - setActiveStep((prevActiveStep) => prevActiveStep - 1); - }; +// const handleBack = () => { +// setActiveStep((prevActiveStep) => prevActiveStep - 1); +// }; - const handleReset = () => { - setActiveStep(0); - };*/} +// const handleReset = () => { +// setActiveStep(0); +// };*/} return ( diff --git a/src/Components/UploadPageComponents/StyledComponents.js b/src/Components/UploadPageComponents/StyledComponents.js index 2bac9300c9e0085b20b308ad48c4714c1796faec..944e96cfc068b0c4ecd38eeb30f44932991ee583 100644 --- a/src/Components/UploadPageComponents/StyledComponents.js +++ b/src/Components/UploadPageComponents/StyledComponents.js @@ -22,7 +22,6 @@ import { Button } from '@material-ui/core'; import TextField from '@material-ui/core/TextField'; import FormHelperText from '@material-ui/core/FormHelperText'; import FormLabel from '@material-ui/core/FormLabel'; -import NativeSelect from '@material-ui/core/NativeSelect'; import { makeStyles } from '@material-ui/core/styles'; import Radio from '@material-ui/core/Radio'; import GetIconByName from './GetIconByName.js' @@ -395,12 +394,6 @@ export const StyledTextField = styled(TextField)` } ` - - const StyledNativeSelect = styled(NativeSelect)` - .MuiInput-underline::after { - border-bottom: 1px solid #00bcd4 !important; - } - ` const useStyles = makeStyles({ root: { '&:hover': { diff --git a/src/Components/UploadPageComponents/UploadFileWrapper.js b/src/Components/UploadPageComponents/UploadFileWrapper.js index 4219c73f7fe0b145115157da045a98947aea62bb..123512f2dc9e81026f99a2173cd573e1ed0f7e32 100644 --- a/src/Components/UploadPageComponents/UploadFileWrapper.js +++ b/src/Components/UploadPageComponents/UploadFileWrapper.js @@ -19,18 +19,14 @@ along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/> import React, {useState} from 'react' import LinkIcon from '../../img/link_icon.svg' import ChooseLink from './ChooseLinkSection.js' -import {WrapperBox, StyledTextField, BlueButton, GrayButton} from './StyledComponents.js'; -import UploadMediaComponent from './ReactFileToUpload.js' -import FileUploadStage from './FileUploadStage.js' -import CloudUploadIcon from '@material-ui/icons/CloudUpload'; +import {WrapperBox, BlueButton, GrayButton} from './StyledComponents.js'; import {DottedBox} from './StyledComponents.js'; -import {getAxiosConfig} from '../HelperFunctions/getAxiosConfig.js' +import {getAxiosConfigFromJSON, updateHeaders, deleteRequest, putRequest} from '../HelperFunctions/getAxiosConfig.js' import AddAPhotoIcon from '@material-ui/icons/AddAPhoto'; import axios from 'axios' import {apiUrl} from '../../env'; import DoneIcon from '@material-ui/icons/Done'; import DeleteIcon from '@material-ui/icons/Delete'; -import LinearProgress from '@material-ui/core/LinearProgress'; import Alert from '../Alert.js'; import Snackbar from '@material-ui/core/Snackbar'; @@ -50,6 +46,7 @@ export default function UploadFileWrapper (props) { const [stage, setStage] = useState(props.prevFile ? "fileSelected" : "default") const handleNextStage = (newStage) => {setStage(newStage)} + // eslint-disable-next-line const [fileToUpload, setFileToUpload] = useState(null); const chunkSize = 262144 const uploadUrl = `${apiUrl}/learning_objects/` + props.draftID + '/chunk' @@ -74,7 +71,7 @@ export default function UploadFileWrapper (props) { handleNextStage("fileSelected") for (var i = 0; i < total; i++) { let chunk = newFile.slice(currentChunkStartByte, currentChunkFinalByte) - let config = getAxiosConfig() + let config = getAxiosConfigFromJSON() let formData = new FormData() formData.append('_chunkFilename', newFile.name); formData.append('_chunkIdentifier', chunkIdentifier); @@ -89,7 +86,7 @@ export default function UploadFileWrapper (props) { const response = await axios.post(uploadUrl, formData, config); console.log(response) if (response.headers['access-token']) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) + updateHeaders(response.headers) } setProgress(Math.round((currentChunkFinalByte/newFile.size) * 100)) remainingBytes = newFile.size - currentChunkFinalByte; @@ -115,17 +112,9 @@ export default function UploadFileWrapper (props) { const handleDelete = () => { if (attachmentID != null) { + const url = `/learning_objects/${props.draftID}/attachment/${attachmentID}` - let config = getAxiosConfig() - axios.delete( (`${apiUrl}/learning_objects/` + props.draftID + '/attachment/' + attachmentID), config).then( - (response) => { - console.log(response) - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - handleNextStage("default") - }, - (error) => {console.log(error)}) + deleteRequest(url, (data) => {handleNextStage("default")}, (error) => {console.log(error)}) } } @@ -151,26 +140,18 @@ export default function UploadFileWrapper (props) { }; const [snackbarOpen, toggleSnackbar] = useState(false) + const handleChooseLink = (link) => { - let config = getAxiosConfig() + const url = `/learning_objects/${props.draftID}` + let payload = { "learning_object" : { "id" : props.draftID, "link" : link } } - axios.put((`${apiUrl}/learning_objects/` + props.draftID), payload, config).then( - (response) => { - console.log(response) - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - toggleSnackbar(true) - }, (error) => { - console.log(error) - } - ) + putRequest(url, payload, (data) => {toggleSnackbar(true)}, (error) => {console.log(error)}) } switch (stage) { @@ -192,7 +173,6 @@ export default function UploadFileWrapper (props) { </div> </WrapperBox> ) - break; case "fileSelected": return( <WrapperBox> @@ -239,7 +219,6 @@ export default function UploadFileWrapper (props) { </div> </WrapperBox> ) - break; case "choosingLink": return ( <React.Fragment> @@ -253,7 +232,6 @@ export default function UploadFileWrapper (props) { <ChooseLink handleNextStage={handleNextStage} submit={handleChooseLink}/> </React.Fragment> ) - break; default: return( <WrapperBox> @@ -291,7 +269,7 @@ export default function UploadFileWrapper (props) { </div> <div className="enviar-link-texto"> - <img src={LinkIcon}/> + <img alt="" src={LinkIcon}/> <br/> <span>Enviar link de um recurso de outro site</span> </div> diff --git a/src/Components/UserCardGamified.js b/src/Components/UserCardGamified.js index 711b9ee433f6a13fcb6f6cbea4c120d8c5793233..a1cb24cacd862255d52b5be8d0acbcbb6bf9ed91 100644 --- a/src/Components/UserCardGamified.js +++ b/src/Components/UserCardGamified.js @@ -15,8 +15,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useState, useContext} from 'react'; -import styled from 'styled-components'; +import React from 'react'; import Grid from '@material-ui/core/Grid'; import Card from '@material-ui/core/Card'; import CardActions from '@material-ui/core/CardActions'; diff --git a/src/Components/UserPageComponents/Avatar.js b/src/Components/UserPageComponents/Avatar.js index f1026a358b3b784ce81494ed1f502da63800c045..f5ff994f43bd2ed4c480d394b44e1be22132d4b4 100644 --- a/src/Components/UserPageComponents/Avatar.js +++ b/src/Components/UserPageComponents/Avatar.js @@ -18,15 +18,15 @@ along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/> import React, {useState, useContext, useEffect} from 'react'; import styled from 'styled-components' import { Store } from '../../Store.js'; -import axios from 'axios' -import {apiUrl, apiDomain} from '../../env'; +import { apiDomain} from '../../env'; import noAvatar from "../../img/default_profile.png"; import ModalAlterarAvatar from '../ModalAlterarAvatar/ModalAlterarAvatar.js' export default function ProfileAvatar (props) { + // eslint-disable-next-line const {state, dispatch} = useContext(Store) - const [currentAvatar, setAvatar] = useState(state.currentUser.userAvatar) + const [currentAvatar, setAvatar] = useState(state.currentUser.avatar) const [hoverBool, toggleHover] = React.useState(false) const handleToggleHover = () => {toggleHover(!hoverBool)} @@ -34,7 +34,7 @@ export default function ProfileAvatar (props) { const [open, toggleOpen] = useState(false) const controlModal = () => {toggleOpen(!open)} - useEffect(() => {setAvatar(state.currentUser.userAvatar)}, state.currentUser.userAvatar) + useEffect(() => {setAvatar(state.currentUser.avatar)}, state.currentUser.avatar) return ( <> diff --git a/src/Components/UserPageComponents/Cover.js b/src/Components/UserPageComponents/Cover.js index 2af5bd7473f2414f1e3a97e627ff01cf5b028b87..339c36fd612cb3dc1a595c9a994a775af089c886 100644 --- a/src/Components/UserPageComponents/Cover.js +++ b/src/Components/UserPageComponents/Cover.js @@ -17,8 +17,7 @@ You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ import React, {useState, useContext, useEffect} from 'react'; import { Store } from '../../Store.js'; -import axios from 'axios' -import {apiUrl, apiDomain} from '../../env'; +import {apiDomain} from '../../env'; import {CoverContainer} from '../TabPanels/StyledComponents.js' import IconButton from '@material-ui/core/IconButton'; import PhotoCamera from '@material-ui/icons/PhotoCamera'; @@ -28,7 +27,9 @@ import ModalAlterarCover from '../ModalAlterarCover/ModalAlterarCover.js' export default function Cover (props) { const {state} = useContext(Store) - const [currentCover, setCoverImg] = useState(state.currentUser.userCover) + const WIDTH = window.innerWidth; + + const [currentCover, setCoverImg] = useState(state.currentUser.cover_file_name) const [tempCover, setTempCover] = useState('') const [open, toggleOpen] = useState(false) @@ -42,8 +43,8 @@ export default function Cover (props) { } useEffect( () => { - setCoverImg(state.currentUser.userCover) - }, state.currentUser.userCover) + setCoverImg(state.currentUser.cover) + }, state.currentUser.cover) return ( <> <ModalAlterarCover @@ -56,11 +57,21 @@ export default function Cover (props) { {currentCover && <img src={apiDomain + currentCover} alt = '' style= {{width:"100%", height:"100%", objectFit : "cover" }}/>} <input accept="image/*" style = {{display:"none"}} id="choose-cover-file" type="file" onChange={(e) => updateCover(e.target.files)}/> <label htmlFor="choose-cover-file"> + { + WIDTH >= 545 ? + <Tooltip title={<span style={{fontSize:"14px", overflow:"hidden", transition:"all .5s ease"}}>ALTERAR CAPA</span>} placement="left"> + <IconButton style={{position:"absolute",right:"0",bottom: "0",color:"#fff"}}color="primary" aria-label="upload picture" component="span"> + <PhotoCamera /> + </IconButton> + </Tooltip> + : <Tooltip title={<span style={{fontSize:"14px", overflow:"hidden", transition:"all .5s ease"}}>ALTERAR CAPA</span>} placement="left"> - <IconButton style={{position:"absolute",right:"0",top:"0",color:"#fff"}}color="primary" aria-label="upload picture" component="span"> + <IconButton style={{position:"absolute",left:"0",top: "0",color:"#fff"}}color="primary" aria-label="upload picture" component="span"> <PhotoCamera /> </IconButton> </Tooltip> + } + </label> </CoverContainer> </> diff --git a/src/Components/UserPageComponents/EditProfileButton.js b/src/Components/UserPageComponents/EditProfileButton.js index 4df7df2c7a5a6b4794ca5fd926d7440c77cc3ec1..beaa7137501ba03fc9de6f46d14391c6e7072f13 100644 --- a/src/Components/UserPageComponents/EditProfileButton.js +++ b/src/Components/UserPageComponents/EditProfileButton.js @@ -49,8 +49,8 @@ const EditProfileAnchor = styled(Link)` box-shadow : 0 2px 5px 0 rgba(0,0,0,.26); background-color : #fafafa; position : absolute; - right : 5px; - bottom : 0; + right : 10px; + top : 10px; margin-bottom : 20px; color : #666; padding : 0 10px; diff --git a/src/Components/UserPageComponents/SubmitterStatus.js b/src/Components/UserPageComponents/SubmitterStatus.js index 47924373223205e9a81575cc957fbb4f371bce34..7795a90df8376ca052eb13013c1771b1c522d03a 100644 --- a/src/Components/UserPageComponents/SubmitterStatus.js +++ b/src/Components/UserPageComponents/SubmitterStatus.js @@ -20,7 +20,7 @@ import { Store } from '../../Store.js'; import CheckDecagram from '../../img/check-decagram-gray.svg' export default function SubmitterStatus (props) { - const {state} = React.useContext(Store) + const {state} = useContext(Store) let text; switch (state.currentUser.submitter_request) { @@ -39,7 +39,7 @@ export default function SubmitterStatus (props) { <p style={{fontSize:"15px", lineHeight:"22px", textAlign:"left", margin:"0 0 10px"}}> <span style={{cursor:"pointer"}}> <span style={{paddingRight:"5px"}}> - <img src={CheckDecagram}/> + <img src={CheckDecagram} alt='check icon'/> </span> {text} <span style={{color:"#00bcd4"}}> SAIBA MAIS</span> diff --git a/src/Components/UserPageComponents/UserInfo.js b/src/Components/UserPageComponents/UserInfo.js index 0a45ac75dff68aeb5065a2610a9c8cdc75a14b37..8c776a95eef3a345b8407007c453c6c2a995ddf5 100644 --- a/src/Components/UserPageComponents/UserInfo.js +++ b/src/Components/UserPageComponents/UserInfo.js @@ -22,7 +22,7 @@ import {UserProfileInfoDiv} from '../TabPanels/StyledComponents.js' export default function UserInfo (props) { const {state} = useContext(Store) - const user = state.currentUser.username + const user = state.currentUser.name const education = state.currentUser.education return ( diff --git a/src/Components/UserCard.js b/src/Components/VerticalRuler.js similarity index 80% rename from src/Components/UserCard.js rename to src/Components/VerticalRuler.js index c8cb4a80e14ae5f66c4f7f4a0466a424679d2da9..a84dc1381675d222245eb7097263f385e15c1b10 100644 --- a/src/Components/UserCard.js +++ b/src/Components/VerticalRuler.js @@ -16,3 +16,16 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ +import React from 'react'; + + +export default function VerticalRuler(props) { + return ( + <div + style={{ + borderLeft: ''+props.width+'px solid '+props.color, + height:props.height + }}/> + ); +} + diff --git a/src/Components/carousel.css b/src/Components/carousel.css index bc5772746539b88af1e010d0776362b508673e9f..9c7ea98633ce9e85948d544465255bcf47760ba9 100644 --- a/src/Components/carousel.css +++ b/src/Components/carousel.css @@ -21,15 +21,28 @@ along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/> } .carousel .control-arrow { background: orange !important; - position: relative !impontant; -} -.carousel.carousel-slider .control-arrow { - top: 40% !important; - bottom: 50% !important; - border-radius: 100% !important; - opacity: 0.8 !important; - padding: 12px !important; + /* position: relative !important; */ + + -webkit-box-shadow: 0 8px 17px 2px rgba(0,0,0,0.14), 0 3px 14px 2px rgba(0,0,0,0.12), 0 5px 5px -3px rgba(0,0,0,0.2); + box-shadow: 0 8px 17px 2px rgba(0,0,0,0.14), 0 3px 14px 2px rgba(0,0,0,0.12), 0 5px 5px -3px rgba(0,0,0,0.2); + + + + } + .MuiPaper-elevation1-209{ box-shadow: none !important; } + + +.carousel.carousel-slider .control-arrow { + top: 35%!important; + bottom: 50%!important; + border-radius: 100%!important; + opacity: 1!important; + text-align: center; + vertical-align: middle; + height: 50px; + width: 50px; +} diff --git a/src/Pages/AboutPage.js b/src/Pages/AboutPage.js index a61ee5514cd8145732288af6edfea7f4e60c2074..56b8404129be79f65c0d98f971bb7006e316d1dd 100644 --- a/src/Pages/AboutPage.js +++ b/src/Pages/AboutPage.js @@ -16,11 +16,13 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { Component } from 'react'; +import React from 'react'; import Grid from '@material-ui/core/Grid'; import styled from 'styled-components'; import Modal from '../Components/ModalAbout'; import AboutCarousel from "../Components/AboutCarousel"; +import AboutCarouselPartner from '../Components/AboutCarouselPartner'; + /*Importação de imagens para o componente*/ import Agpl from "../img/sobre/agpl.svg"; @@ -31,23 +33,6 @@ import Alunos from "../img/sobre/Alunos.png"; import Gestores from "../img/sobre/Gestores.png"; import Comunidade from "../img/sobre/comunidade.png"; -import LogoPortalDoProfessor from "../img/logo_parceiros/logo_portaldoprofessor.png"; -import LogoBioe from "../img/logo_parceiros/logo_bioe.png"; -import LogoDominioPublico from "../img/logo_parceiros/logo_dominiopublico.png"; -import LogoTvEscola from "../img/logo_parceiros/logo_tvescola.png"; -import Safer from "../img/logo_parceiros/safer.png"; -import FundacaoLemann from "../img/logo_parceiros/fundacao-lemann.png"; -import InstitutoCrescer from "../img/logo_parceiros/instituto-crescer.png"; -import RedeEscola from "../img/logo_parceiros/redeescola.png"; -import Educagital from "../img/logo_parceiros/educagital.png"; -import EnefAef from "../img/logo_parceiros/ENEF_AEF.png"; -import Impa from "../img/logo_parceiros/impa.png"; -import Futura from "../img/logo_parceiros/futura.png"; -import Impulsiona from "../img/logo_parceiros/impulsiona.png"; -import InstPeninsula from "../img/logo_parceiros/inst-peninsula.png"; -import Telefonica from "../img/logo_parceiros/telefonica.png"; - - const Secao1 = styled.div` height: 600px; @@ -56,7 +41,6 @@ const Secao1 = styled.div` const Secao2 = styled.div` - height: 600px; color: #666; text-align: center; font-size: 14px; @@ -65,11 +49,11 @@ const Secao2 = styled.div` .container { height: 100%; - width: 1140px; padding-right: 15px; padding-left: 15px; margin-right: auto; margin-left: auto; + padding: 20px 0px; .container-secao { height: 100%; @@ -78,8 +62,8 @@ const Secao2 = styled.div` justify-content: center; - .conteudo-secao { + .conteudo-secao { h2 { text-align: center; font-family: Roboto, sans-serif; @@ -110,23 +94,19 @@ const Secao2 = styled.div` ` const Secao3 = styled.div` - height: auto; padding: 30px 0; background-color: #1ab9de; color: #fff; .container { - height: 100%; - width: 1140px; padding-right: 15px; padding-left: 15px; margin-right: auto; margin-left: auto; + padding-left: 20px; .container-secao { - height: 100%; - width: 1110px; padding-right: 15px; padding-left: 15px; display: flex; @@ -186,7 +166,6 @@ const Secao4 = styled.div` .container { height: 100%; - width: 1140px; padding-right: 15px; padding-left: 15px; margin-right: auto; @@ -300,7 +279,6 @@ const Secao5 = styled.div` .container { height: 100%; - width: 1140px; padding-right: 15px; padding-left: 15px; margin-right: auto; @@ -343,8 +321,7 @@ const Secao6 = styled.div` .container { - height: 450px; - width: 1140px; + height: 100%; padding-top:50px padding-right: 15px; padding-left: 15px; @@ -361,7 +338,7 @@ const Secao6 = styled.div` .conteudo-secao { height: 100%; - width: 970px; + width: 100%; h2 { text-align: center; @@ -394,13 +371,12 @@ const Secao6 = styled.div` ` const Secao7 = styled.div` - height: 592px; + height: 100%; background-color: #f4f4f4; .container { height: 100%; - width: 1170px; margin-right: auto; margin-left: auto; @@ -410,6 +386,7 @@ const Secao7 = styled.div` flex-direction: column; justify-content: center; color: #666; + padding: 50px .conteudo-secao { @@ -438,11 +415,11 @@ const Secao7 = styled.div` .card { - height: 270px; + height: 80%; background-color: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24); - padding: 50px 20px; + padding: 40px 20px; text-align: center; h3 { @@ -480,7 +457,6 @@ const Secao8 = styled.div` .container { height: 100%; - width: 1140px; padding-right: 15px; padding-left: 15px; margin-right: auto; @@ -574,14 +550,30 @@ const Secao8 = styled.div` export default function AboutPage(props) { - + var pageWidth = window.innerWidth + const calculateMargin = ((pageWidth)=>{ + if (pageWidth > 700 && pageWidth <= 850){ + return "40%" + } + if (pageWidth > 850 && pageWidth <= 900){ + return "25%" + } + if (pageWidth > 900 && pageWidth < 1100){ + return "13%" + } + else{ + return "0%" + } + }) + var marginSet = calculateMargin(pageWidth) + const styleIMGSec3 = {float:"right", width:"80%", maxWidth:475, marginRight:30, marginTop: marginSet} return ( <> <link href="https://fonts.googleapis.com/css?family=Pompiere|Roboto:300,400&display=swap" rel="stylesheet"/> <Secao1> - <iframe src="https://player.vimeo.com/video/231609051" width="100%" height="100%" frameborder="0" allow="autoplay; fullscreen" allowfullscreen></iframe> + <iframe title="Vídeo página sobre" src="https://player.vimeo.com/video/231609051" width="100%" height="100%" frameBorder="0" allow="autoplay; fullscreen" allowFullScreen></iframe> </Secao1> @@ -590,30 +582,24 @@ export default function AboutPage(props) { <div className="container-secao"> <div className="conteudo-secao"> <h2>Um Pouco da História</h2> - <br/> - <br/> - <p> + <p style={{marginLeft:20, marginRight:20, marginBottom:40}}> A partir de uma iniciativa do Ministério da Educação, surge em outubro de 2015 a proposta de reunir e disponibilizar, em um único lugar, os Recursos Educacionais Digitais dos principais portais do Brasil. Com o objetivo de melhorar a experiência de busca desses Recursos, a Plataforma foi desenvolvida numa - parceria coletiva entre: Universidade Federal de Santa Catarina - (UFSC), Universidade Federal do Paraná (UFPR) e professoras(es) + parceria coletiva entre: Universidade Federal do Paraná (UFPR), Universidade Federal de Santa Catarina (UFSC) e professoras(es) da Educação Básica de todo o Brasil. Assim, a Plataforma MEC pretende se tornar uma referência em Recursos Educacionais Digitais, como um ambiente de busca, interação e colaboração entre professoras(es)!<br/><br/>Faça parte deste espaço de colaborativo você também! </p> - <br/> - <br/> - <br/> <img src={Agpl} alt="agpl" /> <p> Este programa é software livre, sob os termos da - <a href="https://www.gnu.org/licenses/agpl-3.0.en.html" target="_blank"> licença GNU/AGPL</a><br/> - Seu código fonte está disponível no <a href="https://gitlab.c3sl.ufpr.br/portalmec/portalmec" target="_blank">GitLab</a> + <a href="https://www.gnu.org/licenses/agpl-3.0.en.html" rel="noreferrer" target="_blank"> licença GNU/AGPL</a><br/> + Seu código fonte está disponível no <a href="https://gitlab.c3sl.ufpr.br/portalmec/portalmec" rel="noreferrer" target="_blank">GitLab</a> </p> @@ -627,7 +613,7 @@ export default function AboutPage(props) { <div className="container-secao"> <div className="conteudo-secao"> <Grid container spacing={0}> - <Grid item xs={6}> + <Grid item xs style={{paddingRight:20}}> <h2>O que nos faz diferentes?</h2> <h3>Espaço construído por e para professores</h3> <p> @@ -648,9 +634,15 @@ export default function AboutPage(props) { os Recursos Educacionais Digitais dos principais portais abertos. </p> </Grid> - <Grid item xs={6}> - <img src={Notebook} alt="Imagem Notebook"/> - </Grid> + { + pageWidth >= 751? + <Grid item xs={6} style={{position:"relative"}}> + <img src={Notebook} alt="Imagem Notebook" style={styleIMGSec3}/> + </Grid> + : + <div/> + } + </Grid> @@ -659,97 +651,19 @@ export default function AboutPage(props) { </div> </Secao3> + + <Secao4> - <div className="container"> - <div className="container-secao"> - <div className="conteudo-secao"> + <div className="container"> + <div className="container-secao" id="portaisparceiros"> + <div className="conteudo-secao" > <div> <h2>Portais Parceiros</h2> <p>Aqui na Plataforma você encontra os Recursos Digitais dos principais portais do MEC e de vários outros parceiros.</p> </div> - <div className="portais"> - <ul className="itens"> - <li> - <a href="http://portaldoprofessor.mec.gov.br/index.html" target="_blank"> - <img src={LogoPortalDoProfessor} alt="LogoPortalDoProfessor" /> - </a> - </li> - <li> - <a href="http://objetoseducacionais2.mec.gov.br/" target="_blank"> - <img src={LogoBioe} alt="LogoBioe" /> - </a> - </li> - <li> - <a href="http://www.dominiopublico.gov.br/pesquisa/PesquisaObraForm.jsp" target="_blank"> - <img src={LogoDominioPublico} alt="LogoDominioPublico" /> - </a> - </li> - <li> - <a href="https://tvescola.org.br/" target="_blank"> - <img src={LogoTvEscola} alt="LogoTvEscola" /> - </a> - </li> - </ul> - <ul className="itens"> - <li> - <a href="http://www.fundacaolemann.org.br/" target="_blank"> - <img style={{align: "middle"}} src={FundacaoLemann} alt="FundacaoLemann" /> - </a> - </li> - <li> - <a href="http://new.safernet.org.br/" target="_blank"> - <img src={Safer} alt="Safer" /> - </a> - </li> - <li> - <a href="http://institutocrescer.org.br/" target="_blank"> - <img src={InstitutoCrescer} alt="InstitutoCrescer" /> - </a> - </li> - <li> - <a href="http://escoladigital.org.br/" target="_blank"> - <img src={RedeEscola} alt="RedeEscola" /> - </a> - </li> - <li> - <a href="http://educadigital.org.br" target="_blank"> - <img src={Educagital} alt="Educagital" /> - </a> - </li> - <li> - <a href="http://www.aefbrasil.org.br" target="_blank"> - <img style={{height:"130px",filter: "grayscale(1)"}} src={EnefAef} alt="EnefAef" /> - </a> - </li> - </ul> - <ul className="itens"> - <li> - <a href="https://impa.br/" target="_blank"> - <img src={Impa} alt="Impa" /> - </a> - </li> - <li> - <a href="http://futura.org.br/" target="_blank"> - <img src={Futura} alt="Futura" /> - </a> - </li> - <li> - <a href="http://impulsiona.org.br/" target="_blank"> - <img src={Impulsiona} alt="Impulsiona" /> - </a> - </li> - <li> - <a href="http://www.institutopeninsula.org.br/" target="_blank"> - <img src={InstPeninsula} alt="InstPeninsula" /> - </a> - </li> - <li> - <a href="http://fundacaotelefonica.org.br/" target="_blank"> - <img src={Telefonica} alt="Telefonica" /> - </a> - </li> - </ul> - </div> + + <AboutCarouselPartner/> + <div> <h3>Você busca Recursos Educacionais Digitais em outros sites?</h3> <p> @@ -810,7 +724,7 @@ export default function AboutPage(props) { </div> <div> <Grid container spacing={3}> - <Grid item xs={3}> + <Grid item xs> <div className="card"> <img src={Professores} alt="" /> <h3>Professores</h3> @@ -821,7 +735,7 @@ export default function AboutPage(props) { </p> </div> </Grid> - <Grid item xs={3}> + <Grid item xs> <div className="card"> <img src={Alunos} alt="" /> <h3>Alunos</h3> @@ -832,7 +746,7 @@ export default function AboutPage(props) { </p> </div> </Grid> - <Grid item xs={3}> + <Grid item xs> <div className="card"> <img src={Gestores} alt="" /> <h3>Gestores</h3> @@ -842,7 +756,7 @@ export default function AboutPage(props) { </p> </div> </Grid> - <Grid item xs={3}> + <Grid item xs> <div className="card"> <img src={Comunidade} alt="" /> <h3>Comunidade Escolar</h3> diff --git a/src/Pages/Accessibility.js b/src/Pages/Accessibility.js new file mode 100644 index 0000000000000000000000000000000000000000..a2dbb7efc0d8250abaabc294032b0188242fae5c --- /dev/null +++ b/src/Pages/Accessibility.js @@ -0,0 +1,152 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ +import React from 'react'; +import styled from 'styled-components' +import { Link } from "react-router-dom"; +import Breadcrumbs from "@material-ui/core/Breadcrumbs"; + + +const titulo ={ + fontFamily: "Roboto, sans-serif", + marginTop: "0", + fontSize: "26px", + fontWeight: "300", + marginBottom: "10px", + color: "#666" +} +const subtitulo ={ + fontFamily: "Roboto, sans-serif", + marginBottom: "20px", + marginTop: "0", + fontWeight: "500", + fontSize: "16px", + color: "#00bcd4" + +} + +const paper ={ + padding: "30px 30px 100px 30px", + backgroundColor: "#fff", + boxShadow: "0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24)", + width:"1170px", + margin: "30px auto", + marginBottom:"0", + display: "flex", + flexDirection:"column", + boxSizing: "border-box" +} + +const paragrafo={ + textAlign: "left", + padding: "30px 0", + margin: "0", + fontFamily: "'Roboto Light','Roboto Regular',Roboto", + fontWeight: "300", + fontSize: "18px", + color: "#666", + display:"block" +} + +const azulzinho={ + textAlign: "right", + display:"block", + color: "#00bcd4", + fontSize: "16px" +} + +const atalhos = { + fontWeight: "400", + color: "#00bcd4" + +} + +const breadCrumbs={ + padding: "10px", + display: "flex", + margin: "0 auto", + width:"1170px" +} +const StyledBreadCrumbs = styled(Breadcrumbs)` + display: flex; + justify-content: flex-start; + max-width: 1170px; + span { + color: #a5a5a5; + font-size: 14px; + } + a { + color: #00bcd4; + text-decoration: none; + font-size: 14px; + } +`; + +export default function Acessibility (props) { + return ( + <div style={{padding:"0 0 30px 0",backgroundColor :"#f4f4f4"}}> + + <div style={breadCrumbs}> + <StyledBreadCrumbs> + <Link to="/">Página Inicial</Link> + <span>Acessibilidade</span> + + </StyledBreadCrumbs> + </div> + <link href="https://fonts.googleapis.com/css?family=Roboto:300;400;500&display=swap" rel="stylesheet"/> + <div style={paper}> + <h3 style={titulo}>Acessibilidade</h3> + <div style={{maxWidth:"660px",margin:"0 auto"}}> + <p style={paragrafo}> + Acessibilidade na web é possibilitar qualquer indivíduo de usufruir de quaisquer + atividades ou conteúdos em sítios e serviços disponíveis na web, com igualdade e + autonomia, independentemente de sua capacidade motora, visual, auditiva, + intelectual, cultural ou social + </p> + <span style={azulzinho}> + Cartilha Acessibilidade na Web - W3C Brasil, 2013 + </span> + <p style={paragrafo}> + Na Plataforma a acessibilidade foi baseada principalmente no Modelo de + Acessibilidade em Governo Eletrônico (e-MAG), o modelo pode ser acessado + <a + style={{textDecoration:"none", color:"#222"}} + target="_blank" + rel="noreferrer" + href="https://www.governoeletronico.gov.br/documentos-e-arquivos/e-MAG%20V3.pdf"> aqui</a>. + </p> + </div> + <div style={{color:"#666", fontSize:"14px"}}> + <h3 style={subtitulo}>Atalhos padrões da Plataforma</h3> + Teclando-se <strong style={atalhos}>Alt + 1</strong> em qualquer página da Plataforma, chega-se diretamente ao começo do conteúdo principal da página. + <br/><br/> + Teclando-se <strong style={atalhos}>Alt + 2</strong> em qualquer página da Plataforma, chega-se diretamente ao início do menu principal. + <br/><br/> + Teclando-se <strong style={atalhos}>Alt + 3</strong> em qualquer página da Plataforma, chega-se diretamente no campo de busca. + <br/><br/> + Teclando-se <strong style={atalhos}>Alt + 4</strong> em qualquer página da Plataforma, chega-se diretamente ao rodapé. + <br/><br/> + No caso do <strong style={atalhos}>Firefox</strong>, em vez de Alt + número, tecle simultaneamente <strong style={atalhos}>Alt + Shift + número</strong>. + <br/><br/> + Sendo <strong style={atalhos}>Firefox</strong> no <strong style={atalhos}>Mac OS</strong>, em vez de Alt + Shift + número, tecle simultaneamente <strong style={atalhos}>Ctrl + Alt + número</strong>. + <br/><br/> + No <strong style={atalhos}>Opera</strong>, as teclas são <strong style={atalhos}>Shift + Escape + número</strong>. Ao teclar apenas <strong style={atalhos}>Shift + Escape</strong>, o usuário encontrará uma janela com todas as alternativas de ACCESSKEY da página. + </div> + </div> + </div> + ); +} diff --git a/src/Pages/CollectionPage.js b/src/Pages/CollectionPage.js index 53f2351c0eade585a0709d459f9f940299b60bb5..7aec85f4c15248b0f38a886f918c5befc6df02d6 100644 --- a/src/Pages/CollectionPage.js +++ b/src/Pages/CollectionPage.js @@ -2,7 +2,6 @@ Departamento de Informatica - Universidade Federal do Parana This file is part of Plataforma Integrada MEC. - Plataforma Integrada MEC is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or @@ -16,15 +15,192 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {Component} from 'react'; +import React, { useRef, useState, useEffect, useContext } from 'react'; +import { Grid } from '@material-ui/core'; +import CollectionAuthor from '../Components/CollectionAuthor.js'; +import VerticalRuler from '../Components/VerticalRuler.js'; +import CollectionDescription from '../Components/CollectionDescription.js'; +import ResourceList from '../Components/ResourceList.js'; +import CollectionCommentSection from '../Components/CollectionCommentSection.js'; +import { apiDomain } from '../env'; +import styled from 'styled-components'; +import DowloadButton from '../Components/CollectionDowloadButton.js'; +import Breadcrumbs from "@material-ui/core/Breadcrumbs"; +import { Link } from 'react-router-dom'; +import FollowCollectionButton from '../Components/FollowCollectionButton'; +import { Store } from '../Store.js' +import {getRequest} from '../Components/HelperFunctions/getAxiosConfig.js' + +export default function CollectionPage(props) { + const { state } = useContext(Store); + + const [collection, setCollection] = useState({ + name: '', + id: 0, + }); + const collection_id = props.match.params.id; + const comment_ref = useRef(null); + + useEffect(() => { + const url = `/collections/${collection_id}` + + getRequest(url, (data) => {setCollection(Object.assign({}, data))}, (error) => {console.log(error)}) + }, []); + + const handleScrollToComments = () => { + window.scrollTo(0, comment_ref.current.offsetTop); + } + console.log("COLLECTION >> ", collection) + return ( + <> + <BreadCrumbsDiv> + <StyledBreadCrumbs> + <Link to="/">Página Inicial</Link> + <span>Coleções</span> + </StyledBreadCrumbs> + </BreadCrumbsDiv> + <Grid + container + direction="row" + justify="space-around" + alignItems="center" + spacing={4} + > + <Grid + item + md={3} + > + <CollectionAuthor + author_id={collection.owner ? collection.owner.id : 0} + name={collection.owner ? collection.owner.name : ""} + imgsrc={collection.owner ? apiDomain + collection.owner.avatar : ''} /> + </Grid> + + + <Grid + item + md={5} + > + <CollectionDescription + scrollToComments={handleScrollToComments} + title={collection.name ? collection.name : ""} + collection_id={collection.id ? collection.id : 0} /> + </Grid> + + <Grid + item + md={3} + > + <DowloadButton + id={collection.id ? collection.id : 0} + /> + <div style={{height : 12}}></div> + <FollowCollectionButton + user_id={state.currentUser.id} + collection_id={collection_id} /> + </Grid> + </Grid> + + <VerticalRuler width={1} height={100} color="rgb(238, 238, 238)" /> + <Grid container item xs={12} direction="row" justify="center" alignItems="center" style={{ backgroundColor: '#f4f4f4' }}> + <Grid item xs={10} alignItems="center" justify="center"> + <ResourceList resources={ + collection.collection_items ? + collection.collection_items.map(i => { + return { + type: i.collectionable.object_type, + author: i.collectionable.author, + title: i.collectionable.name, + rating: i.collectionable.review_average, + likeCount: i.collectionable.likes_count, + liked: i.collectionable.liked, + avatar: i.collectionable.publisher.avatar, + thumbnail: i.collectionable.thumbnail, + tags: i.collectionable.tags.map(t => t), + id: i.collectionable.id, + downloadableLink: i.collectionable.default_attachment_location, + publisher: i.collectionable.publisher.name, + published: i.collectionable.state + } + }) + : [] + } /> -class CollectionPage extends Component { - render() { - return ( - <h1> Página visulizar coleção</h1> - ); - } + </Grid> + <Grid container item xs={12} style={{ marginTop: 40 }} ref={comment_ref}> + <CollectionCommentSection id={collection_id} /> + </Grid> + </Grid> + </> + + + // <Grid container + // direction="row" + // justify="space-around" + // alignItems="center" + // style={mainContainerStyle}> + + // <Grid item xs={10} md={3}> + // <CollectionAuthor + // author_id={collection.owner ? collection.owner.id : 0} + // name={collection.owner ? collection.owner.name : ""} + // imgsrc={collection.owner ? apiDomain+collection.owner.avatar : ''}/> + // </Grid> + + // <VerticalRuler width={1} height={300} color="rgb(238, 238, 238)"/> + + // <Grid item xs={10} md={6}> + // <CollectionDescription + // scrollToComments={handleScrollToComments} + // title={collection.name ? collection.name : ""} + // collection_id={collection.id ? collection.id : 0}/> + // </Grid> + + // <Grid container item xs={12} direction="row" justify="center" alignItems="center" style={{backgroundColor: '#f4f4f4'}}> + // <Grid item xs={10}> + // <ResourceList resources={ + // collection.collection_items ? + // collection.collection_items.map(i => { + // return { + // type: i.collectionable.object_type, + // author: i.collectionable.author, + // published: i.collectionable.published_at, + // title: i.collectionable.name, + // rating: i.collectionable.review_average, + // likeCount: i.collectionable.likes_count, + // liked: i.collectionable.liked, + // avatar: i.collectionable.publisher.avatar, + // thumbnail: i.collectionable.thumbnail, + // tags: i.collectionable.tags.map(t => t.name), + // id: i.collectionable.id, + // } + // }) + // : [] + // }/> + + // </Grid> + // <Grid container item xs={12} style={{marginTop: 40}} ref={comment_ref}> + // <CollectionCommentSection id={collection_id}/> + // </Grid> + // </Grid> + // </Grid> + ); +} + +const StyledBreadCrumbs = styled(Breadcrumbs)` + display: flex; + justify-content: flex-start; + span { + color: #a5a5a5; + } + a { + color: #00bcd4; + text-decoration: none; } +`; -export default CollectionPage; +const BreadCrumbsDiv = styled.div` + padding: 10px; + display: flex; +`; diff --git a/src/Pages/EditLearningObjectPage.js b/src/Pages/EditLearningObjectPage.js index 2597832c9390ffb0d18167f05f0b7982e53d38d5..5e04a247c29d2b1fe130a18e5b15af4fab026d69 100644 --- a/src/Pages/EditLearningObjectPage.js +++ b/src/Pages/EditLearningObjectPage.js @@ -18,7 +18,6 @@ along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/> import React, {useState, useEffect, useContext} from 'react' import {Store} from '../Store.js' -import styled from 'styled-components' import axios from 'axios' import {apiUrl, apiDomain} from '../env'; import Grid from '@material-ui/core/Grid'; @@ -26,7 +25,6 @@ import UploadFileWrapper from '../Components/UploadPageComponents/UploadFileWrap import Alert from '../Components/Alert.js'; import Snackbar from '@material-ui/core/Snackbar'; import {GreyButton, OrangeButton, InfoBox} from '../Components/UploadPageComponents/StyledComponents.js' -import {getAxiosConfig} from '../Components/HelperFunctions/getAxiosConfig.js' import {Background} from '../Components/UploadPageComponents/StyledComponents' import LoadingSpinner from '../Components/LoadingSpinner' import NewTitle from '../Components/UploadPageComponents/Forms/NewTitle.js' @@ -38,13 +36,11 @@ import Idioma from '../Components/UploadPageComponents/Forms/Idioma.js' import EducationalStage from '../Components/UploadPageComponents/PartTwoComponents/EducationalStage.js' import SubjectsAndThemes from '../Components/UploadPageComponents/PartTwoComponents/SubjectsAndThemes.js' import Licenca from '../Components/UploadPageComponents/PartTwoComponents/Licenca.js' -import { Button } from '@material-ui/core'; import {LoadingDiv} from '../Components/UploadPageComponents/PartTwo.js' import EditThumbnail from '../Components/UploadPageComponents/PartTwoComponents/EditThumbnail.js' import DisplayThumbnail from '../Components/UploadPageComponents/PartTwoComponents/DisplayThumbnail.js' -import CustomCircularProgress from '../Components/UploadPageComponents/PartTwoComponents/CustomCircularProgress'; import DragAndDropThumbnail from '../Components/UploadPageComponents/PartTwoComponents/DragAndDropThumbnail' - +import {getRequest, deleteRequest, putRequest, postRequest} from '../Components/HelperFunctions/getAxiosConfig.js' export default function EditLearningObjectPage (props) { const recursoId = props.match.params.recursoId @@ -55,23 +51,19 @@ export default function EditLearningObjectPage (props) { const [eduStages, setEduStages] = useState([]) const [subjects, setSubjects] = useState([]) + function handleSuccessfulGet (data) { + setLearningObject(data) + if(data.thumbnail) { + setThumbnail(data.thumbnail) + setThumbnailStage('done') + } + setUpdatedInfo({...updatedInfo, 'id' : data.id}) + toggleLoading(false) + } + useEffect( () => { - const config = getAxiosConfig() - axios.get( (`${apiUrl}/learning_objects/` + recursoId), config - ).then( (response) => { - console.log(response.data) - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - setLearningObject(response.data) - if(response.data.thumbnail) { - setThumbnail(response.data.thumbnail) - setThumbnailStage('done') - } - setUpdatedInfo({...updatedInfo, ['id'] : response.data.id}) - toggleLoading(false) - }, (error) => {console.log(error)} - ) + const url = `/learning_objects/${recursoId}` + getRequest(url, handleSuccessfulGet, (error) => {console.log(error)}) axios.get(`${apiUrl}/object_types/`).then( (response) => { @@ -102,7 +94,7 @@ export default function EditLearningObjectPage (props) { }, (error) => {console.log(error)} ) - }, [, state.currentUser.id]) + }, []) const [loading, toggleLoading] = useState(true) @@ -114,58 +106,37 @@ export default function EditLearningObjectPage (props) { const [snackbarOpen, toggleSnackbar] = useState(false) + function handleSuccessfulDelete (data) { + toggleSnackbar(true) + props.history.push("/") + } const handleDelete = () => { - let config = getAxiosConfig() - axios.delete((`${apiUrl}/learning_objects/` + learningObject.id), config).then( - (response) => { - toggleSnackbar(true) - console.log(response.data) - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - props.history.push("/") - }, - (error) => { - console.log(error) - } - ) + const url = `/learning_objects/${learningObject.id}` + + deleteRequest(url, handleSuccessfulDelete, (error) => {console.log(error)}) } const handleUpdateInfo = () => { - let config = getAxiosConfig() - console.log(updatedInfo) + const url = `/learning_objects/${learningObject.id}` let payload = { "learning_object" : updatedInfo } - console.log(payload) - axios.put((`${apiUrl}/learning_objects/` + learningObject.id), payload, config).then( - (response) => { - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - console.log(response.data); props.history.goBack() - }, - (error) => {console.log(error)} - ) + + putRequest(url, payload, (data) => {props.history.goBack()}, (error) => {console.log(error)}) } const handlePost = () => { - let config = getAxiosConfig() - console.log(updatedInfo) + const url = `/learning_objects/${learningObject.id}/publish` + let payload = { "learning_object" : updatedInfo } - console.log(payload) - axios.post((`${apiUrl}/learning_objects/` + learningObject.id + '/publish'), payload, config).then( - (response) => { - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - console.log(response.data); - props.history.push('/recurso/' + learningObject.id) - }, + + postRequest(url, payload, + (data) => {props.history.push( `/recurso/${learningObject.id}`)}, (error) => {console.log(error)} ) + } const [thumbnailStage, setThumbnailStage] = useState('default') @@ -185,79 +156,43 @@ export default function EditLearningObjectPage (props) { } + function handleFinalizeThumb (data) { + if(data.thumbnail) { + setThumbnail(data.thumbnail) + setThumbnailStage('done') + } + } + const finalizeThumb = () => { setThumbnailStage('uploading') - let config = { - headers : { - 'Accept': 'application/json', - 'Content-Type': 'application/json', - } - } - config.headers["access-Token"] = sessionStorage.getItem('@portalmec/accessToken'); - config.headers.client = sessionStorage.getItem('@portalmec/clientToken') - config.headers.uid = sessionStorage.getItem('@portalmec/uid') + + const url = `/learning_objects/${learningObject.id}` let fdThumb = new FormData() fdThumb.set('learning_object[thumbnail]', thumbnail) - axios.put((`${apiUrl}/learning_objects/` + learningObject.id), fdThumb, config).then( - (response) => { - setThumbnailStage('done') - console.log(response.data) - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - if(response.data.thumbnail) { - setThumbnail(response.data.thumbnail) - setThumbnailStage('done') - } - }, - (error) => { - setThumbnailStage('default') - } - ) + + putRequest(url, fdThumb, handleFinalizeThumb, (error) => {setThumbnailStage('default')}) } const handleDeleteThumbnail = () => { - let config = { - headers : { - 'Accept': 'application/json', - 'Content-Type': 'application/json', - } - } - config.headers["access-Token"] = sessionStorage.getItem('@portalmec/accessToken'); - config.headers.client = sessionStorage.getItem('@portalmec/clientToken') - config.headers.uid = sessionStorage.getItem('@portalmec/uid') + const url = `/learning_objects/${learningObject.id}` let fdThumb = new FormData() fdThumb.set('learning_object[thumbnail]', null) - axios.put((`${apiUrl}/learning_objects/` + learningObject.id), fdThumb, config).then( - (response) => { - setThumbnailStage('default') - console.log(response.data) - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - }, - (error) => { - console.log(error) - } - ) + + putRequest(url, fdThumb, (data) => {setThumbnailStage('default')}, (error) => {console.log(error)}) } const chooseRenderStageThumbnail = () => { switch(thumbnailStage) { case 'uploading': return (<LoadingDiv/>) - break; case 'done': return (<DisplayThumbnail acceptFile={acceptFile} thumbnail={`${apiDomain}` + thumbnail} onEditPage={true} handleDelete={handleDeleteThumbnail}/>) - break; case 'editing': return (<EditThumbnail finalizeThumb={finalizeThumb} tempImgURL={tempUrl} updateThumb={updateThumb}/>) - break; default : return (<DragAndDropThumbnail acceptFile={acceptFile} onEditPage={true}/>) - break; } } @@ -277,7 +212,7 @@ export default function EditLearningObjectPage (props) { <div className="container"> <Grid container spacing={2}> <Grid item md={4} xs={12}> - <UploadFileWrapper draftID={recursoId} prevFile={learningObject. attachments ? learningObject.attachments[0] : null}/> + <UploadFileWrapper draftID={recursoId} prevFile={learningObject.attachments ? learningObject.attachments[0] : null}/> </Grid> <Grid item md={8} xs={12}> <InfoBox> @@ -309,11 +244,11 @@ export default function EditLearningObjectPage (props) { <Grid item xs={12} style={{paddingBottom : "40px"}}> <Autor draftID={learningObject.id} initialValue={ - learningObject.author === state.currentUser.username ? + learningObject.author === state.currentUser.name ? 0 : 1 } initialOutroAutor={ - learningObject.author !== state.currentUser.username ? + learningObject.author !== state.currentUser.name ? learningObject.author : '' } onBlurCallback={onBlurCallback} diff --git a/src/Pages/EditProfilePage.js b/src/Pages/EditProfilePage.js index 2d142d5932ada235c199b1e011ff168025afad35..381a2872bd9441e8442b2944dbe1d9daabe70d07 100644 --- a/src/Pages/EditProfilePage.js +++ b/src/Pages/EditProfilePage.js @@ -1,6 +1,5 @@ -import React, {useState, useContext, useEffect} from 'react'; +import React, {useState, useContext} from 'react'; import styled from 'styled-components' -import {Link} from 'react-router-dom' import Tabs from '@material-ui/core/Tabs' import Tab from '@material-ui/core/Tab'; import Paper from '@material-ui/core/Paper'; @@ -8,12 +7,17 @@ import TabPanelEditarPerfil from '../Components/TabPanels/UserPageTabs/PanelEdit import TabPanelSolicitarContaProfessor from '../Components/TabPanels/UserPageTabs/PanelSolicitarContaProfessor.js' import TabPanelGerenciarConta from '../Components/TabPanels/UserPageTabs/PanelGerenciarConta.js' import Snackbar from '@material-ui/core/Snackbar'; -import MuiAlert from '@material-ui/lab/Alert'; import {Alert} from '../Components/LoginModal.js' import Grid from '@material-ui/core/Grid' import CustomizedBreadcrumbs from '../Components/TabPanels/Breadcrumbs.js' +import {putRequest} from '../Components/HelperFunctions/getAxiosConfig' +import {Store} from '../Store.js' export default function EditProfilePage (props) { + const {state, dispatch} = useContext(Store) + const id = state.currentUser.id + + // eslint-disable-next-line const [tabs, setTabs] = useState([ 'Editar Perfil', 'Solicitar conta de Professor', 'Gerenciar Conta' ]) @@ -30,6 +34,47 @@ export default function EditProfilePage (props) { handleSnackbar(false); } + + const updateUserInfo = (newUserInfo) => { + const url = `/users/${id}` + + putRequest(url, newUserInfo, + (data) => {props.history.push('/perfil')}, + (error) => {console.log(error)} + ) + } + + function handleSuccessUpdateEmail (data) { + let auth_headers = JSON.parse(sessionStorage.getItem('@portalmec/auth_headers')) + + auth_headers['uid'] = data.uid + + sessionStorage.setItem('@portalmec/auth_headers', JSON.stringify(auth_headers)) + + const target = state.currentUser + const source = {uid : data.uid} + dispatch({ + type : 'USER_UPDATED_EMAIL', + currUser : Object.assign(target, source) + }) + } + + const updateUserEmail = (newUserInfo) => { + const url = `/users/${id}` + + putRequest(url, newUserInfo, handleSuccessUpdateEmail, (error) => {console.log(error)} + ) + } + + const updateUserPassword = (newUserInfo) => { + const url = `/users/${id}` + + putRequest(url, newUserInfo, + (data) => {handleSnackbar(true)}, + (error) => {console.log(error)} + ) + } + return ( <div style={{backgroundColor:"#f4f4f4", color:"#666"}}> <Snackbar open={snackbarOpened} autoHideDuration={1000} onClose={handleCloseSnackbar} @@ -66,10 +111,12 @@ export default function EditProfilePage (props) { </Grid> <TabContentDiv item xs={9}> <Paper elevation={3} style= {{width:"100%"}}> - {tabValue === 0 && <TabPanelEditarPerfil />} + {tabValue === 0 && <TabPanelEditarPerfil updateUserInfo={updateUserInfo}/>} {tabValue === 1 && <TabPanelSolicitarContaProfessor/>} </Paper> - {tabValue === 2 && <TabPanelGerenciarConta handleSnackbar={() => {handleSnackbar(true)}}/>} + {tabValue === 2 && <TabPanelGerenciarConta updateUserEmail={updateUserEmail} + updateUserPassword={updateUserPassword} + />} </TabContentDiv> </MainContainerDiv> </div> diff --git a/src/Pages/FormationMaterialIframe.js b/src/Pages/FormationMaterialIframe.js new file mode 100644 index 0000000000000000000000000000000000000000..9f59d62f31a3715411690515a2e3dea43b9a6303 --- /dev/null +++ b/src/Pages/FormationMaterialIframe.js @@ -0,0 +1,61 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + +import React from 'react'; +import styled from 'styled-components'; +import colecoes_obj from '../Components/FormationMaterialsResources/formationMaterials.js'; +import IframeOverlay from '../Components/IframeOverlay.js'; + +export default function FormationMaterialIframe(props) { + const colecao = props.location.pathname === "/colecao"; + const colecoes = colecoes_obj(); + + const colecao_id = Number( + colecao ? + props.location.search.split('=')[1] + : props.location.search.split('&')[0].split('=')[1] + ); + const topico_id = Number(colecao ? 0 : props.location.search.split('&')[1].split('=')[1]); + + const colecao_obj = ((id) => { + for (const c in colecoes) { + if (id === colecoes[c].id) + return colecoes[c]; + } + })(colecao_id); + + const topico_obj = ((id) => { + for (const t in colecao_obj.topics) { + if (id === colecao_obj.topics[t].id) + return colecao_obj.topics[t]; + } + })(topico_id); + + return ( + <div> + <StyledIframe src={topico_obj.url} + /> + <IframeOverlay tag={colecao_obj.tags[0].name}/> + </div> + ); +} + +const StyledIframe=styled.iframe` + width: 98.9vw; + height: 83.5vh; + min-height: 300px; +` diff --git a/src/Pages/FormationMaterialPage.js b/src/Pages/FormationMaterialPage.js new file mode 100644 index 0000000000000000000000000000000000000000..2e8d75c00321fc0bd3d738730bc43f9dfb430b51 --- /dev/null +++ b/src/Pages/FormationMaterialPage.js @@ -0,0 +1,126 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ + +import React, { useRef } from 'react'; +import styled from 'styled-components'; +import { Grid } from '@material-ui/core'; +import FormationMaterialHeader from '../Components/FormationMaterialHeader.js'; +import FormationMaterialDescription from '../Components/FormationMaterialDescription.js'; +import TopicList from '../Components/TopicList.js'; +import TopicFooter from '../Components/TopicFooter.js'; +import colecoes_obj from '../Components/FormationMaterialsResources/formationMaterials.js'; + +export default function FormationMaterialPage(props) { + const colecao = props.location.pathname === "/colecao"; + const colecoes = colecoes_obj(); + + const colecao_id = Number( + colecao ? + props.location.search.split('=')[1] + : props.location.search.split('&')[0].split('=')[1] + ); + const topico_id = Number(colecao ? 0 : props.location.search.split('&')[1].split('=')[1]); + + const colecao_obj = ((id) => { + for (const c in colecoes) { + if (id === colecoes[c].id) + return colecoes[c]; + } + })(colecao_id); + + const topico_obj = ((id) => { + for (const t in colecao_obj.topics) { + if (id === colecao_obj.topics[t].id) + return colecao_obj.topics[t]; + } + })(topico_id); + + const topic_list_ref = useRef(null); + + const handleHeaderClick = () => { + if (colecao) + window.scrollTo(0, topic_list_ref.current.offsetTop); + } + + console.log(colecao_obj); + + return ( + <Background> + <MainContainer> + <Grid container + direction="row" + justify="flex-start" + alignItems="center" + > + <Grid item xs={12}> + <FormationMaterialHeader + colecao={colecao} + colecao_obj={colecao_obj} + topico_obj={topico_obj} + handleClick={handleHeaderClick} + /> + </Grid> + <Grid item xs={12}> + <FormationMaterialDescription + colecao={colecao} + colecao_obj={colecao_obj} + topico_obj={topico_obj} + /> + </Grid> + <Grid item xs={12} ref={topic_list_ref}> + { + colecao ? + <TopicList + topicos={colecao_obj.topics} + colecao_id={colecao_id} + /> + : + <div></div> + } + </Grid> + </Grid> + </MainContainer> + { colecao ? + <div></div> + : + <TopicFooter + topic_name={colecao_obj.topic_name} + src={colecao_obj.img} + colecao_name={colecao_obj.name}/> + } + </Background> + ); +} + +const Background=styled.div` + background-color: #f4f4f4; +` +const MainContainer=styled.div` + margin-left: auto; + margin-right: auto; + padding : 0; + + @media screen and (min-width: 768px) { + width : 750px; + } + @media screen and (min-width: 992px) { + width : 970px; + } + @media screen and (min-width: 1200px) { + width : 1170px; + } +` diff --git a/src/Pages/HelpCenter.js b/src/Pages/HelpCenter.js index 4151f5d7e5ff0d6921deed2be52f1b519343c055..f70481b0db11f0001894d7909721f1f293758eca 100644 --- a/src/Pages/HelpCenter.js +++ b/src/Pages/HelpCenter.js @@ -16,7 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { Component, useState, useEffect } from 'react'; +import React from 'react'; import styled from 'styled-components'; import Grid from '@material-ui/core/Grid'; import { Link } from 'react-router-dom'; @@ -34,13 +34,20 @@ import CardGerenciando from '../Components/HelpCenter/Cards/CardGerenciando'; function HelpCenter(props) { + let windowWidth = window.innerWidth + return( <div style={{backgroundColor: "#f4f4f4"}}> <link href="https://fonts.googleapis.com/css?family=Pompiere|Roboto:300,400&display=swap" rel="stylesheet"/> <Secao1> <div className= "container"> - <img src={Banner3} alt="banner3"/> + { + windowWidth > 420? + <img src={Banner3} alt="banner3"/> + : + <div/> + } <div className= "conteudo"> <div className= "title"> <h2>OLÁ! COMO PODEMOS AJUDAR?</h2> @@ -57,17 +64,17 @@ function HelpCenter(props) { <h2>Tópicos de Ajuda</h2> </div> <div> - <Grid container spacing={2}> - <Grid item xs={3}> + <Grid container justify="center" style={{margin:-8}}> + <Grid item xs={12} md={5} style={{padding:8}}> <CardPublicando/> </Grid> - <Grid item xs={3}> + <Grid item xs={12} md={5} style={{padding:8}}> <CardEncontrando/> </Grid> - <Grid item xs={3}> + <Grid item xs={12} md={5} style={{padding:8}}> <CardParticipando/> </Grid> - <Grid item xs={3}> + <Grid item xs={12} md={5} style={{padding:8}}> <CardGerenciando/> </Grid> </Grid> @@ -77,64 +84,66 @@ function HelpCenter(props) { </div> </Secao2> - + <div style={{width:"100%"}}> <Secao3> - <Grid style={{height:"100%"}} container spacing={2}> - <Grid style={{backgroundColor: "#333",paddingInline:"0" }} item xs={6}> - <iframe src="https://player.vimeo.com/video/231609051" width="100%" height="100%" frameborder="0" allow="autoplay; fullscreen" allowfullscreen></iframe> - </Grid> - <Grid item xs={6}> - <p className="titulo-sobre-ajuda">Plataforma MEC de Recursos Educacionais Digitais</p> - <p className="conteudo-sobre-ajuda"> - Construa conosco a plataforma e amplie sua rede de conhecimento<br/> - interagindo com pessoas envolvidas com experiências que ocorrem<br/> - em todo o Brasil! - </p> - <hr/> - <Grid container spacing={1}> - <Grid item xs={6}> - <p className="links"> - <br/> - <Link to={{ - pathname : 'plataforma-mec', - state : {value : '0'} - }}>O que é a Plataforma MEC</Link> - <br/> - <Link to={{ - pathname : 'plataforma-mec', - state : {value : '1'} - }}>Como foi construida a Plataforma<br/>MEC?</Link> - <br/> - <Link to={{ - pathname : 'plataforma-mec', - state : {value : '3'} - }}>Quais são os Portais Parceiros?</Link> - </p> - </Grid> - <Grid item xs={6}> - <p className="links"> - <br/> - <Link to={{ - pathname : 'plataforma-mec', - state : {value : '2'} - }}>Entendendo as 3 áreas</Link> - <br/> - <Link to={{ - pathname : 'plataforma-mec', - state : {value : '4'} - }}>Tipos de recursos</Link> - <br/> - <Link to={{ - pathname : 'plataforma-mec', - state : {value : '5'} - }}>Softwares específicos</Link> + <Grid style={{height:"100%"}} container justify="center"> + <Grid style={{backgroundColor: "#333",paddingInline:"0" }} item xs={12} md={6}> + <iframe title="Vídeo página ajuda" src="https://player.vimeo.com/video/231609051" width="100%" height="100%" frameborder="0" allow="autoplay; fullscreen" allowfullscreen></iframe> + </Grid> + <Grid item xs={12} md={6}> + <div> + <p className="titulo-sobre-ajuda">Plataforma MEC de Recursos Educacionais Digitais</p> + <p className="conteudo-sobre-ajuda"> + Construa conosco a plataforma e amplie sua rede de conhecimento + interagindo com pessoas envolvidas com experiências que ocorrem + em todo o Brasil! </p> + </div> + <Grid container> + <Grid item xs={12} md={6}> + <p className="links"> + <br/> + <Link to={{ + pathname : 'plataforma-mec', + state : {value : '0'} + }}>O que é a Plataforma MEC</Link> + <br/> + <Link to={{ + pathname : 'plataforma-mec', + state : {value : '1'} + }}>Como foi construida a Plataforma<br/>MEC?</Link> + <br/> + <Link to={{ + pathname : 'plataforma-mec', + state : {value : '3'} + }}>Quais são os Portais Parceiros?</Link> + </p> + </Grid> + <Grid item xs={12} md={6}> + <p className="links"> + <br/> + <Link to={{ + pathname : 'plataforma-mec', + state : {value : '2'} + }}>Entendendo as 3 áreas</Link> + <br/> + <Link to={{ + pathname : 'plataforma-mec', + state : {value : '4'} + }}>Tipos de recursos</Link> + <br/> + <Link to={{ + pathname : 'plataforma-mec', + state : {value : '5'} + }}>Softwares específicos</Link> + </p> + </Grid> </Grid> - </Grid> + </Grid> </Grid> - </Grid> - </Secao3> + </Secao3> + </div> <Secao4> <div className="container"> @@ -142,7 +151,7 @@ function HelpCenter(props) { <h2>Não encontrou o que você precisa?</h2> <span>Entre em contato com a nossa Central de Ajuda</span> <br/> - <button><a href="contato">ENTRAR EM CONTATO</a></button> + <button style={{marginBottom:50, marginTop:20}}><a href="contato">ENTRAR EM CONTATO</a></button> </div> </div> @@ -156,27 +165,25 @@ export default HelpCenter; const Secao1 = styled.div` - height: 374px; background-color:#00bcd4; text-align: center; + width: 100%; .container { height: 100%; - width: 1170px; display: flex; -webkit-box-pack: center; justify-content: center; -webkit-box-align: center; align-items: center; - padding-right: 15px; padding-left: 15px; margin-right: auto; margin-left: auto; img { position: relative; - left: 82px; top: 41.6%; - width: 230px; + max-width: 230px; + width: 90%; float: left; min-height: 1px; padding-right: 15px; @@ -208,14 +215,13 @@ const Secao1 = styled.div` ` const Secao2 = styled.div` - height: 536px; background-color:#f4f4f4; text-align: center; margin-bottom: 20px; - + padding-bottom: 50px + width: 100%; .container { height: 100%; - width: 1170px; margin-right: auto; margin-left: auto; @@ -243,7 +249,7 @@ const Secao2 = styled.div` .card { height: 280px; - padding: 40px 15px; + padding: 40px 0px; text-align: center; font-size: 14px; background-color:#fff; @@ -258,13 +264,6 @@ const Secao2 = styled.div` line-height: 1.1; } - hr { - margin-top: 20px; - margin-bottom: 20px; - border: 0; - border-top: 1px solid #eee; - color: #a5a5a5; - } a { font-size: 15px; @@ -321,14 +320,12 @@ const Secao2 = styled.div` ` const Secao3 = styled.div` - height: 375px; padding: 0; text-align: center; background-color: #fff; - width: 1170px; margin-inline: auto; color: rgba(0,0,0,0.87); - + width: 100%; .links { font-size: 15px; font-weight: lighter; @@ -356,26 +353,16 @@ const Secao3 = styled.div` margin: 0 0 10px; } - hr { - width: 350px; - border: 0; - border-top: 1px solid #ccc; - margin-top: 20px; - margin-bottom: 20px; - - } ` const Secao4 = styled.div` - height: 290px; - + width: 100%; .container { height: 100%; color: #a5a5a5; - width: 1170px; margin-inline: auto; display: flex; flex-direction: column; diff --git a/src/Pages/ItemStore.js b/src/Pages/ItemStore.js index ce8855c0306f2542b67b0f2db18bf2d0f1086a8b..45c3649d1a69a5535dcaee82960343f373527745 100644 --- a/src/Pages/ItemStore.js +++ b/src/Pages/ItemStore.js @@ -15,13 +15,10 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useState, useContext, useEffect} from 'react'; +import React, {useState, useEffect} from 'react'; import styled from 'styled-components'; import axios from 'axios'; import Grid from '@material-ui/core/Grid'; -import Card from '@material-ui/core/Card'; -import CardActions from '@material-ui/core/CardActions'; -import CardContent from '@material-ui/core/CardContent'; import Container from '@material-ui/core/Container'; import UserCardGamified from '../Components/UserCardGamified.js'; import StoreGuide from '../Components/StoreGuide.js'; @@ -53,7 +50,7 @@ export default function ItemStoreContainer (props) { useEffect(() => { axios.all( ['avatar_frame', 'card_frame', 'cover_frame', 'badge'].map((r) => { - return axios.get(apiUrl+'/' + 'user_items/index?item_type='+r+'&unlock_rule=purchase'); + return axios.get(`${apiUrl}/user_items/index?item_type=${r}&unlock_rule=purchase`); })).then(axios.spread((avatar, card, cover, badge) => { setAvatarFrames(avatar); setCardFrames(card); diff --git a/src/Pages/PageProfessor.js b/src/Pages/PageProfessor.js index 8a2783de2e3ce40c466d4747f56d2565bcd3d377..6ee8588e27a0ba57100336e6da714c2c938f1acd 100644 --- a/src/Pages/PageProfessor.js +++ b/src/Pages/PageProfessor.js @@ -1,14 +1,12 @@ import React, {useState,useContext} from 'react' import {Store} from '../Store.js' -import styled from 'styled-components' import Paper from '@material-ui/core/Paper'; import PartOne from '../Components/PageProfessorComponents/PartOne.js' import PartTwo from '../Components/PageProfessorComponents/PartTwo.js' import PartThree from '../Components/PageProfessorComponents/PartThree.js' import SuccessfulRequest from '../Components/PageProfessorComponents/SuccessfulRequest.js' import ModalConfirmarProfessor from '../Components/PageProfessorComponents/ModalConfirmarProfessor.js' -import axios from 'axios' -import {apiUrl} from '../env'; +import {postRequest} from '../Components/HelperFunctions/getAxiosConfig' export default function PageProfessor (props) { const {state} = useContext(Store) @@ -50,7 +48,6 @@ export default function PageProfessor (props) { } const handleBuscarParteUm = (ufAbbreviation, ufName, nomeMunicipio, inep) => { - console.log('handleBuscarParteUm: ', ufAbbreviation, ufName, nomeMunicipio, inep) setRegisterInformation({...registerInformation, school_uf : { abbreviation: (ufAbbreviation ? ufAbbreviation : ''), @@ -91,27 +88,24 @@ export default function PageProfessor (props) { props.history.push('/perfil/atualizacoes') } + function handleSuccessfulSubmit (data) { + toggleModal() + toggleStepper(false, false, false, true) + } + const handleFinalSubmit = () => { - //adicionar headers de accessToken - axios.post( `${apiUrl}/users/teacher_request`, { + const url = `/users/teacher_request` + + const payload = { city : registerInformation.school_city.name, cpf : registerInformation.teacher_cpf, inep_id : registerInformation.inep_code, phone : registerInformation.school_phone, school : registerInformation.school_name, uf : registerInformation.school_uf.name - }, - { headers : { - 'Access-Token': sessionStorage.getItem('@portalmec/accessToken'), - 'Client': sessionStorage.getItem('@portalmec/clientToken'), - 'Uid': sessionStorage.getItem('@portalmec/uid') - }} - ) - .then( (response) => { - toggleModal() - toggleStepper(false, false, false, true) - }, (error) => console.log('deu erro') - ) + } + + postRequest(url, payload, handleSuccessfulSubmit, (error) =>{console.log(error)}) } return ( @@ -119,7 +113,6 @@ export default function PageProfessor (props) { { state.userAgreedToPublicationTerms? ( - [ <> <ModalConfirmarProfessor open={modalOpen} handleClose={handleModal} info={registerInformation} confirmar = {() => {handleFinalSubmit()}} @@ -155,7 +148,6 @@ export default function PageProfessor (props) { </div> </div> </> - ] ) : ( diff --git a/src/Pages/PasswordRecoveryPage.js b/src/Pages/PasswordRecoveryPage.js index 82038103ec38d07b3cedb99394d567b9f62b2f22..010a164ba112a342e7e01e14fc2c5ba2bc38a1ff 100644 --- a/src/Pages/PasswordRecoveryPage.js +++ b/src/Pages/PasswordRecoveryPage.js @@ -1,22 +1,15 @@ -import React, {useState, useContext} from 'react' +import React, {useState} from 'react' import {BackgroundDiv} from '../Components/TabPanels/StyledComponents.js' -import {Link} from 'react-router-dom' import Paper from '@material-ui/core/Paper'; import styled from 'styled-components' -import FormInput from "../Components/FormInput.js" -import ValidateUserInput from '../Components/FormValidationFunction.js' -import {CompletarCadastroButton} from '../Components/TabPanels/UserPageTabs/PanelSolicitarContaProfessor.js' +import ValidateUserInput from '../Components/HelperFunctions/FormValidationFunction.js' import Default from '../Components/PasswordRecoveryComponents/Default.js' import Success from '../Components/PasswordRecoveryComponents/Success.js' import CaseError from '../Components/PasswordRecoveryComponents/Error.js' -import {Store} from '../Store.js' import CustomizedBreadcrumbs from '../Components/TabPanels/Breadcrumbs.js' -import {apiUrl, apiDomain} from '../env'; -import axios from 'axios' - +import {postRequest} from '../Components/HelperFunctions/getAxiosConfig' export default function PasswordRecoveryPage (props) { - const {state, dispatch} = useContext(Store) const [formEmail, setEmail] = useState( { @@ -45,18 +38,21 @@ export default function PasswordRecoveryPage (props) { setCase(value) }; + function handleSuccessfulSubmit (data) { + handleChangeSwitch((data.success ? "success" : "error")) + } const onSubmit = (e) => { e.stopPropagation() + + const url = `/auth/password` + const payload = { "email" : formEmail.value, "redirect_url" : "https://plataformaintegrada.mec.gov.br/recuperar-senha#/alterar-senha" } - axios.post((`${apiUrl}/auth/password`), payload).then( - (response) => { - console.log(response) - handleChangeSwitch(response.data.success ? "success" : "error") - }, - (error) => {console.log(error)}) + + postRequest(url, payload, handleSuccessfulSubmit, (error) => {console.log(error)}) + } @@ -70,13 +66,10 @@ export default function PasswordRecoveryPage (props) { switch(value) { case 'success': return components.success; - break; case 'error': return components.error; - break; default: return components.default - break; } } diff --git a/src/Pages/ProfilePage.js b/src/Pages/ProfilePage.js deleted file mode 100644 index 6959ad9357650785a7088ddbb25ac0a0ac3bffe1..0000000000000000000000000000000000000000 --- a/src/Pages/ProfilePage.js +++ /dev/null @@ -1,30 +0,0 @@ -/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre -Departamento de Informatica - Universidade Federal do Parana - -This file is part of Plataforma Integrada MEC. - -Plataforma Integrada MEC is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -Plataforma Integrada MEC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ - -import React, {Component} from 'react'; - - -class ProfilePage extends Component { - render() { - return ( - <h1> Página visulizar prefil de usuário</h1> - ); - } - } - -export default ProfilePage; diff --git a/src/Pages/PublicUserPage.js b/src/Pages/PublicUserPage.js index 2c38097a295c96674ee4935aa944af8a223181c7..2000c8619371ba81c0b8ea395ede083935a4a1de 100644 --- a/src/Pages/PublicUserPage.js +++ b/src/Pages/PublicUserPage.js @@ -18,18 +18,14 @@ along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/> import React, {useEffect, useState} from 'react' import styled from 'styled-components' -import axios from 'axios' -import {apiUrl, apiDomain} from '../env'; +import {apiDomain} from '../env'; import CustomizedBreadcrumbs from '../Components/TabPanels/Breadcrumbs.js' -import {Link} from 'react-router-dom'; import Grid from '@material-ui/core/Grid'; import FollowButton from '../Components/ContactButtons/FollowButton.js' import FollowingButton from '../Components/ContactButtons/FollowingButton.js' import FollowersCountButton from '../Components/ContactButtons/FollowersCountButton.js' import noAvatar from "../img/default_profile.png"; -import Button from '@material-ui/core/Button'; import Tab from '@material-ui/core/Tab'; -import Tabs from '@material-ui/core/Tabs'; import TabInicio from '../Components/TabPanels/PublicUserPageTabs/TabInicio.js' import TabRecursos from '../Components/TabPanels/PublicUserPageTabs/TabRecursos.js' import TabColecoes from '../Components/TabPanels/PublicUserPageTabs/TabColecoes.js' @@ -37,6 +33,7 @@ import TabRede from '../Components/TabPanels/PublicUserPageTabs/TabRede.js' import CheckDecagram from '../img/check-decagram-blue.svg' import ReportButton from '../Components/ReportButton.js' import {HeaderContainer, UserProfileContainer, CoverContainer, UserProfileInfoDiv, StyledTabs, CheckTeacherDiv, RodapeDiv, NavBarContentContainer, BackgroundDiv} from '../Components/TabPanels/StyledComponents.js' +import {fetchAllRequest} from '../Components/HelperFunctions/getAxiosConfig' const RenderFollowContainer = (boolUserFollowed, id, followCount) => { return ( @@ -88,7 +85,7 @@ const RenderCheckTeacher = (submitter_request) => { <CheckTeacherDiv> <p> <span> - <img src={CheckDecagram}/> + <img alt="" src={CheckDecagram}/> </span> Professor(a) </p> @@ -107,6 +104,7 @@ export default function PublicUserPage (props) { /*---------------------------------------------------------*/ /*content control variables--------------------------------*/ + // eslint-disable-next-line const [tabs, setTabs] = useState([ 'Início', 'Recursos', 'Coleções', 'Rede' ]) @@ -123,38 +121,19 @@ export default function PublicUserPage (props) { const handleCollections = (data) => {setCollections(data)} /*---------------------------------------------------------*/ + function handleSuccess (responseArr) { + fillUserInfo(responseArr[0]) + + handleLearningObjects(responseArr[1]) + + handleCollections(responseArr[2]) + } /*Component Will Mount*/ useEffect( () => { - let config = { - headers : { - 'Accept': 'application/json', - 'Content-Type': 'application/json', - 'Access-Token': sessionStorage.getItem('@portalmec/accessToken'), - 'Client': sessionStorage.getItem('@portalmec/clientToken'), - 'Uid': sessionStorage.getItem('@portalmec/uid'), - } - } - axios.all([ - axios.get( (`${apiUrl}/users/` + id ), config ), - axios.get( (`${apiUrl}/users/` + id + '/learning_objects'), {'Accept': 'application/json','Content-Type':'application/json'}), - axios.get( (`${apiUrl}/users/` + id + '/collections'), {'Accept': 'application/json','Content-Type':'application/json'}) - ]) - .then( (responseArr) => { - - console.log(responseArr) - fillUserInfo(responseArr[0].data) - - console.log(responseArr[1]) - handleLearningObjects(responseArr[1].data) - - console.log(responseArr[2]) - handleCollections(responseArr[2].data) - }, - (error) => { - console.log('error while running ComponentDidMout') - } - ) + const urls = [`/users/${id}`, `/users/${id}/learning_objects`, `/users/${id}/collections`] + + fetchAllRequest(urls, handleSuccess, (error) => {console.log(error)}) }, []) /*---------------------------------------------------------*/ @@ -172,7 +151,7 @@ export default function PublicUserPage (props) { <HeaderContainer> <> {RenderFollowContainer(userData.followed, id, userData.follows_count)} - {RenderProfileAvatar(userData.avatar ? userData.avatar : noAvatar)} + {RenderProfileAvatar(userData.avatar ? userData.avatar : undefined)} <CoverContainer> {userData.cover && <img src={apiDomain + userData.cover} alt = '' style= {{width:"100%", height:"100%", objectFit : "cover" }}/>} </CoverContainer> @@ -194,7 +173,7 @@ export default function PublicUserPage (props) { { tabs.map( (tab) => <Tab label={tab} key={tab} - disabled={tab === "Recursos" && learningObjArr.length === 0 || tab === "Coleções" && collectionsArr.length === 0} + disabled={(tab === "Recursos" && learningObjArr.length === 0) || (tab === "Coleções" && collectionsArr.length === 0)} /> ) } @@ -210,7 +189,7 @@ export default function PublicUserPage (props) { {tabValue === 0 && <TabInicio id={id} user={userData} learningObjs={learningObjArr} collections={collectionsArr}/>} {tabValue === 1 && - <TabRecursos count={userData.learning_objects_count} learningObjs={learningObjArr}/>} + <TabRecursos count={userData.learning_objects_count} learningObjs={learningObjArr} id={id}/>} {tabValue === 2 && <TabColecoes count={userData.collections_count} collections={collectionsArr} />} diff --git a/src/Pages/PublicationPermissionsPage.js b/src/Pages/PublicationPermissionsPage.js index 0c113cd2845698182acdc1ffde54c5bca393b889..d7dcb6ac34900cb4155629e3382997be37650f10 100644 --- a/src/Pages/PublicationPermissionsPage.js +++ b/src/Pages/PublicationPermissionsPage.js @@ -120,6 +120,9 @@ export default function PermissionsContainer(props) { props.history.push("/termos-publicar-recurso"); }; + const redirectToHome = () => { + props.history.push("/"); + }; return ( <> {state.userAgreedToPublicationTerms ? ( @@ -180,7 +183,7 @@ export default function PermissionsContainer(props) { backgroundColor: "#e9e9e9", }} > - <Styledspan style={{ color: "rgb(102, 102, 102)" , fontWeight : "600 !important"}}> + <Styledspan style={{ color: "rgb(102, 102, 102)" , fontWeight : "600 !important"}} onClick={() => {redirectToHome()}}> Cancelar </Styledspan> </Button> diff --git a/src/Pages/ResourcePage.js b/src/Pages/ResourcePage.js index 9ed188d5fd6539de5da9d98253e1921c5f91a3b2..194807e62cc60998b5b1f470a2bf7decc803fef4 100644 --- a/src/Pages/ResourcePage.js +++ b/src/Pages/ResourcePage.js @@ -19,8 +19,7 @@ along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/> import React, {useEffect, useState, useContext} from 'react' import {Store} from '../Store.js' import styled from 'styled-components' -import axios from 'axios' -import {apiUrl, apiDomain} from '../env'; +import {apiDomain} from '../env'; import Grid from '@material-ui/core/Grid'; import TextoObjeto from '../Components/ResourcePageComponents/TextoObjeto.js' import Footer from '../Components/ResourcePageComponents/Footer.js' @@ -36,7 +35,7 @@ import AppBar from '@material-ui/core/AppBar'; import ButtonAvaliarRecurso from '../Components/ButtonAvaliarRecurso' import ModalAvaliarRecurso from '../Components/ModalAvaliarRecurso' import ModalConfirmarCuradoria from '../Components/ModalConfirmarCuradoria' -import {getAxiosConfig} from '../Components/HelperFunctions/getAxiosConfig' +import {getRequest} from '../Components/HelperFunctions/getAxiosConfig' function urlVerify (url) { return (url ? url.indexOf("youtu") !== -1 || url.indexOf("vimeo") !== -1 : false) @@ -48,29 +47,16 @@ export default function LearningObjectPage (props){ const [carregando, toggle] = useState(true) const [recurso, setRecurso] = useState({}) + function handleSuccessfulGet (data) { + setRecurso(data) + toggle(false) + } useEffect( () => { - let config = { - headers : { - 'Accept': 'application/json', - 'Content-Type': 'application/json', - } - } - if (state.currentUser.id !== "") { - config.headers["Access-Token"] = sessionStorage.getItem('@portalmec/accessToken'); - config.headers.Client = sessionStorage.getItem('@portalmec/clientToken') - config.headers.Uid = sessionStorage.getItem('@portalmec/uid') - } + const url = `/learning_objects/${id}` - axios.get( (`${apiUrl}/learning_objects/` + id), config - ).then( (response) => { - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - console.log(response) - setRecurso(response.data) - toggle(false) - }, (error) => {console.log(error);}) - }, [, state.currentUser]) + getRequest(url, handleSuccessfulGet, (error) => {console.log(error)}) + + }, []) const [snackbarOpen, toggleSnackbar] = useState(false) @@ -88,7 +74,7 @@ export default function LearningObjectPage (props){ const handleModalCuradoria = (value) => {toggleModalCuradoria(value)} const checkAccessLevel = (levelToCheck) => { - if (state.currentUser.id != '') { + if (state.currentUser.id !== '') { return(checkUserRole(levelToCheck)) } else { @@ -118,15 +104,8 @@ export default function LearningObjectPage (props){ const finalizeCuratorshipFlow = () => { handleModalConfirmarCuradoria(false) - let config = getAxiosConfig() - axios.get( (`${apiUrl}/learning_objects/` + id), config - ).then( (response) => { - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - console.log(response) - setRecurso(response.data) - }, (error) => {console.log(error);}) + const url = `/learning_objects/${id}` + getRequest(url, (data) => {setRecurso(data)}, (error) => {console.log(error)}) } return ( @@ -185,7 +164,7 @@ export default function LearningObjectPage (props){ <Card> <div> {recurso.thumbnail && - <img src={apiDomain + recurso.thumbnail}/> + <img alt="" src={apiDomain + recurso.thumbnail}/> } @@ -218,7 +197,6 @@ export default function LearningObjectPage (props){ title={recurso.name} thumb={recurso.thumbnail} currPageLink={window.location.href} - handleSnackbar={handleSnackbar} complained={recurso.complained} /> </Card> diff --git a/src/Pages/Search.js b/src/Pages/Search.js index 50234337bc6dc86c83545d9722f6febe3982c706..8648fbaf61b2a2f986dce3186432ca33454a381d 100644 --- a/src/Pages/Search.js +++ b/src/Pages/Search.js @@ -18,221 +18,381 @@ along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/> import React, { useEffect, useState, useContext } from "react"; import axios from "axios"; +import { apiDomain } from '../env'; import { Link } from "react-router-dom"; import styled from "styled-components"; import Paper from "@material-ui/core/Paper"; - +import LoadingSpinner from '../Components/LoadingSpinner'; // import ResourceCard from '../Components/ResourceCard' // import CollectionCard from '../Components/CollectionCard' // import UserCard from '../Components/UserCard' +// import Select from "react-dropdown-select"; import Breadcrumbs from "@material-ui/core/Breadcrumbs"; import { apiUrl } from "../env"; import "./Styles/Home.css"; import { Store } from "../Store"; import { Grid } from "@material-ui/core"; -import Dropdown from 'react-dropdown' -import 'react-dropdown/style.css' +import Dropdown from "react-dropdown"; +import "react-dropdown/style.css"; import SearchExpansionPanel from "../Components/SearchExpansionPanel/SearchExpansionPanel"; -import ResourceCard from "../Components/ResourceCard"; +import ResourceCardFunction from "../Components/ResourceCardFunction"; +import CollectionCardFunction from "../Components/CollectionCardFunction"; +import ContactCard from "../Components/ContactCard"; +import CircularProgress from '@material-ui/core/CircularProgress'; +import { saveHeaders } from '../Components/HelperFunctions/saveTokens'; +import {getRequest} from '../Components/HelperFunctions/getAxiosConfig' + + +let order = "review_average"; +let currFilter = ""; export default function Search(props) { const { state, dispatch } = useContext(Store); - const [results, setResults] = useState([]); + const [resultsResource, setResultsResource] = useState([]); + const [resultsCollection, setResultsCollection] = useState([]); + const [resultsUser, setResultsUser] = useState([]); + const [currOrder, setCurrOrder] = useState(order); const [page] = useState(0); + const [isloading, setIsLoading] = useState(false); + const [loadingMoreData, setLoadingMoreData] = useState(false); + const [isFiltering, setIsFiltering] = useState(false); const [resultsPerPage, setResultsPerPage] = useState(12); - const [order] = useState("score"); - const options = [ - - {value:"LearningObject", label:"Recursos"}, - {value:"Collection", label:"Coleções"}, - {value:"User", label:"Usuários"} - - ]; - const ordenar = [ - {label:"Mais Estrelas"}, - {label:"Mais Relevante"}, - {label:"Mais Baixados"}, - {label:"Mais Favoritados"}, - {label:"Mais Recentes"}, - {label:"Ordem Alfabética"}, - ]; - - const [defaultOption,setDefaultOption] =useState( options[0]); - const [defaultOrder,setDefaultOrder] =useState( ordenar[0]); - - const collectStuff = (tipoBusca=state.search.class,option=undefined) => { - - axios - .get( - `${apiUrl}/search?page=${page}&results_per_page=${resultsPerPage}&order=${order}&query=${state.search.query}&search_class=${tipoBusca}` - ) - .then(res => { - setResults(res.data); - if (option != undefined) { - let aux = undefined; - for (let i=0; i < options.length;i=i+1){ - - console.log("Vamo dale0") - if (options[i].label==option){ - console.log("Vamo dale") - setDefaultOption(options[i]); - - } - } + const [totalResults, setTotalResults] = useState(0); + const [options] = React.useState([ + { label: "Recursos", value: "LearningObject" }, + { label: "Coleções", value: "Collection" }, + { label: "Usuários", value: "User" }, + ]); + const [ordenar] = useState([ + { label: "Mais Estrelas", value: "review_average" }, + { label: "Mais Relevante", value: "score" }, + { label: "Mais Baixados", value: "downloads" }, + { label: "Mais Favoritados", value: "likes" }, + { label: "Mais Recentes", value: "publicationdesc" }, + { label: "Ordem Alfabética", value: "title" }, + ]); + + const [option, setOption] = useState( + new URLSearchParams(window.location.search).get("search_class") + ); + const [optionResult, setOptionResult] = useState(option); + + function handleSuccessfulGet (data) { + if (option === "LearningObject") setResultsResource(data); + else if (option === "Collection") setResultsCollection(data); + else if (option === "User") setResultsUser(data); + setOptionResult(option); + dispatch({ + type: "SAVE_SEARCH", + newSearch: { + query: state.search.query, + class: option, + }, + }); + setTotalResults(data.length); + setIsLoading(false); + setIsFiltering(false); + setLoadingMoreData(false); + } - } - console.log(res.data); - console.log(tipoBusca); - })}; + const collectStuff = (tipoBusca, filtro) => { + if (!loadingMoreData) // this line prevents resetting filter when loading more data + currFilter = filtro; + if (filtro) + setIsFiltering(true); + + const url = `/search?page=${page}&results_per_page=${resultsPerPage}&order=${order}&query=${state.search.query}${currFilter ? currFilter : ""}&search_class=${tipoBusca}` + + getRequest(url, handleSuccessfulGet, (error) => {console.log(error)}) + + }; useEffect(() => { dispatch({ type: "HANDLE_SEARCH_BAR", - opened: false + opened: false, }); const urlParams = new URLSearchParams(window.location.search); const query = urlParams.get("query"); const searchClass = urlParams.get("search_class"); - console.log(searchClass); if (state.search.query !== query || state.search.class !== searchClass) { dispatch({ type: "SAVE_SEARCH", newSearch: { query: query, - class: searchClass - } + class: searchClass, + }, }); } return () => dispatch({ type: "HANDLE_SEARCH_BAR", - opened: false + opened: false, }); }, []); - useEffect(() => { - collectStuff(); - }, [state.search, resultsPerPage]); - - - + collectStuff(option); + }, [resultsPerPage]); return ( <div style={{ backgroundColor: "#f4f4f4" }}> - <React.Fragment> - <h1> - Search for {state.search.query !== "*" ? state.search.query : "all"}{" "} - in {state.search.class} - </h1> - {state.search.class === "LearningObject" && ( - <ul> - {results.map(res => ( - <li key={res.id}> {res.name} </li> - ))} - </ul> - )} - {state.search.class === "Collection" && ( - <ul> - {results.map(res => ( - <li key={res.id}> {res.name} </li> - ))} - </ul> - )} - {state.search.class === "User" && ( - <ul> - {results.map(res => ( - <li key={res.id}> {res.name} </li> - ))} - </ul> - )} - </React.Fragment> - <Principal> - <BreadCrumbsDiv> + <BreadCrumbsDiv style={{margin:"15px 2%", }}> <StyledBreadCrumbs> <Link to="/">Página Inicial</Link> <span>Busca</span> </StyledBreadCrumbs> </BreadCrumbsDiv> - <HeaderFilters elevation={4} square> - <Grid container spacing={0} style={{ height: "100%" }}> - <Grid - item - xs={4} - style={{ - display: "flex", - flexDirection: "column", - justifyContent: "center" - }} - > - <div style={{display:"flex",flexDirection:"row"}}> - <div style={{ textAlign: "left" }}>Mostrar</div> - <Dropdown options={options} onChange={()=>{collectStuff(options.value,options.label )}} value={defaultOption} placeholder="Select an option" /> - - </div> - </Grid> - <Grid - item - xs={4} - style={{ - display: "flex", - flexDirection: "column", - justifyContent: "center" - }} - > - <div>Numero</div> - </Grid> - <Grid - item - xs={4} - style={{ - display: "flex", - flexDirection: "column", - justifyContent: "center" - }} - > - <div style={{ textAlign: "right" }}>Ordenar por:</div> - <Dropdown options={ordenar} onChange={()=>{collectStuff(ordenar.label )}} value={defaultOrder} placeholder="Select an order "/> - </Grid> - </Grid> - </HeaderFilters> - <GridBusca container spacing={2}> - <Grid item md={3} xs={12}> - <Paper elevation={4} square> - <SearchExpansionPanel /> - </Paper> - </Grid> - <Grid item md={9} xs={12}> - <Grid container spacing={2}> - {results.map(card => ( - <Grid item md={4} xs={6} key={card.id}> - <ResourceCard - name={card.name} - rating={card.score} - type={card.object_type} - description={card.description} - thumbnail={card.thumbnail} - author={card.author} - avatar={card.publisher.avatar} + + <div style={{margin:"15px 2%", }}> + <HeaderFilters elevation={4} square> + <Grid container spacing={0} style={{ height: "100%" }}> + <Grid item xs style={{display:"flex", flexDirection:"column", justifyContent:"center", paddingLeft:20}}> + <div style={{ marginRight:5, marginTop:15 }}> + <div className="textInfo"> + <span style={{ fontWeight:"bold" }}> + MOSTRAR + </span> + </div> + <Dropdown options={options} value={optionResult} onChange={(e) => { + setIsLoading(true); + setOption(e.value); + collectStuff(e.value, ""); + }} + placeholder="Selecione um tipo" /> - </Grid> - ))} + </div> + </Grid> + + { + optionResult === "User" ? null : + <Grid item xs style={{display: "flex", flexDirection: "column", justifyContent: "center", paddingRight: 20,}}> + <div style={{marginLeft:5, marginTop:15}}> + <div className="textInfo"> + <span style={{ fontWeight:"bold" }}> + ORDENAR POR + </span> + </div> + <Dropdown options={ordenar} value={currOrder} onChange={(e) => { + order = e.value; + setCurrOrder(e.label) + collectStuff(optionResult, currFilter); + }} + placeholder="Selecione uma opção" + /> + </div> + </Grid> + } + <Grid item xs={12}> + <div style={{display: "flex", flexDirection: "column", justifyContent: "center" }}> + <div style={{textAlign: "center", paddingTop: 10, fontWeight:"bolder"}}> + {/* Exibindo {totalResults === 0 ? 0 : resultsPerPage} resultados de {totalResults} encontrados */} + Exibindo {totalResults === 0 ? 0 : resultsPerPage} resultados + </div> + </div> + </Grid> </Grid> - <button onClick={() => setResultsPerPage(resultsPerPage + 12)}> - Número de recursos mostrados {resultsPerPage} - </button> - </Grid> - </GridBusca> + </HeaderFilters> + + { + isloading ? <LoadingSpinner text="Carregando..." /> : + optionResult === "Collection" ? ( + <GridBuscaCollection container spacing={2}> + <Grid item xs> + <Grid container spacing={2}> + {resultsCollection.map((card) => ( + <Grid item xs key={card.id}> + <CollectionCardFunction + name={card.name} + tags={card.tags} + rating={card.review_average} + id={card.id} + author={card.owner.name} + description={card.description} + thumbnails={card.items_thumbnails} + avatar={card.owner.avatar} + likeCount={card.likes_count} + followed={card.followed} + liked={card.liked} + collections={card.collection_items} + authorID={card.owner.id} + /> + + </Grid> + ))} + </Grid> + <div style={{ display: "flex", flexDirection: "row", justifyContent: "center", }}> + <button + style={{ height: 36, backgroundColor: "#ff7f00", marginBottom: 50, marginTop: 50, fontSize: 14, + color: "white", borderRadius: 4,border: "none", + }} + onClick={() => { + setLoadingMoreData(true); + setResultsPerPage(resultsPerPage + 12) + // collectStuff("Collection", ""); + }} + > + { + loadingMoreData ? <CircularProgress size={24} color="inherit" /> : "Carregar mais 12" + } + </button> + </div> + </Grid> + </GridBuscaCollection> + ) : + + optionResult === "LearningObject" ? ( + <GridBuscaResource container spacing={2}> + <Grid item xs={12} md={2}> + <Grid container > + <Grid item xs={12}> + <Paper elevation={4} square> + <SearchExpansionPanel onChange={collectStuff} onFiltering={isFiltering} /> + </Paper> + </Grid> + </Grid> + </Grid> + <Grid item xs> + <Grid container spacing={2}> + {resultsResource.map((card) => ( + <Grid item xs={12} sm={6} md={4} lg={3} key={card.id}> + <ResourceCardFunction + avatar={card.publisher.avatar} + id={card.id} + thumbnail={card.thumbnail} + type={card.object_type ? card.object_type : "Outros"} + title={card.name} + published={card.state === "published" ? true : false} + likeCount={card.likes_count} + liked={card.liked} + rating={card.review_average} + author={card.author} + tags={card.educational_stages} + href={"/recurso/" + card.id} + downloadableLink={card.default_attachment_location} + /> + </Grid> + ))} + </Grid> + <div + style={{ + display: "flex", + flexDirection: "row", + justifyContent: "center", + }} + > + <button + style={{ + height: 36, + backgroundColor: "#ff7f00", + marginBottom: 50, + marginTop: 50, + fontSize: 14, + color: "white", + borderRadius: 4, + border: "none", + }} + onClick={() => { + setLoadingMoreData(true); + setResultsPerPage(resultsPerPage + 12) + // collectStuff("LearningObject", ""); + }} + > + { + loadingMoreData ? <CircularProgress size={24} color="inherit" /> : "Carregar mais 12" + } + </button> + </div> + </Grid> + </GridBuscaResource> + ) : + optionResult === "User" && ( + <GridBuscaUser container spacing={2}> + <Grid item xs > + <Grid container spacing={2}> + {resultsUser.map((card) => ( + <Grid item xs key={card.id}> + <ContactCard + name={card.name} + avatar={card.avatar ? apiDomain + card.avatar : null} + cover={card.cover ? apiDomain + card.cover : null} + numCollections={card.collections_count} + numLearningObjects={card.learning_objects_count} + follow_count={card.follows_count} + followed={card.followed || null} + followerID={card.id} + href={'/usuario-publico/' + card.id} + /> + </Grid> + ))} + </Grid> + <div + style={{ + display: "flex", + flexDirection: "row", + justifyContent: "center", + }} + > + <button + style={{ + height: 36, + backgroundColor: "#ff7f00", + marginBottom: 50, + marginTop: 50, + fontSize: 14, + color: "white", + borderRadius: 4, + border: "none", + }} + onClick={() => { + setLoadingMoreData(true); + setResultsPerPage(resultsPerPage + 12) + // collectStuff("User", ""); + }} + > + { + loadingMoreData ? <CircularProgress color="inherit" size={24} /> : "Carregar mais 12" + } + </button> + </div> + </Grid> + </GridBuscaUser> + ) + } + </div> </Principal> </div> ); } -const GridBusca = styled(Grid)` +const GridBuscaCollection = styled(Grid)` color: #666; + ${'' /* background-color: green; */} + + h4 { + padding: 0 15px; + font-size: 18px; + margin-block: 10px; + text-transform: uppercase; + } +`; +const GridBuscaResource = styled(Grid)` + color: #666; + ${'' /* background-color: red; */} + + h4 { + padding: 0 15px; + font-size: 18px; + margin-block: 10px; + text-transform: uppercase; + } +`; +const GridBuscaUser = styled(Grid)` + color: #666; + ${'' /* background-color: blue; */} h4 { padding: 0 15px; @@ -243,11 +403,14 @@ const GridBusca = styled(Grid)` `; const HeaderFilters = styled(Paper)` - height: 60px; + height: 150px; text-align: center; background-color: #fff; margin-bottom: 30px; color: #666; + .textInfo{ + text-align: start; + } `; const StyledBreadCrumbs = styled(Breadcrumbs)` @@ -269,6 +432,5 @@ const BreadCrumbsDiv = styled.div` `; const Principal = styled.div` - width: 1170px; margin-inline: auto; `; diff --git a/src/Pages/SiteMap.js b/src/Pages/SiteMap.js new file mode 100644 index 0000000000000000000000000000000000000000..492d885c0013422940f28347fed261584f82977d --- /dev/null +++ b/src/Pages/SiteMap.js @@ -0,0 +1,188 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ +import React from 'react'; +import styled from 'styled-components' +import { Link } from "react-router-dom"; +import Breadcrumbs from "@material-ui/core/Breadcrumbs"; + + +const titulo ={ + fontFamily: "Roboto, sans-serif", + marginTop: "0", + fontSize: "26px", + fontWeight: "300", + marginBottom: "10px", + color: "#666" +} +const subtitulo ={ + fontFamily: "Roboto, sans-serif", + marginTop: "40px", + fontWeight:"500", + fontSize:"16px", + color: "#00bcd4" + +} +const item={ + fontFamily: "Roboto, sans-serif", + textDecoration: "none", + display:"block", + fontSize:"15px", + color: "#333", + fontWeight:"300", + paddingBottom: "5px" +} +const linha={ + margin: "15px 0", + borderTop: "2px solid #00bcd4", + borderBottom:"none" +} + +const paper ={ + padding: "30px 30px 100px 30px", + backgroundColor: "#fff", + boxShadow: "0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24)", + maxWidth:"1170px", + margin: "30px auto", + marginBottom:"0", + display: "flex", + flexDirection:"column", + boxSizing: "border-box" +} + +const cards={ + display:"flex", + flexDirection:"row" +} + +const card = { + padding:"0 15px", + width:"25%" +} + +const breadCrumbs={ + padding: "10px", + display: "flex", + margin: "0 auto", + width:"1170px" +} +const StyledBreadCrumbs = styled(Breadcrumbs)` + display: flex; + justify-content: flex-start; + max-width: 1170px; + span { + color: #a5a5a5; + font-size: 14px; + } + a { + color: #00bcd4; + text-decoration: none; + font-size: 14px; + } +`; + +export default function SiteMap (props) { + return ( + <div style={{ padding:"0 0 30px 0",backgroundColor :"#f4f4f4"}}> + + <div style={breadCrumbs}> + <StyledBreadCrumbs> + <Link to="/">Página Inicial</Link> + <span>Mapa do site</span> + + </StyledBreadCrumbs> + </div> + <link href="https://fonts.googleapis.com/css?family=Roboto:300;500&display=swap" rel="stylesheet"/> + <div style={paper}> + <h3 style={titulo}>Mapa do site</h3> + <div style={cards}> + <div style={card}> + <h3 style={subtitulo}>Sobre</h3> + <hr style={linha} /> + <a style={item} href="sobre">Sobre a Plataforma</a> + <a style={item} href="sobre#portaisparceiros">Portais Parceiros</a> + <a style={item} href="termos">Termos de Uso</a> + <a style={item} href="contato">Contato</a> + </div> + <div style={card}> + <h3 style={subtitulo}>Ajuda</h3> + <hr style={linha} /> + <a style={item} href="ajuda">Central de Ajuda</a> + <Link + style={item} + to={{ + pathname: "plataforma-mec", + + state: { value: "0" } + }} + > O que é a Plataforma MEC</Link> + <Link + style={item} + to={{ + pathname: "publicando-recurso", + state: { value: "0" } + }} + > Publicando Recurso + </Link> + + <Link + style={item} + to={{ + pathname: "encontrando-recurso", + state: { value: "0" } + }} + > Encontrando Recurso + </Link> + <Link + style={item} + to={{ + pathname: "/participando-da-rede", + + state: { value: "0" } + }} + > Participando da Rede + </Link> + <Link + style={item} + to={{ + pathname: "gerenciando-conta", + + state: { value: "0" } + }} + > Gerenciando a conta + </Link> + </div> + + <div style={card}> + <h3 style={subtitulo}>Acessibilidade</h3> + <hr style={linha} /> + <a style={item} href="acessibilidade">Acessibilidade</a> + </div> + <div style={card}> + <h3 style={subtitulo}>Área do Usuário</h3> + <hr style={linha} /> + <a style={item} href="/perfil">Perfil e Atividades</a> + <a style={item} href="perfil">Recursos Publicados</a> + <a style={item} href="/perfil">Favoritos</a> + <a style={item} href="perfil">Coleções</a> + <a style={item} href="/perfil">Rede</a> + </div> + </div> + </div> + </div> + ); +} diff --git a/src/Pages/TabsHelp/TabManageAc.js b/src/Pages/TabsHelp/TabManageAc.js index 6caf56bae22264e70fb5aa0152502ccdc9fa370c..9aa293b3fac8e07bc551a59e97f6161618f4d4f9 100644 --- a/src/Pages/TabsHelp/TabManageAc.js +++ b/src/Pages/TabsHelp/TabManageAc.js @@ -16,7 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { Component, useState, useEffect } from "react"; +import React, { useState } from "react"; import styled from "styled-components"; import Tabs from "@material-ui/core/Tabs"; import Tab from "@material-ui/core/Tab"; @@ -43,9 +43,7 @@ export default function TabManageAc(props) { "Gerenciando a Conta" ]; - const [tabValue, setTabValue] = useState( - Number(props.location.state.value) || 0 - ); + const [tabValue, setTabValue] = useState(props.location.state === "undefined" ? 0 : props.location.state); const handleChangeTab = (e, newValue) => { setTabValue(newValue); @@ -67,41 +65,32 @@ export default function TabManageAc(props) { <span>{tabs[5]}</span> </StyledBreadCrumbs> </BreadCrumbsDiv> - <Grid container spacing={4}> - <Grid item xs={3}> - <Menu> - <h4>{tabs[5]}</h4> - <TabsStyled - orientation="vertical" - variant="scrollable" - value={tabValue} - onChange={handleChangeTab} - TabIndicatorProps={{ style: { display: "none" } }} - > + <Grid container justify="center"> + <Grid item xs={12} md={10} > + <Principal> + <Menu> + <div className="fixo"> + <img src={GerenciandoConta} alt="Gerenciando a conta" /> + <span>{tabs[5]}</span> + </div> + <TabsStyled orientation = "vertical" + variant = "scrollable" + value = {tabValue} + onChange = {handleChangeTab} + TabIndicatorProps = {{style:{display: "none"}}} + > <TabStyled label={tabs[0]}></TabStyled> <TabStyled label={tabs[1]}></TabStyled> <TabStyled label={tabs[2]}></TabStyled> <TabStyled label={tabs[3]}></TabStyled> <TabStyled label={tabs[4]}></TabStyled> - </TabsStyled> - <br /> - <div className="voltarInicio"> - <a href="ajuda">VOLTAR AO ÍNICIO</a> - </div> - <hr /> - <div className="procurava"> - Não encontrou o que procurava? Entre em - <a href="contato"> contato</a> - </div> - </Menu> - </Grid> + </TabsStyled> + <br/> + <div className="voltarInicio"> + <a href="ajuda">VOLTAR AO ÍNICIO</a> + </div> + </Menu> - <Grid item xs={9}> - <Principal> - <div className="fixo"> - <img src={GerenciandoConta} alt="Gerenciando a conta" /> - <span>{tabs[5]}</span> - </div> {tabValue === 0 && <Why title={tabs[0]} />} {tabValue === 1 && <HowToDo title={tabs[1]} />} {tabValue === 2 && <HowToChange title={tabs[2]} />} @@ -110,69 +99,77 @@ export default function TabManageAc(props) { <div className="resultadosProcura"> <span>Não era bem o que você procurava?</span> <div className="subtitulo"> - <span> - Você pode navegar pelos tópicos de ajuda ou entrar em{" "} - <a href="contato">Contato</a>. - </span> + <span>Você pode navegar pelos tópicos de ajuda ou entrar em <a href="contato">Contato</a>.</span> </div> </div> - <Grid style={{ marginBottom: "50px" }} container spacing={2}> - <Grid item xs={4}> + + </Principal> + </Grid> + </Grid> + + + <Grid style={{ marginBottom: "50px" }} container justify={"center"}> + <Grid item xs={12} md={3} style={{margin:5}}> <CardPublicando /> </Grid> - <Grid item xs={4}> + <Grid item xs={12} md={3} style={{margin:5}}> <CardEncontrando /> </Grid> - <Grid item xs={4}> + <Grid item xs={12} md={3} style={{margin:5}}> <CardParticipando /> </Grid> </Grid> - </Principal> - </Grid> - </Grid> </Secao> </div> ); } const StyledBreadCrumbs = styled(Breadcrumbs)` - display: flex; - justify-content: flex-start; - max-width: 1170px; + display : flex; + justify-content : flex-start; span { - color: #a5a5a5; + color : #a5a5a5; } a { color: #00bcd4; text-decoration: none; } -`; + +` const BreadCrumbsDiv = styled.div` - padding: 10px; - display: flex; -`; + + padding : 10px; + display : flex; +` + const Principal = styled.div` .fixo { + height: 40px; text-align: center; background-color: #fff; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); padding: 30px; margin-bottom: 30px; color: #666; + img { height: 50px; width: 50px; margin-right: 40px; vertical-align: middle; + } span { font-size: 20px; + vertical-align: ; } + + + } .resultadosProcura { text-align: center; @@ -186,46 +183,62 @@ const Principal = styled.div` margin-top: 10px; span { - font-size: 15px; + font-size: 15px } a { font-size: 15px; padding: 0; - color: #00bcd4; + color:#00bcd4; text-decoration: none; } + } } -`; + +` const TabsStyled = styled(Tabs)` + .Mui-selected { background-color: #e7e4e4; } - .MuiTab-root { + .MuiTab-root{ text-transform: none !important; + max-width:100% } -`; + text-align: center; + width:100% + +` const TabStyled = styled(Tab)` + padding: 4px 15px !important; font-weight: 500; font-size: 14px !important; border-radius: 4px !important; + text-align: center; + + + + &:hover { background-color: #e7e4e4; } -`; +` + const Menu = styled.div` width: auto; background-color: #fff; color: #666; padding-block: 10px; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); + box-shadow: 0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24); + margin-bottom:30px + h4 { padding-inline: 15px; @@ -242,7 +255,7 @@ const Menu = styled.div` a { font-size: 15px; padding: 0; - color: #00bcd4; + color:#00bcd4; text-decoration: none; } } @@ -262,13 +275,15 @@ const Menu = styled.div` a { font-size: 15px; padding: 0; - color: #00bcd4; + color:#00bcd4; text-decoration: none; } + } -`; + +` const Secao = styled.div` - width: 1138px; margin-inline: auto; -`; + +` diff --git a/src/Pages/TabsHelp/TabNetPart.js b/src/Pages/TabsHelp/TabNetPart.js index 743a8a70698247afc53df97c2e6573eede53d8a5..107a998b5eda35618bd647ec5a266c41bc86e871 100644 --- a/src/Pages/TabsHelp/TabNetPart.js +++ b/src/Pages/TabsHelp/TabNetPart.js @@ -16,7 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { Component, useState, useEffect } from 'react'; +import React, { useState } from 'react'; import styled from 'styled-components'; import Tabs from '@material-ui/core/Tabs' import Tab from '@material-ui/core/Tab'; @@ -43,8 +43,7 @@ export default function TabNetPart (props) { 'Participando da Rede' ] - const [tabValue, setTabValue] = useState( - Number(props.location.state.value) || 0); + const [tabValue, setTabValue] = useState(props.location.state === "undefined" ? 0 : props.location.state); const handleChangeTab = (e, newValue) => { setTabValue(newValue) @@ -74,37 +73,29 @@ export default function TabNetPart (props) { </StyledBreadCrumbs> </BreadCrumbsDiv> - <Grid container spacing={4}> - <Grid item xs={3}> - <Menu> - <h4>{tabs[2]}</h4> - <TabsStyled orientation = "vertical" - variant = "scrollable" - value = {tabValue} - onChange = {handleChangeTab} - TabIndicatorProps = {{style:{display: "none"}}} - > - <TabStyled label={tabs[0]}></TabStyled> - <TabStyled label={tabs[1]}></TabStyled> - </TabsStyled> - <br/> - <div className="voltarInicio"> - <a href="ajuda">VOLTAR AO ÍNICIO</a> - </div> - <hr/> - <div className="procurava"> - Não encontrou o que procurava? Entre em - <a href="contato"> contato</a> - </div> - </Menu> - </Grid> - - <Grid item xs={9}> + <Grid container justify="center"> + <Grid item xs={12} md={10} > <Principal> - <div className="fixo"> + <Menu> + <div className="fixo"> <img src={ParticipandoRede} alt="Participando da Rede"/> - <span>{tabs[2]}</span> - </div> + <span>{tabs[2]}</span> + </div> + <TabsStyled orientation = "vertical" + variant = "scrollable" + value = {tabValue} + onChange = {handleChangeTab} + TabIndicatorProps = {{style:{display: "none"}}} + > + <TabStyled label={tabs[0]}></TabStyled> + <TabStyled label={tabs[1]}></TabStyled> + </TabsStyled> + <br/> + <div className="voltarInicio"> + <a href="ajuda">VOLTAR AO ÍNICIO</a> + </div> + </Menu> + {tabValue === 0 && <How title={tabs[0]}/>} {tabValue === 1 && <What title={tabs[1]}/>} <div className="resultadosProcura"> @@ -113,24 +104,25 @@ export default function TabNetPart (props) { <span>Você pode navegar pelos tópicos de ajuda ou entrar em <a href="contato">Contato</a>.</span> </div> </div> - <Grid style={{marginBottom:"50px"}} container spacing={2}> - <Grid item xs={4}> + + </Principal> + </Grid> + </Grid> + + + <Grid style={{paddingBottom:"50px"}} container justify={"center"}> + <Grid item xs={12} md={3} style={{margin:5}}> <CardPublicando/> </Grid> - <Grid item xs={4}> + <Grid item xs={12} md={3} style={{margin:5}}> <CardEncontrando/> </Grid> - <Grid item xs={4}> + <Grid item xs={12} md={3} style={{margin:5}}> <CardGerenciando/> </Grid> </Grid> - </Principal> - </Grid> - </Grid> - - </Secao> </div> ); @@ -138,7 +130,6 @@ export default function TabNetPart (props) { const StyledBreadCrumbs = styled(Breadcrumbs)` display : flex; justify-content : flex-start; - max-width : 1170px; span { color : #a5a5a5; } @@ -162,7 +153,6 @@ const Principal = styled.div` height: 40px; text-align: center; background-color: #fff; - box-shadow: 0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24); padding: 30px; margin-bottom: 30px; color: #666; @@ -219,7 +209,10 @@ const TabsStyled = styled(Tabs)` .MuiTab-root{ text-transform: none !important; + max-width:100% } + text-align: center; + width:100% ` @@ -229,6 +222,7 @@ const TabStyled = styled(Tab)` font-weight: 500; font-size: 14px !important; border-radius: 4px !important; + text-align: center; @@ -246,6 +240,8 @@ const Menu = styled.div` color: #666; padding-block: 10px; box-shadow: 0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24); + margin-bottom:30px + h4 { padding-inline: 15px; @@ -291,7 +287,6 @@ const Menu = styled.div` ` const Secao = styled.div` - width: 1138px; margin-inline: auto; ` diff --git a/src/Pages/TabsHelp/TabPlataformaMEC.js b/src/Pages/TabsHelp/TabPlataformaMEC.js index 02ca0646d0f555f49a5d2a1e0d8f80cc1c3d7deb..c704d98fed23e0a02df21be202f1233284067c9e 100644 --- a/src/Pages/TabsHelp/TabPlataformaMEC.js +++ b/src/Pages/TabsHelp/TabPlataformaMEC.js @@ -16,7 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { Component, useState, useEffect } from 'react'; +import React, { useState } from 'react'; import styled from 'styled-components'; import Tabs from '@material-ui/core/Tabs' import Tab from '@material-ui/core/Tab'; diff --git a/src/Pages/TabsHelp/TabResourseFind.js b/src/Pages/TabsHelp/TabResourseFind.js index f3d3a3f3aa9fb7a144f63eb4548f1eaed4df40e5..8691d2822ea4f4f7100eb8a413f104a78db94788 100644 --- a/src/Pages/TabsHelp/TabResourseFind.js +++ b/src/Pages/TabsHelp/TabResourseFind.js @@ -16,7 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { Component, useState, useEffect } from 'react'; +import React, { useState } from 'react'; import styled from 'styled-components'; import Tabs from '@material-ui/core/Tabs' import Tab from '@material-ui/core/Tab'; @@ -45,8 +45,7 @@ export default function TabResourseFind (props) { 'Encontrando Recursos' ] - const [tabValue, setTabValue] = useState( - Number(props.location.state.value) || 0); + const [tabValue, setTabValue] = useState(props.location.state === "undefined" ? 0 : props.location.state); const handleChangeTab = (e, newValue) => { setTabValue(newValue) @@ -74,38 +73,30 @@ export default function TabResourseFind (props) { </StyledBreadCrumbs> </BreadCrumbsDiv> - <Grid container spacing={4}> - <Grid item xs={3}> - <Menu> - <h4>{tabs[3]}</h4> - <TabsStyled orientation = "vertical" - variant = "scrollable" - value = {tabValue} - onChange = {handleChangeTab} - TabIndicatorProps = {{style:{display: "none"}}} - > - <TabStyled label={tabs[0]}></TabStyled> - <TabStyled label={tabs[1]}></TabStyled> - <TabStyled label={tabs[2]}></TabStyled> - </TabsStyled> - <br/> - <div className="voltarInicio"> - <a href="ajuda">VOLTAR AO ÍNICIO</a> - </div> - <hr/> - <div className="procurava"> - Não encontrou o que procurava? Entre em - <a href="contato"> contato</a> - </div> - </Menu> - </Grid> - - <Grid item xs={9}> + <Grid container justify="center"> + <Grid item xs={12} md={10} > <Principal> - <div className="fixo"> + <Menu> + <div className="fixo"> <img src={EncontrandoRecurso} alt="Encontrando Recursos"/> - <span>{tabs[3]}</span> - </div> + <span>{tabs[3]}</span> + </div> + <TabsStyled orientation = "vertical" + variant = "scrollable" + value = {tabValue} + onChange = {handleChangeTab} + TabIndicatorProps = {{style:{display: "none"}}} + > + <TabStyled label={tabs[0]}></TabStyled> + <TabStyled label={tabs[1]}></TabStyled> + <TabStyled label={tabs[2]}></TabStyled> + </TabsStyled> + <br/> + <div className="voltarInicio"> + <a href="ajuda">VOLTAR AO ÍNICIO</a> + </div> + </Menu> + {tabValue === 0 && <HowToDo title={tabs[0]}/>} {tabValue === 1 && <HowToFilter title={tabs[1]}/>} {tabValue === 2 && <HowToRank title={tabs[2]}/>} @@ -115,22 +106,23 @@ export default function TabResourseFind (props) { <span>Você pode navegar pelos tópicos de ajuda ou entrar em <a href="contato">Contato</a>.</span> </div> </div> - <Grid style={{marginBottom:"50px"}} container spacing={2}> - <Grid item xs={4}> - <CardPublicando/> - </Grid> - <Grid item xs={4}> - <CardParticipando/> - </Grid> - <Grid item xs={4}> - <CardGerenciando/> - </Grid> - </Grid> + </Principal> </Grid> </Grid> - + <Grid style={{paddingBottom:"50px"}} container justify={"center"}> + <Grid item xs={12} md={3} style={{margin:5}}> + <CardPublicando/> + </Grid> + <Grid item xs={12} md={3} style={{margin:5}}> + <CardParticipando/> + </Grid> + <Grid item xs={12} md={3} style={{margin:5}}> + <CardGerenciando/> + </Grid> + </Grid> + </Secao> </div> @@ -140,7 +132,6 @@ export default function TabResourseFind (props) { const StyledBreadCrumbs = styled(Breadcrumbs)` display : flex; justify-content : flex-start; - max-width : 1170px; span { color : #a5a5a5; } @@ -157,13 +148,13 @@ const BreadCrumbsDiv = styled.div` display : flex; ` + const Principal = styled.div` .fixo { height: 40px; text-align: center; background-color: #fff; - box-shadow: 0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24); padding: 30px; margin-bottom: 30px; color: #666; @@ -220,7 +211,10 @@ const TabsStyled = styled(Tabs)` .MuiTab-root{ text-transform: none !important; + max-width:100% } + text-align: center; + width:100% ` @@ -230,6 +224,7 @@ const TabStyled = styled(Tab)` font-weight: 500; font-size: 14px !important; border-radius: 4px !important; + text-align: center; @@ -247,6 +242,8 @@ const Menu = styled.div` color: #666; padding-block: 10px; box-shadow: 0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24); + margin-bottom:30px + h4 { padding-inline: 15px; @@ -292,7 +289,6 @@ const Menu = styled.div` ` const Secao = styled.div` - width: 1138px; margin-inline: auto; ` diff --git a/src/Pages/TabsHelp/TabResoursePub.js b/src/Pages/TabsHelp/TabResoursePub.js index 8753044a17ebadde1539879d0c4d21d058d99565..75dead021e85c99fc38053789a634f487d94e9dd 100644 --- a/src/Pages/TabsHelp/TabResoursePub.js +++ b/src/Pages/TabsHelp/TabResoursePub.js @@ -16,7 +16,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { Component, useState, useEffect } from 'react'; +import React, { useState } from 'react'; import styled from 'styled-components'; import Tabs from '@material-ui/core/Tabs' import Tab from '@material-ui/core/Tab'; @@ -31,13 +31,10 @@ import CardParticipando from '../../Components/HelpCenter/Cards/CardParticipando import CardGerenciando from '../../Components/HelpCenter/Cards/CardGerenciando'; import { Link } from 'react-router-dom'; - - - - - - export default function TabResoursePub (props) { + + console.log(props) + const tabs= [ 'Por que enviar um recurso?', 'Como publicar um recurso?', @@ -45,15 +42,12 @@ export default function TabResoursePub (props) { 'Publicando Recursos' ] - const [tabValue, setTabValue] = useState( - Number(props.location.state.value) || 0); + const [tabValue, setTabValue] = useState(props.location.state === "undefined" ? 0 : props.location.state); const handleChangeTab = (e, newValue) => { setTabValue(newValue) } - - return( <div style={{backgroundColor:"#f4f4f4"}}> <link href="https://fonts.googleapis.com/css?family=Pompiere|Roboto:500,400&display=swap" rel="stylesheet"/> @@ -66,48 +60,37 @@ export default function TabResoursePub (props) { </Link> <Link to="ajuda" > Ajuda - </Link> - + </Link> <span> {tabs[3]} </span> - - </StyledBreadCrumbs> </BreadCrumbsDiv> - <Grid container spacing={4}> - <Grid item xs={3}> - <Menu> - <h4>{tabs[3]}</h4> - <TabsStyled orientation = "vertical" - variant = "scrollable" - value = {tabValue} - onChange = {handleChangeTab} - TabIndicatorProps = {{style:{display: "none"}}} - > - <TabStyled label={tabs[0]}></TabStyled> - <TabStyled label={tabs[1]}></TabStyled> - <TabStyled label={tabs[2]}></TabStyled> - </TabsStyled> - <br/> - <div className="voltarInicio"> - <a href="ajuda">VOLTAR AO ÍNICIO</a> - </div> - <hr/> - <div className="procurava"> - Não encontrou o que procurava? Entre em - <a href="contato"> contato</a> - </div> - </Menu> - </Grid> - - <Grid item xs={9}> + <Grid container justify="center"> + <Grid item xs={12} md={10} > <Principal> - <div className="fixo"> - <img src={PublicandoRecursos} alt="Publicando Recursos"/> - <span>{tabs[3]}</span> - </div> + <Menu> + <div className="fixo"> + <img src={PublicandoRecursos} alt="Publicando Recursos"/> + <span>{tabs[3]}</span> + </div> + <TabsStyled orientation = "vertical" + variant = "scrollable" + value = {tabValue} + onChange = {handleChangeTab} + TabIndicatorProps = {{style:{display: "none"}}} + > + <TabStyled label={tabs[0]}></TabStyled> + <TabStyled label={tabs[1]}></TabStyled> + <TabStyled label={tabs[2]}></TabStyled> + </TabsStyled> + <br/> + <div className="voltarInicio"> + <a href="ajuda">VOLTAR AO ÍNICIO</a> + </div> + </Menu> + {tabValue === 0 && <Why title={tabs[0]}/>} {tabValue === 1 && <How title={tabs[1]}/>} {tabValue === 2 && <Which title={tabs[2]}/>} @@ -117,22 +100,22 @@ export default function TabResoursePub (props) { <span>Você pode navegar pelos tópicos de ajuda ou entrar em <a href="contato">Contato</a>.</span> </div> </div> - <Grid style={{marginBottom:"50px"}} container spacing={2}> - <Grid item xs={4}> - <CardEncontrando/> - </Grid> - <Grid item xs={4}> - <CardParticipando/> - </Grid> - <Grid item xs={4}> - <CardGerenciando/> - </Grid> - - </Grid> </Principal> </Grid> - </Grid> + </Grid> + <Grid style={{paddingBottom:"50px"}} container justify={"center"}> + <Grid item xs={12} md={3} style={{margin:5}}> + <CardEncontrando/> + </Grid> + <Grid item xs={12} md={3} style={{margin:5}}> + <CardParticipando/> + </Grid> + <Grid item xs={12} md={3} style={{margin:5}}> + <CardGerenciando/> + </Grid> + + </Grid> </Secao> @@ -142,7 +125,6 @@ export default function TabResoursePub (props) { const StyledBreadCrumbs = styled(Breadcrumbs)` display : flex; justify-content : flex-start; - max-width : 1170px; span { color : #a5a5a5; } @@ -166,7 +148,6 @@ const Principal = styled.div` height: 40px; text-align: center; background-color: #fff; - box-shadow: 0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24); padding: 30px; margin-bottom: 30px; color: #666; @@ -223,7 +204,10 @@ const TabsStyled = styled(Tabs)` .MuiTab-root{ text-transform: none !important; + max-width:100% } + text-align: center; + width:100% ` @@ -233,6 +217,7 @@ const TabStyled = styled(Tab)` font-weight: 500; font-size: 14px !important; border-radius: 4px !important; + text-align: center; @@ -250,6 +235,8 @@ const Menu = styled.div` color: #666; padding-block: 10px; box-shadow: 0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24); + margin-bottom:30px + h4 { padding-inline: 15px; @@ -295,7 +282,6 @@ const Menu = styled.div` ` const Secao = styled.div` - width: 1138px; margin-inline: auto; ` diff --git a/src/Pages/TermsPage.js b/src/Pages/TermsPage.js index 7a168814b56a521e46b8a86e5dd2155b25e168f4..4f50cd4611c2a061c0db847ac0aa6a9052897666 100644 --- a/src/Pages/TermsPage.js +++ b/src/Pages/TermsPage.js @@ -21,7 +21,6 @@ import {device} from '../Components/device.js' import { Store } from '../Store.js'; import { Button } from '@material-ui/core'; import Card from '@material-ui/core/Card'; -import CardActions from '@material-ui/core/CardActions'; import LabeledCheckbox from "../Components/Checkbox.js" import TermsPageContent from '../Components/TermsPageContent.js' import AppBar from '@material-ui/core/AppBar'; @@ -80,7 +79,9 @@ const Background = styled.div` ` export default function TermsContainer (props) { + // eslint-disable-next-line const {state, dispatch} = useContext(Store) + // eslint-disable-next-line const [checked, setChecked] = useState(false); const [unavailableButton, setButtonAvailability] = useState(true); const classes = useStyles() @@ -97,7 +98,7 @@ export default function TermsContainer (props) { userAgreement: true }) - if (props.cameFromPublishButton) { + if (props.location.state) { props.history.push('/professor') }else { props.history.push('/permission') @@ -207,25 +208,25 @@ const StyledAppBarContainer = styled.div` } ` -{/*<CardActions style={{justifyContent:"center", padding:"25px", borderTop : "2px solid #dadada"}}> -<div> -<div style={{fontSize:"14px"}}> -<LabeledCheckbox label={<Styledspan>Li e concordo com os termos de uso da Plataforma Integrada de RED do MEC</Styledspan>} handleChange={handleChecked}/> -<div style={{marginLeft:"1em", paddingLeft:"16px", color:"#a0a0a0", justifyContent:"center",display:"flex"}}> -<Button disabled = {unavailableButton} -style={ unavailableButton ? {backgroundColor:"#e9e9e9"} : {backgroundColor:"#00bcd4"}} -onClick={handleAgreement} -> -<StyledSpanContinuar style={unavailableButton ? {color:"#666666"} : {}}> -Continuar -</StyledSpanContinuar> -</Button> -<Button style={{marginLeft:"45px", backgroundColor:"#e9e9e9"}}> -<Styledspan style={{color:"rgb(102, 102, 102)"}}> -Cancelar -</Styledspan> -</Button> -</div> -</div> -</div> -</CardActions>*/} +// {/*<CardActions style={{justifyContent:"center", padding:"25px", borderTop : "2px solid #dadada"}}> +// <div> +// <div style={{fontSize:"14px"}}> +// <LabeledCheckbox label={<Styledspan>Li e concordo com os termos de uso da Plataforma Integrada de RED do MEC</Styledspan>} handleChange={handleChecked}/> +// <div style={{marginLeft:"1em", paddingLeft:"16px", color:"#a0a0a0", justifyContent:"center",display:"flex"}}> +// <Button disabled = {unavailableButton} +// style={ unavailableButton ? {backgroundColor:"#e9e9e9"} : {backgroundColor:"#00bcd4"}} +// onClick={handleAgreement} +// > +// <StyledSpanContinuar style={unavailableButton ? {color:"#666666"} : {}}> +// Continuar +// </StyledSpanContinuar> +// </Button> +// <Button style={{marginLeft:"45px", backgroundColor:"#e9e9e9"}}> +// <Styledspan style={{color:"rgb(102, 102, 102)"}}> +// Cancelar +// </Styledspan> +// </Button> +// </div> +// </div> +// </div> +// </CardActions>*/} diff --git a/src/Pages/UploadPage.js b/src/Pages/UploadPage.js index b37b9238f2b948b90ab935b77c1f24efb6afb38c..848b3b5b76edf5f975011b676dcfc021bbcd701e 100644 --- a/src/Pages/UploadPage.js +++ b/src/Pages/UploadPage.js @@ -17,14 +17,12 @@ You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ import React, {useState, useEffect, useContext} from 'react' -import axios from 'axios' -import {apiUrl, apiDomain} from '../env'; import Grid from '@material-ui/core/Grid'; import UploadFileWrapper from '../Components/UploadPageComponents/UploadFileWrapper.js' import {Store} from '../Store.js' import {InfoBox} from '../Components/UploadPageComponents/StyledComponents.js' import Stepper from '../Components/UploadPageComponents/Stepper.js' -import {getAxiosConfig} from '../Components/HelperFunctions/getAxiosConfig.js' +import {postRequest} from '../Components/HelperFunctions/getAxiosConfig.js' import PartOne from '../Components/UploadPageComponents/PartOne.js' import PartTwo from '../Components/UploadPageComponents/PartTwo.js' import PartThree from '../Components/UploadPageComponents/PartThree.js' @@ -36,24 +34,25 @@ import {Redirect} from 'react-router-dom' export default function UploadPage (props) { const {state} = useContext(Store) - {/*Object : link or file uploaded*/} + // {/*Object : link or file uploaded*/} + // eslint-disable-next-line const [object, setObject] = useState() const [loading, toggleLoading] = useState(true) const [draft, setDraft] = useState({}) + function handleSuccessfulGet (data) { + setDraft(data) + toggleLoading(false) + } useEffect( () => { if (state.currentUser.id !== "") { - const config = getAxiosConfig() + + const url = `/learning_objects/` + let payload = {} - axios.post( (`${apiUrl}/learning_objects/`), payload, config - ).then( (response) => { - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - setDraft(response.data) - toggleLoading(false) - console.log(response) - }, (error) => {console.log(error)}) + + postRequest(url, payload, handleSuccessfulGet, (error) => {console.log(error)}) + } }, []) @@ -65,38 +64,33 @@ export default function UploadPage (props) { const handlePost = () => { if (state.currentUser.id !== "") { - const config = getAxiosConfig() + const url = `/learning_objects/${draft.id}/publish` + let payload = {} - axios.post( (`${apiUrl}/learning_objects/` + draft.id + '/publish'), payload, config - ).then( (response) => { - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - handleModal(true) - console.log(response) - }, (error) => {console.log(error)}) + postRequest(url, payload, + (data) => {handleModal(true)}, + (error) => {console.log(error)} + ) + } } const handleSubmit = () => { if (state.currentUser.id !== "") { - const config = getAxiosConfig() + const url = `/submissions/` + let payload = { "submission" : { "learning_object_id" : draft.id } } - axios.post( (`${apiUrl}/submissions/`), payload, config - ).then( (response) => { - if ( response.headers['access-token'] ) { - sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token']) - } - handleModal(true) - console.log(response) + postRequest(url, payload, + (data) => {handleModal(true)}, + (error) => {console.log(error)} + ) - }, (error) => {console.log(error)}) } } diff --git a/src/Pages/UserPage.js b/src/Pages/UserPage.js index 83acf71d2e65b3e60dc654cfb92a9ba0f54b6661..c4b0755096ba9eae554a9525245915dccc2536d8 100644 --- a/src/Pages/UserPage.js +++ b/src/Pages/UserPage.js @@ -20,42 +20,23 @@ import React, {useState, useContext, useEffect} from 'react'; import styled from 'styled-components' import CustomizedBreadcrumbs from '../Components/TabPanels/Breadcrumbs.js' import { Store } from '../Store.js'; -import Tabs from '@material-ui/core/Tabs'; import Tab from '@material-ui/core/Tab'; -import Paper from '@material-ui/core/Paper'; import ModalAlterarAvatar from '../Components/ModalAlterarAvatar/ModalAlterarAvatar' import TabPanelAtividades from '../Components/TabPanels/UserPageTabs/PanelAtividades.js' import TabPanelMeusRecursos from '../Components/TabPanels/UserPageTabs/PanelMeusRecursos.js' import TabPanelFavoritos from '../Components/TabPanels/UserPageTabs/PanelFavoritos.js' import TabPanelColecoes from '../Components/TabPanels/UserPageTabs/PanelColecoes.js' import TabPanelRede from '../Components/TabPanels/UserPageTabs/PanelRede.js' -import TabPanelStatusEConquistas from '../Components/TabPanels/TabPanelStatusEConquistas.js' import TabPanelCuradoria from '../Components/TabPanels/UserPageTabs/PanelCuradoria.js' -import axios from 'axios' -import {apiUrl, apiDomain} from '../env'; import Grid from '@material-ui/core/Grid'; import {HeaderContainer, UserProfileContainer, CheckTeacherDiv, StyledTabs, RodapeDiv, NavBarContentContainer, BackgroundDiv} from '../Components/TabPanels/StyledComponents.js' - import Cover from '../Components/UserPageComponents/Cover.js' + +import Cover from '../Components/UserPageComponents/Cover.js' import ProfileAvatar from '../Components/UserPageComponents/Avatar.js' import UserInfo from '../Components/UserPageComponents/UserInfo.js' import EditProfileButton from '../Components/UserPageComponents/EditProfileButton.js' import SubmitterStatus from '../Components/UserPageComponents/SubmitterStatus.js' - -const GetHeaderConfig = () => { - - let config = { - headers : { - 'Accept': 'application/json', - 'Content-Type': 'application/json', - 'Access-Token': sessionStorage.getItem('@portalmec/accessToken'), - 'Client': sessionStorage.getItem('@portalmec/clientToken'), - 'Uid': sessionStorage.getItem('@portalmec/uid'), - } - } - {/*'Host': 'api.portalmec.c3sl.ufpr.br', - 'Cookie': ''*/} - return config -} +import {getRequest} from '../Components/HelperFunctions/getAxiosConfig.js' export default function UserPage (props){ const {state, dispatch} = useContext(Store) @@ -65,33 +46,32 @@ export default function UserPage (props){ Number(props.location.state) || 0 ); const [tabs, setTabs] = useState([ - 'Atividades', 'Status e Conquistas', 'Meus Recursos', 'Favoritos', 'Coleções', 'Rede' + 'Atividades', 'Meus Recursos', 'Favoritos', 'Coleções', 'Rede' ]) const handleChangeTab = (event, newValue) => { setTabValue(newValue) } - useEffect( () => { - if (id != '') { - axios.get( (`${apiUrl}/users/` + id), { - 'Accept': 'application/json', - 'Content-Type': 'application/json', - 'Host': 'api.portalmec.c3sl.ufpr.br', - 'Cookie': '' - }) - .then( (response) => { - console.log(response) - - if((response.data.role_ids.includes(4))) { - setTabs([ - 'Atividades', 'Status e Conquistas', 'Meus Recursos', 'Favoritos', 'Coleções', 'Rede', 'Curadoria' - ]) - } - }, - (error) => { - console.log('error while running ComponentDidMout') + function handleSuccessfulGet (data) { + dispatch ( { + type: 'GET_USER', + user: data } - )} + ) + + if((data.role_ids.includes(4))) { + setTabs([ + 'Atividades', 'Meus Recursos', 'Favoritos', 'Coleções', 'Rede', 'Curadoria' + ]) + } + } + + useEffect( () => { + if (id !== '') { + const url = `/users/${id}` + + getRequest(url, handleSuccessfulGet, (error) => {console.log(error)}) + } }, []) const redirect = () => { @@ -111,7 +91,7 @@ export default function UserPage (props){ <ModalAlterarAvatar open={modalOpen} handleClose={() => {toggleModal(false)}} - userAvatar={state.currentUser.userAvatar} + userAvatar={state.currentUser.avatar} /> <BackgroundDiv> @@ -160,19 +140,17 @@ export default function UserPage (props){ <Grid item xs={12}> {tabValue === 0 && - <TabPanelAtividades id={id} config={GetHeaderConfig()}/>} + <TabPanelAtividades id={id}/>} {tabValue === 1 && - <TabPanelStatusEConquistas id={id} config={GetHeaderConfig()}/>} + <TabPanelMeusRecursos id={id}/>} {tabValue === 2 && - <TabPanelMeusRecursos id={id} config={GetHeaderConfig()}/>} + <TabPanelFavoritos id={id}/>} {tabValue === 3 && - <TabPanelFavoritos id={id} config={GetHeaderConfig()}/>} + <TabPanelColecoes id={id}/>} {tabValue === 4 && - <TabPanelColecoes id={id} config={GetHeaderConfig()}/>} + <TabPanelRede id={id}/>} {tabValue === 5 && - <TabPanelRede id={id} config={GetHeaderConfig()}/>} - {tabValue === 6 && - <TabPanelCuradoria id={id} config={GetHeaderConfig()}/>} + <TabPanelCuradoria id={id}/>} </Grid> </Grid> </BackgroundDiv> diff --git a/src/Pages/UserTerms.js b/src/Pages/UserTerms.js index ad0dead21f5d83f11b46a41287905ec38f6763a3..d7722bef70cdf003c64d9f8ae743c4f2337c99b1 100644 --- a/src/Pages/UserTerms.js +++ b/src/Pages/UserTerms.js @@ -42,27 +42,6 @@ const BannerStyle=styled.div` verticalAlign: "middle" ` -const center={ - width: "100%", - textAlign: "center" -} - -const container={ - paddingInline: "15px", - paddingBlock: "20px", - marginInline: "auto", - textAlign:"center", - width:"750px" - -} - -const secao2={ - height: "100%", - alignItems: "center", - paddingBlock: "30px" -} - - const AColorido = styled.a` color: #00BCD4; @@ -220,7 +199,7 @@ class UserTerms extends Component { </BannerStyle> <ImagemSeçao2> - <Grid container spacing={3}> + <Grid container > <Grid item xs={12} md={1}></Grid> <Grid item xs={12} md={10}> <div> @@ -237,7 +216,7 @@ class UserTerms extends Component { </ImagemSeçao2> <Secao3 > - <Grid container spacing ={3}> + <Grid container > <h3>Para melhor compreensão, podemos dividir os recursos em dois tipos:</h3> <Grid item xs={12} md={1} ></Grid> <Grid item xs={12} md={5} > @@ -264,12 +243,12 @@ class UserTerms extends Component { - <Grid container spacing={3}> + <Grid container > <Grid item xs={12} md={1}></Grid> <Grid item xs={12} md={10}> <Secao4> <div class="texto" style={{paddingTop:"70px"}}> - <p>O <a href="http://www.planalto.gov.br/ccivil_03/_ato2011-2014/2014/lei/l13005.htm" target="_blank">Plano Nacional de Educação</a> (2014-2024) enfatiza nas metas 5 e 7 a importância dos recursos educacionais abertos para fomentar a qualidade da educação básica. A <a href="http://portal.mec.gov.br/index.php?option=com_docman&view=download&alias=35541-res-cne-ces-001-14032016-pdf&category_slug=marco-2016-pdf&Itemid=30192" target="_blank">Resolução CNE/CES nº 1</a>, de 11 de março de 2016, também destaca a importância dos recursos educacionais abertos para as instituições de educação superior e para as atividades de educação a distância.</p> + <p>O <a href="http://www.planalto.gov.br/ccivil_03/_ato2011-2014/2014/lei/l13005.htm" rel="noreferrer" target="_blank">Plano Nacional de Educação</a> (2014-2024) enfatiza nas metas 5 e 7 a importância dos recursos educacionais abertos para fomentar a qualidade da educação básica. A <a href="http://portal.mec.gov.br/index.php?option=com_docman&view=download&alias=35541-res-cne-ces-001-14032016-pdf&category_slug=marco-2016-pdf&Itemid=30192" rel="noreferrer" target="_blank">Resolução CNE/CES nº 1</a>, de 11 de março de 2016, também destaca a importância dos recursos educacionais abertos para as instituições de educação superior e para as atividades de educação a distância.</p> </div> <div class="titulo"> <h3>TERMOS DE USO</h3> @@ -288,7 +267,7 @@ class UserTerms extends Component { </Grid> - <Grid container spacing={3}> + <Grid container > <Grid item xs={12} md={1}></Grid> <Grid item xs={12} md={10}> <div style={{ marginBottom:"50px",paddingTop: "20px"}}> diff --git a/src/Store.js b/src/Store.js index 2d5aaa81d7419740f6f4a34618975773ea836cac..6beb65ee59e17e1bcb427dfccf31fbb433f40922 100644 --- a/src/Store.js +++ b/src/Store.js @@ -35,17 +35,15 @@ const initialState = { height: 0 }, currentUser: { - askTeacherQuestion : true, + askTeacherQuestion : false, id : '', - username : '', + name : '', email : '', - accessToken : '', - clientToken : '', - userAvatar : '', - userCover : '', + avatar : '', + cover : '', uid : '', - followCount : 0, - collectionsCount : 0, + follows_count : 0, + collections_count : 0, submitter_request : 'default', roles : [] } @@ -78,13 +76,28 @@ function reducer(state, action) { return { ...state, userIsLoggedIn:action.userLoggedIn, - currentUser:action.login + currentUser:action.user } case 'USER_LOGGED_OUT': + sessionStorage.clear() return { ...state, userIsLoggedIn:action.userLoggedOut, - currentUser:action.login + currentUser:{ + askTeacherQuestion : false, + id : '', + name : '', + email : '', + avatar_file_name : '', + cover_file_name : '', + uid : '', + follows_count : 0, + collections_count : 0, + submitter_request : 'default', + roles : [] + }, + userAgreedToPublicationTerms: false, + userAgreedToPublicationPermissions: false } case 'USER_AGREED_TO_PUBLICATION_TERMS': return { @@ -106,6 +119,40 @@ function reducer(state, action) { ...state, currentUser : action.currUser } + case 'USER_DELETED_ACCOUNT': + localStorage.clear() + return { + ...state, + userIsLoggedIn:false, + currentUser: { + askTeacherQuestion : false, + id : '', + name : '', + email : '', + avatar_file_name : '', + cover_file_name : '', + uid : '', + follows_count : 0, + collections_count : 0, + submitter_request : 'default', + roles : [] + }, + } + case 'TOGGLE_MODAL_COLABORAR_PLATAFORMA': + return { + ...state, + modalColaborarPlataformaOpen : action.modalColaborarPlataformaOpen + } + case 'GET_USER': + return { + ...state, + currentUser:action.user + } + case 'USER_UPDATED_EMAIL': + return { + ...state, + currentUser : action.currUser + } default: return state } diff --git a/src/env.js b/src/env.js index 1f221ee7772cbcd5478dcb68a32769645a7e862d..c13c03e40d90e114c527b17dd43088c759948fcb 100644 --- a/src/env.js +++ b/src/env.js @@ -22,8 +22,8 @@ var apiDomain = 'https://api.portalmec.c3sl.ufpr.br', apiUrl = apiDomain + '/' + apiVersion; var simcaqAPIDomain = 'https://www.simcaq.c3sl.ufpr.br/api', - apiVersion = 'v1', - simcaqAPIurl = simcaqAPIDomain + '/' + apiVersion + apiSimcaqVersion = 'v1', + simcaqAPIurl = simcaqAPIDomain + '/' + apiSimcaqVersion export {apiUrl}; export {apiDomain}; diff --git a/src/img/Excluir.png b/src/img/Excluir.png new file mode 100644 index 0000000000000000000000000000000000000000..fd6fb1bd51208e07d3565f89b5e517f8e1386145 Binary files /dev/null and b/src/img/Excluir.png differ diff --git a/src/index.js b/src/index.js index 7759fd80d097363e57313a8bedfae2e84e0ce75f..032a5eeeccd2687e53c6e2e72097dae3ff7efa72 100755 --- a/src/index.js +++ b/src/index.js @@ -19,7 +19,6 @@ along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/> import React from 'react'; import ReactDOM from 'react-dom'; import * as serviceWorker from './serviceWorker'; - import './index.css'; import App from './App.js' import { StoreProvider } from './Store'; @@ -27,7 +26,7 @@ import { StoreProvider } from './Store'; ReactDOM.render( <StoreProvider> - <App /> + <App /> </StoreProvider> , document.getElementById('root'));