├── .editorconfig ├── .env.example ├── .gitignore ├── LICENSE ├── README.md ├── config-overrides.js ├── db.json ├── package.json ├── paths.json ├── public ├── .well-known │ └── assetlinks.json ├── android-icon-144x144.png ├── android-icon-192x192.png ├── android-icon-36x36.png ├── android-icon-48x48.png ├── android-icon-72x72.png ├── android-icon-96x96.png ├── apple-icon-114x114.png ├── apple-icon-120x120.png ├── apple-icon-144x144.png ├── apple-icon-152x152.png ├── apple-icon-180x180.png ├── apple-icon-57x57.png ├── apple-icon-60x60.png ├── apple-icon-72x72.png ├── apple-icon-76x76.png ├── apple-icon-precomposed.png ├── apple-icon.png ├── browserconfig.xml ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon-96x96.png ├── favicon.ico ├── index.html ├── locales │ ├── en │ │ └── translation.json │ └── pt │ │ └── translation.json ├── manifest.json ├── ms-icon-144x144.png ├── ms-icon-150x150.png ├── ms-icon-310x310.png ├── ms-icon-70x70.png └── robots.txt ├── src ├── API │ ├── CasesService │ │ └── index.ts │ ├── CepService │ │ └── index.ts │ ├── DonationCaptableService │ │ └── index.ts │ ├── DonationPremeService │ │ └── index.ts │ └── index.ts ├── App.js ├── Router.js ├── assets │ ├── data │ │ ├── br-states.json │ │ ├── brazil-cases.json │ │ ├── brazil-geojson-states.json │ │ ├── brazil-map.json │ │ ├── brazil-states-map.json │ │ ├── brazil-states.json │ │ ├── casos_240320.json │ │ └── google-maps-style.json │ ├── icons │ │ ├── about-active.svg │ │ ├── about.svg │ │ ├── area-active.svg │ │ ├── area.svg │ │ ├── arrow-left.svg │ │ ├── bell.svg │ │ ├── city-active.svg │ │ ├── city.svg │ │ ├── donations-active.svg │ │ ├── donations.svg │ │ ├── help-active.svg │ │ ├── help.svg │ │ ├── hospital-marker.svg │ │ ├── map-active.svg │ │ ├── map-marker.svg │ │ ├── map.svg │ │ ├── newspaper-active.svg │ │ ├── newspaper.svg │ │ ├── question.js │ │ ├── share.svg │ │ └── small-log.svg │ ├── images │ │ ├── CovidZero_Universidade_de_Oxford_recruta_para_testes_de_vacina_criada_para_erradicar_o_COVID-19.jpg │ │ ├── Diretor-Geral_da_OMS_apela_ao_G20_para_combater_unir_e_inflamar_o_COVID-19.jpg │ │ ├── Revelando_a_origem_e_transmissao_do_COVID-19.jpg │ │ ├── as-mudancas-nas-relacoes-de-consumo-durante-a-pandemia.jpg │ │ ├── cap-table.png │ │ ├── cap-table.svg │ │ ├── como-manter-a-eficacia-da-midia-durante-a-pandemia.jpg │ │ ├── donations.jpg │ │ ├── icon-ok.svg │ │ ├── img-reuniao.jpg │ │ ├── logo-preme.png │ │ ├── logo-preme.svg │ │ ├── logo-ribon.svg │ │ ├── logo.png │ │ ├── logo.svg │ │ ├── medidas_basicas_de_protecao_contra_o_novo_coronavirus.jpg │ │ ├── meeting_room.jpg │ │ ├── o-mercado-brasileiro-e-as-mudanças-no-consumo.jpg │ │ ├── o_impacto_da_COVID-19_nas_relacoes_de_trabalho.jpg │ │ ├── o_inicio_da_pandemia_e_o_isolamento_social_no_brasil.jpg │ │ ├── por_tras_do_relatorio_que_pos_os_EUA_e_o_Reino_Unido_em_acao_contra_o_virus_COVID-19.jpg │ │ ├── projeto_de_ventilador_recebe_sinal_verde_do_governo_do_Reino_Unido_para_avancar_a_proxima_etapa_dos_testes.jpg │ │ ├── qual-o-impacto-da-crise-do-coronavirus-na-midia.jpg │ │ ├── saude_mental_em_tempos_de_pandemia.jpg │ │ └── seja-criativo-para-anunciar-durante-o-isolamento-social.jpg │ └── scss │ │ ├── _area.scss │ │ ├── _base.scss │ │ ├── _cities.scss │ │ ├── _contentPlaceholder.scss │ │ ├── _loading.scss │ │ ├── _mixins.scss │ │ ├── _news.scss │ │ ├── _sidebar.scss │ │ ├── _socialShared.scss │ │ └── _variables.scss ├── components │ ├── ArticleNewsHeader │ │ ├── index.js │ │ └── styles.js │ ├── Button │ │ ├── index.js │ │ └── styles.js │ ├── CardDonations │ │ ├── index.js │ │ └── styles.js │ ├── CardNews │ │ ├── index.js │ │ └── styles.js │ ├── CardStats │ │ ├── index.js │ │ └── styles.js │ ├── Charts │ │ ├── CasesAndDeaths │ │ │ └── index.js │ │ ├── DailyCases │ │ │ └── index.js │ │ ├── DailyDeaths │ │ │ └── index.js │ │ ├── RegionCases │ │ │ └── index.js │ │ ├── TotalCases │ │ │ └── index.js │ │ ├── TotalDeaths │ │ │ └── index.js │ │ └── styles.js │ ├── Chips │ │ ├── index.js │ │ └── styles.js │ ├── Circle │ │ ├── index.js │ │ └── styles.js │ ├── Dots │ │ ├── index.js │ │ └── styles.js │ ├── ExpandableBox │ │ ├── index.js │ │ └── styles.js │ ├── Header │ │ ├── index.js │ │ └── styles.js │ ├── Input │ │ ├── index.js │ │ └── styles.js │ ├── Loading │ │ └── index.js │ ├── MapArea │ │ ├── index.js │ │ └── styles.js │ ├── MapBrazil │ │ ├── index.js │ │ └── styles.js │ ├── MapCities │ │ ├── index.js │ │ └── styles.js │ ├── MapHome │ │ ├── index.js │ │ └── styles.js │ ├── Marker │ │ ├── index.js │ │ └── styles.js │ ├── SocialShare │ │ └── index.js │ ├── Switch │ │ ├── index.js │ │ └── styles.js │ └── index.js ├── i18n │ └── index.js ├── index.js ├── layout │ ├── Sidebar │ │ └── index.js │ ├── index.js │ └── scss │ │ └── Layout.scss ├── pages │ ├── Area │ │ ├── index.js │ │ └── styles.js │ ├── Brazil │ │ ├── index.js │ │ └── styles.js │ ├── Cities │ │ ├── index.js │ │ └── styles.js │ ├── Donations │ │ ├── checkoutBoleto.js │ │ ├── checkoutBoletoPreme.js │ │ ├── checkoutCartaoCaptable.js │ │ ├── checkoutCartaoPreme.js │ │ ├── confirmedCaptable.js │ │ ├── confirmedPreme.js │ │ ├── details.js │ │ ├── form.js │ │ ├── index.js │ │ ├── mask.js │ │ ├── projects.json │ │ └── styles.js │ ├── Help │ │ └── index.js │ ├── Map │ │ └── styles.js │ ├── News │ │ ├── News1.js │ │ ├── News10.js │ │ ├── News11.js │ │ ├── News12.js │ │ ├── News13.js │ │ ├── News14.js │ │ ├── News2.js │ │ ├── News3.js │ │ ├── News4.js │ │ ├── News5.js │ │ ├── News6.js │ │ ├── News7.js │ │ ├── News8.js │ │ ├── News9.js │ │ ├── index.js │ │ └── styles.js │ └── UiKit │ │ ├── index.js │ │ └── styles.js ├── react-app-env.d.ts ├── services │ ├── history.js │ ├── last30Days.js │ ├── regionCases.js │ ├── totalCases.js │ └── usePosition.js ├── store │ ├── ducks │ │ ├── cities │ │ │ ├── actions.ts │ │ │ ├── index.ts │ │ │ ├── sagas.ts │ │ │ └── types.ts │ │ ├── rootReducer.ts │ │ └── rootSaga.ts │ └── index.ts ├── styles │ ├── fonts.js │ └── theme.js └── utils │ ├── config │ ├── http.js │ └── httpDonations.js │ └── constants │ └── index.js └── tsconfig.json /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | charset = utf-8 6 | trim_trailing_whitespace = true 7 | insert_final_newline = true 8 | indent_style = space 9 | indent_size = 2 -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | REACT_APP_GMAP_KEY= -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | 25 | yarn.lock 26 | package-lock.json 27 | 28 | .env 29 | 30 | # IDE 31 | /.vscode 32 | /.idea -------------------------------------------------------------------------------- /config-overrides.js: -------------------------------------------------------------------------------- 1 | const { addBabelPlugin, override } = require("customize-cra"); 2 | 3 | module.exports = override( 4 | addBabelPlugin([ 5 | "babel-plugin-root-import", 6 | { 7 | rootPathSuffix: "src" 8 | } 9 | ]) 10 | ); 11 | -------------------------------------------------------------------------------- /db.json: -------------------------------------------------------------------------------- 1 | { 2 | "cities": [ 3 | { 4 | "id": 1, 5 | "city": "São Paulo", 6 | "stateCode": "SP", 7 | "quantity": 200, 8 | "confirmed": 12, 9 | "recovered": 1, 10 | "deaths": 2, 11 | "suspected": 0 12 | }, 13 | { 14 | "id": 5, 15 | "city": "São Caetano", 16 | "stateCode": "SP", 17 | "quantity": 200, 18 | "confirmed": 12, 19 | "recovered": 1, 20 | "deaths": 2, 21 | "suspected": 0 22 | }, 23 | { 24 | "id": 2, 25 | "city": "Rio de Janeiro", 26 | "stateCode": "RJ", 27 | "quantity": 100, 28 | "confirmed": 10, 29 | "recovered": 2, 30 | "deaths": 1, 31 | "suspected": 1 32 | }, 33 | { 34 | "id": 3, 35 | "city": "Fortaleza", 36 | "stateCode": "CE", 37 | "quantity": 50, 38 | "confirmed": 9, 39 | "recovered": 2, 40 | "deaths": 3, 41 | "suspected": 4 42 | } 43 | ] 44 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "covidzero", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@material/react-layout-grid": "^0.15.0", 7 | "@testing-library/jest-dom": "^4.2.4", 8 | "@testing-library/react": "^9.3.2", 9 | "@testing-library/user-event": "^7.1.2", 10 | "axios": "^0.19.2", 11 | "chart.js": "^2.9.3", 12 | "google-map-react": "^1.1.7", 13 | "history": "^4.10.1", 14 | "i18next": "^19.3.3", 15 | "i18next-browser-languagedetector": "^4.0.2", 16 | "i18next-xhr-backend": "^3.2.2", 17 | "lodash": "^4.17.15", 18 | "moment": "^2.26.0", 19 | "node-sass": "^4.14.1", 20 | "react": "^16.13.1", 21 | "react-chartjs-2": "^2.9.0", 22 | "react-document-meta": "^3.0.0-beta.2", 23 | "react-dom": "^16.13.1", 24 | "react-ga": "^2.7.0", 25 | "react-i18next": "^11.3.3", 26 | "react-infinite-scroll-component": "^5.0.4", 27 | "react-redux": "^7.2.0", 28 | "react-router-dom": "^5.1.2", 29 | "react-scripts": "3.4.0", 30 | "react-simple-maps": "^1.0.0-beta.0", 31 | "react-tooltip": "^4.1.2", 32 | "react-truncate": "^2.4.0", 33 | "redux": "^4.0.5", 34 | "redux-saga": "^1.1.3", 35 | "styled-components": "^5.0.1", 36 | "styled-icons": "^10.2.1", 37 | "supercluster": "^7.0.0", 38 | "typesafe-actions": "^5.1.0", 39 | "typescript": "^3.8.3", 40 | "use-supercluster": "^0.2.6" 41 | }, 42 | "scripts": { 43 | "start": "react-app-rewired start", 44 | "build": "react-app-rewired build", 45 | "test": "react-app-rewired test", 46 | "eject": "react-scripts eject" 47 | }, 48 | "eslintConfig": { 49 | "extends": "react-app" 50 | }, 51 | "browserslist": { 52 | "production": [ 53 | ">0.2%", 54 | "not dead", 55 | "not op_mini all" 56 | ], 57 | "development": [ 58 | "last 1 chrome version", 59 | "last 1 firefox version", 60 | "last 1 safari version" 61 | ] 62 | }, 63 | "devDependencies": { 64 | "@types/lodash": "^4.14.149", 65 | "@types/react-redux": "^7.1.7", 66 | "babel-plugin-root-import": "^6.4.1", 67 | "customize-cra": "^0.9.1", 68 | "eslint-import-resolver-babel-plugin-root-import": "^1.1.1", 69 | "react-app-rewired": "^2.1.5" 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /paths.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "paths": { 4 | "~/*": ["*"] 5 | } 6 | } 7 | } -------------------------------------------------------------------------------- /public/.well-known/assetlinks.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "relation": ["delegate_permission/common.handle_all_urls"], 3 | "target" : { "namespace": "android_app", "package_name": "com.covidzero.app", 4 | "sha256_cert_fingerprints": ["BB:EC:7C:BB:3E:7C:46:8B:ED:46:4F:FA:AF:CD:0E:01:66:98:20:E2:FB:AB:06:E8:AB:F4:ED:42:5A:77:26:F1"] } 5 | }] -------------------------------------------------------------------------------- /public/android-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/public/android-icon-144x144.png -------------------------------------------------------------------------------- /public/android-icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/public/android-icon-192x192.png -------------------------------------------------------------------------------- /public/android-icon-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/public/android-icon-36x36.png -------------------------------------------------------------------------------- /public/android-icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/public/android-icon-48x48.png -------------------------------------------------------------------------------- /public/android-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/public/android-icon-72x72.png -------------------------------------------------------------------------------- /public/android-icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/public/android-icon-96x96.png -------------------------------------------------------------------------------- /public/apple-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/public/apple-icon-114x114.png -------------------------------------------------------------------------------- /public/apple-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/public/apple-icon-120x120.png -------------------------------------------------------------------------------- /public/apple-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/public/apple-icon-144x144.png -------------------------------------------------------------------------------- /public/apple-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/public/apple-icon-152x152.png -------------------------------------------------------------------------------- /public/apple-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/public/apple-icon-180x180.png -------------------------------------------------------------------------------- /public/apple-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/public/apple-icon-57x57.png -------------------------------------------------------------------------------- /public/apple-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/public/apple-icon-60x60.png -------------------------------------------------------------------------------- /public/apple-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/public/apple-icon-72x72.png -------------------------------------------------------------------------------- /public/apple-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/public/apple-icon-76x76.png -------------------------------------------------------------------------------- /public/apple-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/public/apple-icon-precomposed.png -------------------------------------------------------------------------------- /public/apple-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/public/apple-icon.png -------------------------------------------------------------------------------- /public/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | #ffffff -------------------------------------------------------------------------------- /public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/public/favicon-16x16.png -------------------------------------------------------------------------------- /public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/public/favicon-32x32.png -------------------------------------------------------------------------------- /public/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/public/favicon-96x96.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 36 | 37 | 41 | 50 | 54 | 55 | 56 | 57 | 58 | 59 | 69 | 70 | 71 | 72 | CovidZero 73 | 74 | 75 | 76 |
77 | 87 | 88 |
89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /public/locales/en/translation.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Testando o store do Redux", 3 | "buttons": { 4 | "1": "Diminuir", 5 | "2": "Adicionar" 6 | }, 7 | "menu": { 8 | "map": "Brasil", 9 | "cities": "Regiões", 10 | "area": "Sua área", 11 | "help": "Ajuda", 12 | "news": "Conteúdos", 13 | "donations":"Apoie ONGs" 14 | }, 15 | "header": { 16 | "map": "Brasil", 17 | "cities": "Estados e Cidades", 18 | "area": "Sua área", 19 | "help": "Ajuda", 20 | "news": "Conteúdos relevantes", 21 | "donations":"Doações" 22 | }, 23 | "searchGithub": "Pesquisar suas informações do Github" 24 | } -------------------------------------------------------------------------------- /public/locales/pt/translation.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Testando o store do Redux", 3 | "buttons": { 4 | "1": "Diminuir", 5 | "2": "Adicionar" 6 | }, 7 | "menu": { 8 | "map": "Brasil", 9 | "cities": "Regiões", 10 | "area": "Sua área", 11 | "help": "Ajuda", 12 | "news": "Conteúdos", 13 | "donations":"Apoie ONGs" 14 | }, 15 | "header": { 16 | "map": "Brasil", 17 | "cities": "Estados e Cidades", 18 | "area": "Sua área", 19 | "help": "Ajuda", 20 | "news": "Conteúdos relevantes", 21 | "donations":"Doações" 22 | }, 23 | "searchGithub": "Pesquisar suas informações do Github" 24 | } 25 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Covid Zero", 3 | "short_name": "Covid Zero", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "theme_color": "#000000", 7 | "background_color": "#ffffff", 8 | "icons": [ 9 | { 10 | "src": "\/android-icon-36x36.png", 11 | "sizes": "36x36", 12 | "type": "image\/png", 13 | "density": "0.75" 14 | }, 15 | { 16 | "src": "\/android-icon-48x48.png", 17 | "sizes": "48x48", 18 | "type": "image\/png", 19 | "density": "1.0" 20 | }, 21 | { 22 | "src": "\/android-icon-72x72.png", 23 | "sizes": "72x72", 24 | "type": "image\/png", 25 | "density": "1.5" 26 | }, 27 | { 28 | "src": "\/android-icon-96x96.png", 29 | "sizes": "96x96", 30 | "type": "image\/png", 31 | "density": "2.0" 32 | }, 33 | { 34 | "src": "\/android-icon-144x144.png", 35 | "sizes": "144x144", 36 | "type": "image\/png", 37 | "density": "3.0" 38 | }, 39 | { 40 | "src": "\/android-icon-192x192.png", 41 | "sizes": "192x192", 42 | "type": "image\/png", 43 | "density": "4.0" 44 | } 45 | ] 46 | } 47 | -------------------------------------------------------------------------------- /public/ms-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/public/ms-icon-144x144.png -------------------------------------------------------------------------------- /public/ms-icon-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/public/ms-icon-150x150.png -------------------------------------------------------------------------------- /public/ms-icon-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/public/ms-icon-310x310.png -------------------------------------------------------------------------------- /public/ms-icon-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/public/ms-icon-70x70.png -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /src/API/CasesService/index.ts: -------------------------------------------------------------------------------- 1 | import http from '~/utils/config/http'; 2 | 3 | 4 | const URL = { 5 | statesCases: '/cases/state', 6 | all: '/cases/state/report', 7 | cityCases:'/cases/city' 8 | } 9 | export interface Cases { 10 | confirmed: number; 11 | suspected: number; 12 | recovered: number; 13 | deaths: number; 14 | } 15 | 16 | export interface StateCases { 17 | stateName: string, 18 | stateCode: string, 19 | latitude: string, 20 | longitude: string, 21 | cases: Cases 22 | } 23 | 24 | export interface CityCases {} 25 | 26 | 27 | 28 | 29 | 30 | interface CasesProvider { 31 | getStatesCases(): Promise, 32 | getAllCases(): Promise 33 | getCityCases(): Promise 34 | } 35 | 36 | export default function CasesService(casesBaseURL: string): CasesProvider { 37 | 38 | async function getAllCases(): Promise { 39 | try { 40 | const response = await http.get(`${casesBaseURL}${URL.all}`) 41 | const cases: Cases = convertCasesResponse(response.data) 42 | 43 | return cases; 44 | } catch (error) { 45 | console.log('error=>', error) 46 | throw (error) 47 | } 48 | } 49 | 50 | async function getStatesCases(): Promise { 51 | try { 52 | 53 | const response = await http.get(`${casesBaseURL}${URL.statesCases}`) 54 | const statesCases: StateCases[] = convertStateCasesResponse(response.data) 55 | return statesCases; 56 | } catch (error) { 57 | console.log('error=>', error) 58 | throw (error) 59 | } 60 | } 61 | 62 | 63 | async function getCityCases(): Promise { 64 | try { 65 | 66 | const response = await http.get(`${casesBaseURL}${URL.cityCases}`) 67 | const cityCases:CityCases[] = response.data 68 | return cityCases; 69 | } catch (error) { 70 | console.log('error=>', error) 71 | throw (error) 72 | } 73 | } 74 | 75 | 76 | return { 77 | getStatesCases, 78 | getAllCases, 79 | getCityCases 80 | } 81 | 82 | } 83 | 84 | interface CasesResponse { 85 | totalCases: number, 86 | suspectedCase?: number, 87 | recoveredCases?: number, 88 | deaths?: number, 89 | } 90 | 91 | interface stateCasesResponse { 92 | stateCode: string, 93 | stateName: string, 94 | lat: string, 95 | lng: string, 96 | cases: CasesResponse 97 | } 98 | 99 | //Utils para convertes o data do endpoint em Tipos mais amigáveis de serem escritos 100 | function convertStateCasesResponse(statesCasesResponse: stateCasesResponse[]): StateCases[] { 101 | return statesCasesResponse.map(stateCasesResponse => { 102 | const cases = stateCasesResponse.cases; 103 | const _case: StateCases = { 104 | stateCode: stateCasesResponse.stateCode, 105 | stateName: stateCasesResponse.stateName, 106 | latitude: stateCasesResponse.lat, 107 | longitude: stateCasesResponse.lng, 108 | cases: { 109 | confirmed: cases.totalCases ? cases.totalCases : 0, 110 | recovered: cases.recoveredCases ? cases.recoveredCases : 0, 111 | suspected: cases.suspectedCase ? cases.suspectedCase : 0, 112 | deaths: cases.deaths ? cases.deaths : 0 113 | } 114 | } 115 | 116 | return _case 117 | }) 118 | 119 | } 120 | 121 | function convertCasesResponse(casesResponse: CasesResponse): Cases { 122 | 123 | const _case: Cases = { 124 | confirmed: casesResponse.totalCases ? casesResponse.totalCases : 0, 125 | recovered: casesResponse.recoveredCases ? casesResponse.recoveredCases : 0, 126 | suspected: casesResponse.suspectedCase ? casesResponse.suspectedCase : 0, 127 | deaths: casesResponse.deaths ? casesResponse.deaths : 0 128 | } 129 | 130 | return _case; 131 | 132 | } 133 | 134 | //Util para tratar possíveis casos de undefined em valores que talvez não estejam incluidos 135 | //no reponse.data dos endpoints 136 | function calculateActiveCases(totalCases: number, deaths: number | undefined, recovered: number | undefined) { 137 | 138 | const _deaths = deaths ? deaths : 0; 139 | const _recovered = recovered ? recovered : 0; 140 | const activeCases = totalCases - _deaths - _recovered 141 | 142 | return activeCases; 143 | } 144 | -------------------------------------------------------------------------------- /src/API/CepService/index.ts: -------------------------------------------------------------------------------- 1 | import http from '~/utils/config/httpDonations'; 2 | import { API_URL_VIA_CEP as baseURL} from "~/utils/constants"; 3 | 4 | 5 | export default function CepService(){ 6 | 7 | async function findCep(_cep:string) { 8 | let cep = _cep.replace(/\D/g, ''); 9 | try { 10 | const resp = await http.get(`${baseURL}${cep}/json/`); 11 | return resp.data; 12 | } catch (error) { 13 | return []; 14 | } 15 | 16 | } 17 | 18 | return { 19 | findCep 20 | } 21 | } -------------------------------------------------------------------------------- /src/API/DonationCaptableService/index.ts: -------------------------------------------------------------------------------- 1 | import http from '~/utils/config/httpDonations'; 2 | import { API_URL_DONATION_CAPTABLE as baseURL} from "~/utils/constants"; 3 | 4 | 5 | 6 | 7 | export interface Projects { 8 | id:number, 9 | name:string, 10 | about:string, 11 | goal:number, 12 | quota_total:number, 13 | quota_value: number, 14 | } 15 | 16 | 17 | 18 | interface DonationsProvider { 19 | findAllProjects(): Promise, 20 | findProjects(id:number): Promise, 21 | DonationsProjects(id:number,param:any):Promise, 22 | CheckoutProjects(param:any):Promise 23 | 24 | } 25 | 26 | 27 | export default function DonationsCapTableService(casesBaseURL: string): DonationsProvider { 28 | 29 | async function findAllProjects() { 30 | try { 31 | const resp = await http.get(`${baseURL}`+"/projects"); 32 | return resp.data; 33 | }catch (error) { 34 | console.log('error=>', error) 35 | throw (error) 36 | } 37 | 38 | } 39 | 40 | 41 | async function findProjects(id:number) { 42 | try { 43 | const resp = await http.get(`${baseURL}`+"/projects/"+`${id}`); 44 | return resp.data; 45 | } catch (error) { 46 | 47 | throw (error) 48 | } 49 | 50 | } 51 | 52 | async function DonationsProjects(id:any,param:any) { 53 | try { 54 | const resp = await http.post(`${baseURL}`+"/projects/"+`${id}`+"/donations",param); 55 | return resp.data; 56 | }catch (error) { 57 | 58 | throw (error) 59 | } 60 | 61 | } 62 | 63 | async function CheckoutProjects(param:any) { 64 | try { 65 | const resp = await http.post(`${baseURL}`+"/donation_checkout/",param); 66 | return resp.data; 67 | } catch (error) { 68 | 69 | throw (error.response.data) 70 | } 71 | 72 | } 73 | 74 | 75 | 76 | return { 77 | findAllProjects, 78 | findProjects, 79 | DonationsProjects, 80 | CheckoutProjects 81 | } 82 | } -------------------------------------------------------------------------------- /src/API/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | API_URL_DONATION_CAPTABLE, 3 | API_URL_DONATION_PREME 4 | } from "~/utils/constants"; 5 | 6 | import CasesService from './CasesService'; 7 | import DonationsCapTableService from './DonationCaptableService'; 8 | import DonationPremeService from './DonationPremeService'; 9 | import CepService from './CepService'; 10 | 11 | 12 | function API() { 13 | 14 | const baseURLs = { 15 | cases: `https://api.covidzero.com.br/data_api/v1`, 16 | donationsCaptable:API_URL_DONATION_CAPTABLE, 17 | donationsPreme:API_URL_DONATION_PREME 18 | } 19 | 20 | return { 21 | cases: CasesService(baseURLs.cases), 22 | donationsCaptable: DonationsCapTableService(baseURLs.donationsCaptable), 23 | donationsPreme: DonationPremeService(baseURLs.donationsPreme), 24 | cep:CepService() 25 | } 26 | 27 | } 28 | 29 | const apiInstance = API(); 30 | export default apiInstance; -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useTranslation } from "react-i18next"; 3 | 4 | import "@material/react-layout-grid/index.scss"; 5 | 6 | import Layout from "~/layout"; 7 | import Routes from "./Router"; 8 | 9 | import ReactGA from 'react-ga'; 10 | 11 | function App() { 12 | const [t, i18n] = useTranslation(); 13 | 14 | function handleChangeLang(lang) { 15 | i18n.changeLanguage(lang); 16 | } 17 | 18 | 19 | 20 | return ( 21 | 22 | 23 | 24 | ); 25 | } 26 | 27 | function initializeReactGA() { 28 | ReactGA.initialize('UA-161000549-1'); 29 | ReactGA.pageview('/'); 30 | } 31 | 32 | export default App; 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/Router.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Route, Switch } from "react-router-dom"; 3 | import Brazil from "./pages/Brazil"; 4 | import Cities from "./pages/Cities"; 5 | import Area from "./pages/Area"; 6 | import Help from "./pages/Help"; 7 | import News from "./pages/News"; 8 | import UiKit from "./pages/UiKit"; 9 | import News1 from "./pages/News/News1"; 10 | import News2 from "./pages/News/News2"; 11 | import News3 from "./pages/News/News3"; 12 | import News4 from "./pages/News/News4"; 13 | import News5 from "./pages/News/News5"; 14 | import News6 from "./pages/News/News6"; 15 | import News7 from "./pages/News/News7"; 16 | import News8 from "./pages/News/News8"; 17 | import News9 from "./pages/News/News9"; 18 | import News10 from "./pages/News/News10"; 19 | import News11 from "./pages/News/News11"; 20 | import News12 from "./pages/News/News12"; 21 | import News13 from "./pages/News/News13"; 22 | import News14 from "./pages/News/News14"; 23 | 24 | import Donations from "./pages/Donations"; 25 | import Details from "./pages/Donations/details"; 26 | import CheckoutCartaoCaptable from "./pages/Donations/checkoutCartaoCaptable"; 27 | import checkoutBoleto from "./pages/Donations/checkoutBoleto"; 28 | import confirmedPreme from "./pages/Donations/confirmedPreme"; 29 | import confirmedCaptable from "./pages/Donations/confirmedCaptable"; 30 | 31 | import checkoutBoletoPreme from "./pages/Donations/checkoutBoletoPreme"; 32 | import CheckoutCartaoPreme from "./pages/Donations/checkoutCartaoPreme"; 33 | 34 | export default function Routes() { 35 | return ( 36 | 37 | 38 | {/* */} 39 | 40 | {/* */} 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | {" "} 56 | 57 | {/* News section /> */} 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 |

Desculpe, um erro ocorreu. Estaremos verificando o que aconteceu.

} /> 74 |
75 | ); 76 | } 77 | -------------------------------------------------------------------------------- /src/assets/data/brazil-states.json: -------------------------------------------------------------------------------- 1 | {"UF":[{"NM_ESTADO":"ACRE","NM_REGIAO":"NORTE","NM_SIGLA":"AC","CD_GEOCUF":"12"},{"NM_ESTADO":"ALAGOAS","NM_REGIAO":"NORDESTE","NM_SIGLA":"AL","CD_GEOCUF":"27"},{"NM_ESTADO":"AMAP\u00c1","NM_REGIAO":"NORTE","NM_SIGLA":"AP","CD_GEOCUF":"16"},{"NM_ESTADO":"BAHIA","NM_REGIAO":"NORDESTE","NM_SIGLA":"BA","CD_GEOCUF":"29"},{"NM_ESTADO":"CEAR\u00c1","NM_REGIAO":"NORDESTE","NM_SIGLA":"CE","CD_GEOCUF":"23"},{"NM_ESTADO":"DISTRITO FEDERAL","NM_REGIAO":"CENTRO-OESTE","NM_SIGLA":"DF","CD_GEOCUF":"53"},{"NM_ESTADO":"ESP\u00cdRITO SANTO","NM_REGIAO":"SUDESTE","NM_SIGLA":"ES","CD_GEOCUF":"32"},{"NM_ESTADO":"GOI\u00c1S","NM_REGIAO":"CENTRO-OESTE","NM_SIGLA":"GO","CD_GEOCUF":"52"},{"NM_ESTADO":"MARANH\u00c3O","NM_REGIAO":"NORDESTE","NM_SIGLA":"MA","CD_GEOCUF":"21"},{"NM_ESTADO":"MATO GROSSO","NM_REGIAO":"CENTRO-OESTE","NM_SIGLA":"MT","CD_GEOCUF":"51"},{"NM_ESTADO":"MATO GROSSO DO SUL","NM_REGIAO":"CENTRO-OESTE","NM_SIGLA":"MS","CD_GEOCUF":"50"},{"NM_ESTADO":"MINAS GERAIS","NM_REGIAO":"SUDESTE","NM_SIGLA":"MG","CD_GEOCUF":"31"},{"NM_ESTADO":"PAR\u00c1","NM_REGIAO":"NORTE","NM_SIGLA":"PA","CD_GEOCUF":"15"},{"NM_ESTADO":"PARA\u00cdBA","NM_REGIAO":"NORDESTE","NM_SIGLA":"PB","CD_GEOCUF":"25"},{"NM_ESTADO":"PERNAMBUCO","NM_REGIAO":"NORDESTE","NM_SIGLA":"PE","CD_GEOCUF":"26"},{"NM_ESTADO":"PIAU\u00cd","NM_REGIAO":"NORDESTE","NM_SIGLA":"PI","CD_GEOCUF":"22"},{"NM_ESTADO":"RIO DE JANEIRO","NM_REGIAO":"SUDESTE","NM_SIGLA":"RJ","CD_GEOCUF":"33"},{"NM_ESTADO":"RIO GRANDE DO NORTE","NM_REGIAO":"NORDESTE","NM_SIGLA":"RN","CD_GEOCUF":"24"},{"NM_ESTADO":"RIO GRANDE DO SUL","NM_REGIAO":"SUL","NM_SIGLA":"RS","CD_GEOCUF":"43"},{"NM_ESTADO":"RORAIMA","NM_REGIAO":"NORTE","NM_SIGLA":"RR","CD_GEOCUF":"14"},{"NM_ESTADO":"SANTA CATARINA","NM_REGIAO":"SUL","NM_SIGLA":"SC","CD_GEOCUF":"42"},{"NM_ESTADO":"S\u00c3O PAULO","NM_REGIAO":"SUDESTE","NM_SIGLA":"SP","CD_GEOCUF":"35"},{"NM_ESTADO":"SERGIPE","NM_REGIAO":"NORDESTE","NM_SIGLA":"SE","CD_GEOCUF":"28"},{"NM_ESTADO":"TOCANTINS","NM_REGIAO":"NORTE","NM_SIGLA":"TO","CD_GEOCUF":"17"},{"NM_ESTADO":"PARAN\u00c1","NM_REGIAO":"SUL","NM_SIGLA":"PR","CD_GEOCUF":"41"},{"NM_ESTADO":"ROND\u00d4NIA","NM_REGIAO":"NORTE","NM_SIGLA":"RO","CD_GEOCUF":"11"},{"NM_ESTADO":"AMAZONAS","NM_REGIAO":"NORTE","NM_SIGLA":"AM","CD_GEOCUF":"13"}]} -------------------------------------------------------------------------------- /src/assets/data/casos_240320.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "state": "SP", 4 | "uf_nome": "São Paulo", 5 | "totalCases": 745, 6 | "deaths": 30, 7 | "long": -48.75933253, 8 | "lat": -22.25689629 9 | }, 10 | { 11 | "state": "AC", 12 | "uf_nome": "Acre", 13 | "totalCases": 17, 14 | "deaths": 0, 15 | "long": -72.13278532, 16 | "lat": -8.790273369 17 | }, 18 | { 19 | "state": "RJ", 20 | "uf_nome": "Rio de Janeiro", 21 | "totalCases": 233, 22 | "deaths": 4, 23 | "long": -42.89486166, 24 | "lat": -22.48289272 25 | }, 26 | { 27 | "state": "AL", 28 | "uf_nome": "Alagoas", 29 | "totalCases": 8, 30 | "deaths": 0, 31 | "long": -36.67169365, 32 | "lat": -9.78261012 33 | }, 34 | { 35 | "state": "ES", 36 | "uf_nome": "Espírito Santo", 37 | "totalCases": 33, 38 | "deaths": 0, 39 | "long": -40.67555693, 40 | "lat": -19.5962671 41 | }, 42 | { 43 | "state": "AM", 44 | "uf_nome": "Amazonas", 45 | "totalCases": 32, 46 | "deaths": 0, 47 | "long": -64.68219739, 48 | "lat": -4.181781605 49 | }, 50 | { 51 | "state": "BA", 52 | "uf_nome": "Bahia", 53 | "totalCases": 63, 54 | "deaths": 0, 55 | "long": -41.73416561, 56 | "lat": -12.47128057 57 | }, 58 | { 59 | "state": "AP", 60 | "uf_nome": "Amapá", 61 | "totalCases": 1, 62 | "deaths": 0, 63 | "long": -51.97549803, 64 | "lat": 1.391022019 65 | }, 66 | { 67 | "state": "DF", 68 | "uf_nome": "Distrito Federal", 69 | "totalCases": 146, 70 | "deaths": 0, 71 | "long": -47.79584647, 72 | "lat": -15.77756387 73 | }, 74 | { 75 | "state": "CE", 76 | "uf_nome": "Ceará", 77 | "totalCases": 164, 78 | "deaths": 0, 79 | "long": -39.5850178, 80 | "lat": -5.097246159 81 | }, 82 | { 83 | "state": "MG", 84 | "uf_nome": "Minas Gerais", 85 | "totalCases": 128, 86 | "deaths": 0, 87 | "long": -44.63183484, 88 | "lat": -18.44591442 89 | }, 90 | { 91 | "state": "RS", 92 | "uf_nome": "Rio Grande do Sul", 93 | "totalCases": 96, 94 | "deaths": 0, 95 | "long": -53.33181857, 96 | "lat": -29.75305161 97 | }, 98 | { 99 | "state": "PE", 100 | "uf_nome": "Pernambuco", 101 | "totalCases": 42, 102 | "deaths": 0, 103 | "long": -38.05086543, 104 | "lat": -8.330994796 105 | }, 106 | { 107 | "state": "GO", 108 | "uf_nome": "Goiás", 109 | "totalCases": 23, 110 | "deaths": 0, 111 | "long": -49.60311111, 112 | "lat": -16.0467844 113 | }, 114 | { 115 | "state": "PR", 116 | "uf_nome": "Paraná", 117 | "totalCases": 60, 118 | "deaths": 0, 119 | "long": -51.63564161, 120 | "lat": -24.65625532 121 | }, 122 | { 123 | "state": "MA", 124 | "uf_nome": "Maranhão", 125 | "totalCases": 8, 126 | "deaths": 0, 127 | "long": -45.29536634, 128 | "lat": -5.047432049 129 | }, 130 | { 131 | "state": "SC", 132 | "uf_nome": "Santa Catarina", 133 | "totalCases": 86, 134 | "deaths": 0, 135 | "long": -50.50838917, 136 | "lat": -27.24658227 137 | }, 138 | { 139 | "state": "MS", 140 | "uf_nome": "Mato Grosso do Sul", 141 | "totalCases": 21, 142 | "deaths": 0, 143 | "long": -54.88071217, 144 | "lat": -20.32456331 145 | }, 146 | { 147 | "state": "RN", 148 | "uf_nome": "Rio Grande do Norte", 149 | "totalCases": 13, 150 | "deaths": 0, 151 | "long": -36.68738063, 152 | "lat": -5.842578641 153 | }, 154 | { 155 | "state": "MT", 156 | "uf_nome": "Mato Grosso", 157 | "totalCases": 7, 158 | "deaths": 0, 159 | "long": -55.9009429, 160 | "lat": -12.93153781 161 | }, 162 | { 163 | "state": "PA", 164 | "uf_nome": "Pará", 165 | "totalCases": 5, 166 | "deaths": 0, 167 | "long": -52.4880964, 168 | "lat": -5.292059687 169 | }, 170 | { 171 | "state": "PB", 172 | "uf_nome": "Paraíba", 173 | "totalCases": 2, 174 | "deaths": 0, 175 | "long": -37.77807815, 176 | "lat": -6.946955058 177 | }, 178 | { 179 | "state": "SE", 180 | "uf_nome": "Sergipe", 181 | "totalCases": 10, 182 | "deaths": 0, 183 | "long": -37.44218263, 184 | "lat": -10.5944836 185 | }, 186 | { 187 | "state": "PI", 188 | "uf_nome": "Piauí", 189 | "totalCases": 6, 190 | "deaths": 0, 191 | "long": -43.17488463, 192 | "lat": -8.093344997 193 | }, 194 | { 195 | "state": "TO", 196 | "uf_nome": "Tocantins", 197 | "totalCases": 7, 198 | "deaths": 0, 199 | "long": -48.35472734, 200 | "lat": -10.1086123 201 | }, 202 | { 203 | "state": "RO", 204 | "uf_nome": "Rondônia", 205 | "totalCases": 3, 206 | "deaths": 0, 207 | "long": -63.31891522, 208 | "lat": -10.31709036 209 | }, 210 | { 211 | "state": "RR", 212 | "uf_nome": "Roraima", 213 | "totalCases": 2, 214 | "deaths": 0, 215 | "long": -61.39106106, 216 | "lat": 2.100328071 217 | } 218 | ] -------------------------------------------------------------------------------- /src/assets/data/google-maps-style.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "elementType": "geometry", 4 | "stylers": [ 5 | { 6 | "color": "#212121" 7 | } 8 | ] 9 | }, 10 | { 11 | "elementType": "labels", 12 | "stylers": [ 13 | { 14 | "visibility": "off" 15 | } 16 | ] 17 | }, 18 | { 19 | "elementType": "labels.icon", 20 | "stylers": [ 21 | { 22 | "visibility": "off" 23 | } 24 | ] 25 | }, 26 | { 27 | "elementType": "labels.text.fill", 28 | "stylers": [ 29 | { 30 | "color": "#757575" 31 | } 32 | ] 33 | }, 34 | { 35 | "elementType": "labels.text.stroke", 36 | "stylers": [ 37 | { 38 | "color": "#212121" 39 | } 40 | ] 41 | }, 42 | { 43 | "featureType": "administrative", 44 | "elementType": "geometry", 45 | "stylers": [ 46 | { 47 | "color": "#757575" 48 | } 49 | ] 50 | }, 51 | { 52 | "featureType": "administrative.country", 53 | "elementType": "labels.text.fill", 54 | "stylers": [ 55 | { 56 | "color": "#9e9e9e" 57 | } 58 | ] 59 | }, 60 | { 61 | "featureType": "administrative.land_parcel", 62 | "stylers": [ 63 | { 64 | "visibility": "off" 65 | } 66 | ] 67 | }, 68 | { 69 | "featureType": "administrative.locality", 70 | "elementType": "labels.text.fill", 71 | "stylers": [ 72 | { 73 | "color": "#bdbdbd" 74 | } 75 | ] 76 | }, 77 | { 78 | "featureType": "administrative.neighborhood", 79 | "stylers": [ 80 | { 81 | "visibility": "off" 82 | } 83 | ] 84 | }, 85 | { 86 | "featureType": "poi", 87 | "elementType": "labels.text.fill", 88 | "stylers": [ 89 | { 90 | "color": "#757575" 91 | } 92 | ] 93 | }, 94 | { 95 | "featureType": "poi.park", 96 | "elementType": "geometry", 97 | "stylers": [ 98 | { 99 | "color": "#181818" 100 | } 101 | ] 102 | }, 103 | { 104 | "featureType": "poi.park", 105 | "elementType": "labels.text.fill", 106 | "stylers": [ 107 | { 108 | "color": "#616161" 109 | } 110 | ] 111 | }, 112 | { 113 | "featureType": "poi.park", 114 | "elementType": "labels.text.stroke", 115 | "stylers": [ 116 | { 117 | "color": "#1b1b1b" 118 | } 119 | ] 120 | }, 121 | { 122 | "featureType": "road", 123 | "stylers": [ 124 | { 125 | "visibility": "off" 126 | } 127 | ] 128 | }, 129 | { 130 | "featureType": "road", 131 | "elementType": "geometry.fill", 132 | "stylers": [ 133 | { 134 | "color": "#2c2c2c" 135 | } 136 | ] 137 | }, 138 | { 139 | "featureType": "road", 140 | "elementType": "labels.text.fill", 141 | "stylers": [ 142 | { 143 | "color": "#8a8a8a" 144 | } 145 | ] 146 | }, 147 | { 148 | "featureType": "road.arterial", 149 | "elementType": "geometry", 150 | "stylers": [ 151 | { 152 | "color": "#373737" 153 | } 154 | ] 155 | }, 156 | { 157 | "featureType": "road.highway", 158 | "elementType": "geometry", 159 | "stylers": [ 160 | { 161 | "color": "#3c3c3c" 162 | } 163 | ] 164 | }, 165 | { 166 | "featureType": "road.highway.controlled_access", 167 | "elementType": "geometry", 168 | "stylers": [ 169 | { 170 | "color": "#4e4e4e" 171 | } 172 | ] 173 | }, 174 | { 175 | "featureType": "road.local", 176 | "elementType": "labels.text.fill", 177 | "stylers": [ 178 | { 179 | "color": "#616161" 180 | } 181 | ] 182 | }, 183 | { 184 | "featureType": "transit", 185 | "elementType": "labels.text.fill", 186 | "stylers": [ 187 | { 188 | "color": "#757575" 189 | } 190 | ] 191 | }, 192 | { 193 | "featureType": "water", 194 | "elementType": "geometry", 195 | "stylers": [ 196 | { 197 | "color": "#000000" 198 | } 199 | ] 200 | }, 201 | { 202 | "featureType": "water", 203 | "elementType": "labels.text.fill", 204 | "stylers": [ 205 | { 206 | "color": "#3d3d3d" 207 | } 208 | ] 209 | } 210 | ] -------------------------------------------------------------------------------- /src/assets/icons/about-active.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/about.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/area-active.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/area.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/arrow-left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/icons/bell.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/city-active.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/icons/city.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/assets/icons/donations-active.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/icons/donations.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/icons/help-active.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/help.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/hospital-marker.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/icons/map-active.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/map-marker.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/icons/map.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/newspaper-active.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/newspaper.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/question.js: -------------------------------------------------------------------------------- 1 | ; 16 | -------------------------------------------------------------------------------- /src/assets/icons/share.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/small-log.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/images/CovidZero_Universidade_de_Oxford_recruta_para_testes_de_vacina_criada_para_erradicar_o_COVID-19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/src/assets/images/CovidZero_Universidade_de_Oxford_recruta_para_testes_de_vacina_criada_para_erradicar_o_COVID-19.jpg -------------------------------------------------------------------------------- /src/assets/images/Diretor-Geral_da_OMS_apela_ao_G20_para_combater_unir_e_inflamar_o_COVID-19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/src/assets/images/Diretor-Geral_da_OMS_apela_ao_G20_para_combater_unir_e_inflamar_o_COVID-19.jpg -------------------------------------------------------------------------------- /src/assets/images/Revelando_a_origem_e_transmissao_do_COVID-19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/src/assets/images/Revelando_a_origem_e_transmissao_do_COVID-19.jpg -------------------------------------------------------------------------------- /src/assets/images/as-mudancas-nas-relacoes-de-consumo-durante-a-pandemia.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/src/assets/images/as-mudancas-nas-relacoes-de-consumo-durante-a-pandemia.jpg -------------------------------------------------------------------------------- /src/assets/images/cap-table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/src/assets/images/cap-table.png -------------------------------------------------------------------------------- /src/assets/images/como-manter-a-eficacia-da-midia-durante-a-pandemia.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/src/assets/images/como-manter-a-eficacia-da-midia-durante-a-pandemia.jpg -------------------------------------------------------------------------------- /src/assets/images/donations.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/src/assets/images/donations.jpg -------------------------------------------------------------------------------- /src/assets/images/icon-ok.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/img-reuniao.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/src/assets/images/img-reuniao.jpg -------------------------------------------------------------------------------- /src/assets/images/logo-preme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/src/assets/images/logo-preme.png -------------------------------------------------------------------------------- /src/assets/images/logo-ribon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/src/assets/images/logo.png -------------------------------------------------------------------------------- /src/assets/images/medidas_basicas_de_protecao_contra_o_novo_coronavirus.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/src/assets/images/medidas_basicas_de_protecao_contra_o_novo_coronavirus.jpg -------------------------------------------------------------------------------- /src/assets/images/meeting_room.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/src/assets/images/meeting_room.jpg -------------------------------------------------------------------------------- /src/assets/images/o-mercado-brasileiro-e-as-mudanças-no-consumo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/src/assets/images/o-mercado-brasileiro-e-as-mudanças-no-consumo.jpg -------------------------------------------------------------------------------- /src/assets/images/o_impacto_da_COVID-19_nas_relacoes_de_trabalho.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/src/assets/images/o_impacto_da_COVID-19_nas_relacoes_de_trabalho.jpg -------------------------------------------------------------------------------- /src/assets/images/o_inicio_da_pandemia_e_o_isolamento_social_no_brasil.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/src/assets/images/o_inicio_da_pandemia_e_o_isolamento_social_no_brasil.jpg -------------------------------------------------------------------------------- /src/assets/images/por_tras_do_relatorio_que_pos_os_EUA_e_o_Reino_Unido_em_acao_contra_o_virus_COVID-19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/src/assets/images/por_tras_do_relatorio_que_pos_os_EUA_e_o_Reino_Unido_em_acao_contra_o_virus_COVID-19.jpg -------------------------------------------------------------------------------- /src/assets/images/projeto_de_ventilador_recebe_sinal_verde_do_governo_do_Reino_Unido_para_avancar_a_proxima_etapa_dos_testes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/src/assets/images/projeto_de_ventilador_recebe_sinal_verde_do_governo_do_Reino_Unido_para_avancar_a_proxima_etapa_dos_testes.jpg -------------------------------------------------------------------------------- /src/assets/images/qual-o-impacto-da-crise-do-coronavirus-na-midia.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/src/assets/images/qual-o-impacto-da-crise-do-coronavirus-na-midia.jpg -------------------------------------------------------------------------------- /src/assets/images/saude_mental_em_tempos_de_pandemia.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/src/assets/images/saude_mental_em_tempos_de_pandemia.jpg -------------------------------------------------------------------------------- /src/assets/images/seja-criativo-para-anunciar-durante-o-isolamento-social.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CovidZero/covidzero-frontend/1ba36b4610c17a0072bb0f7848a446218280b243/src/assets/images/seja-criativo-para-anunciar-durante-o-isolamento-social.jpg -------------------------------------------------------------------------------- /src/assets/scss/_area.scss: -------------------------------------------------------------------------------- 1 | .gm-style .gm-style-mtc div { 2 | box-sizing: border-box; 3 | background-color: #232328 !important; 4 | color: #F5F5F5 !important; 5 | font-size: 12px !important; 6 | } 7 | 8 | .gm-bundled-control .gmnoprint { 9 | //top: -6vh !important; 10 | } 11 | 12 | .gm-control-active { 13 | background-color: #232328 !important; 14 | } -------------------------------------------------------------------------------- /src/assets/scss/_base.scss: -------------------------------------------------------------------------------- 1 | :root { 2 | font-size: 16px; 3 | font-family: "Open Sans"; 4 | } 5 | 6 | main { 7 | margin-left: 5rem; 8 | } 9 | 10 | @media only screen and (min-width: map-get($map: $breakpoints, $key: "tablet")) { 11 | main { 12 | animation: marginLeft 1s ease; 13 | margin-left: 16rem; 14 | } 15 | } 16 | @keyframes marginLeft { 17 | from { 18 | margin-left: 5rem; 19 | } 20 | to { 21 | margin-left: 16rem; 22 | } 23 | } 24 | 25 | body { 26 | color: $white; 27 | background: $gray-80; 28 | font-family: $default-font-family; 29 | font-size: $default-font-size; 30 | margin: 0; 31 | 32 | -webkit-font-smoothing: antialiased; 33 | -moz-osx-font-smoothing: grayscale; 34 | } 35 | 36 | body::-webkit-scrollbar { 37 | width: 0.25rem; 38 | } 39 | 40 | body::-webkit-scrollbar-track { 41 | background: $gray-80; 42 | } 43 | 44 | body::-webkit-scrollbar-thumb { 45 | background: $gray-60; 46 | } 47 | 48 | html { 49 | scroll-behavior: smooth; 50 | } 51 | 52 | * { 53 | box-sizing: border-box; 54 | } 55 | 56 | a { 57 | text-decoration: none; 58 | color: white; 59 | } 60 | 61 | .main-logo { 62 | display: block; 63 | margin-left: auto; 64 | margin-right: auto; 65 | width: 35%; 66 | } 67 | 68 | 69 | @include respond-to(tablet) { 70 | .main-logo { 71 | width: 20%; 72 | padding-right: 80px; 73 | } 74 | } 75 | 76 | .mdc-layout-grid { 77 | width: 100%; 78 | } 79 | 80 | @keyframes zoominoutsinglefeatured { 81 | 0% { 82 | transform: scale(1,1); 83 | } 84 | 50% { 85 | transform: scale(1.2,1.2); 86 | } 87 | 100% { 88 | transform: scale(1,1); 89 | } 90 | } 91 | 92 | circle{ 93 | animation: zoominoutsinglefeatured 3s infinite ; 94 | } 95 | 96 | .gm-style div a, .gm-style div a div, .gm-style-cc, .gmnoprint { 97 | display: none; 98 | } 99 | 100 | .hIOJIb { 101 | background-color: #FFF !important; 102 | } 103 | 104 | #neoron button { 105 | cursor: pointer; 106 | } 107 | 108 | ._hj-f5b2a1eb-9b07_feedback_minimized_label{ 109 | zoom: 70%; 110 | } 111 | 112 | @media only screen and (max-width: 600px) { 113 | .rsc-float-button { 114 | background: white !important; 115 | zoom: 65% !important; 116 | bottom: 7rem !important; 117 | right: 1rem !important; 118 | } 119 | } 120 | 121 | .rsc-header { 122 | background: #FCFCFC !important; 123 | } 124 | 125 | .rsc-content { 126 | background: #282731; 127 | padding: 1rem; 128 | 129 | button { 130 | border-color: #FCFCFC !important; 131 | color: #FCFCFC !important; 132 | } 133 | } 134 | 135 | .rsc-ts-bubble { 136 | background: #d6d6d6 !important; 137 | color: #1f1f1f !important; 138 | 139 | div a b { 140 | color: #000 !important; 141 | font-weight: normal !important; 142 | } 143 | } 144 | 145 | .rsc-ts-user { 146 | .rsc-ts-bubble { 147 | background: #FFF !important; 148 | } 149 | } 150 | 151 | #ribon { 152 | width: 5rem; 153 | } 154 | 155 | .aboutOpenSource { 156 | color: #a4a4a4; 157 | font-size: 12px; 158 | 159 | a { 160 | color: #a4a4a4; 161 | text-decoration: underline; 162 | } 163 | } 164 | 165 | -------------------------------------------------------------------------------- /src/assets/scss/_cities.scss: -------------------------------------------------------------------------------- 1 | @include respond-to(mobile-xl) { 2 | .cities-scroller { 3 | max-height: 78vh; 4 | overflow-y: scroll; 5 | } 6 | 7 | .cities-grid { 8 | width: 50rem; 9 | } 10 | } 11 | 12 | .cities-scroller::-webkit-scrollbar { 13 | width: 0.7rem; 14 | } 15 | 16 | .cities-scroller::-webkit-scrollbar-track { 17 | background: $gray-70; 18 | } 19 | 20 | .cities-scroller::-webkit-scrollbar-thumb { 21 | background: $gray-50; 22 | } 23 | 24 | 25 | .states-scroller { 26 | max-height: 28vh; 27 | overflow-y: scroll; 28 | } -------------------------------------------------------------------------------- /src/assets/scss/_contentPlaceholder.scss: -------------------------------------------------------------------------------- 1 | .content-placeholder { 2 | 3 | margin: 0 auto; 4 | max-width: 375px; 5 | min-height: 200px; 6 | } 7 | 8 | @keyframes placeHolderShimmer{ 9 | 0%{ 10 | background-position: -468px 0 11 | } 12 | 100%{ 13 | background-position: 468px 0 14 | } 15 | } 16 | 17 | .animated-background { 18 | animation-duration: 1s; 19 | animation-fill-mode: forwards; 20 | animation-iteration-count: infinite; 21 | animation-name: placeHolderShimmer; 22 | animation-timing-function: linear; 23 | background: linear-gradient(to right, #282731 8%, #535354 18%, #282731 33%); 24 | background-size: 800px 104px; 25 | height: 8px; 26 | position: relative; 27 | margin-bottom: 5px; 28 | } 29 | .content-1{ 30 | width: 90%; 31 | } 32 | .content-2{ 33 | width: 80%; 34 | } 35 | .content-3{ 36 | width: 70%; 37 | } 38 | .content-4{ 39 | width: 80%; 40 | } -------------------------------------------------------------------------------- /src/assets/scss/_mixins.scss: -------------------------------------------------------------------------------- 1 | @mixin respond-to($breakpoint) { 2 | // from http://www.sitepoint.com/managing-responsive-breakpoints-sass/ 3 | $value: map-get($breakpoints, $breakpoint); 4 | 5 | @if $value != null { 6 | @media print, (min-width: $value) { 7 | @content; 8 | } 9 | } @else { 10 | @warn "Unfortunately, no value could be retrieved from `#{$breakpoint}`. " 11 | + 'Please make sure it is defined in `$breakpoints` map.'; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/assets/scss/_news.scss: -------------------------------------------------------------------------------- 1 | .news-item-header { 2 | padding: 0; 3 | } 4 | 5 | .news-item-header-image { 6 | position: relative; 7 | text-align: center; 8 | } 9 | 10 | .news-item-image { 11 | height: 135px; 12 | width: 100%; 13 | object-fit: cover; 14 | } 15 | 16 | .news-item-title { 17 | position: absolute; 18 | bottom: 20px; 19 | left: 16px; 20 | right: 16px; 21 | font-weight: bold; 22 | text-align: left; 23 | text-shadow: 1px 1px 1px #0000006e; 24 | } 25 | 26 | .news-info { 27 | color: $gray-20; 28 | font-size: 12px; 29 | line-height: 18px; 30 | } 31 | 32 | .news-date { 33 | float: right; 34 | margin-right: 10px; 35 | } 36 | 37 | @include respond-to(mobile) { 38 | .news-item-image { 39 | height: 200px; 40 | object-fit: cover; 41 | } 42 | } 43 | @include respond-to(mobile-xl) { 44 | //tablet 45 | .news-info, 46 | .new-content { 47 | font-size: 14px; 48 | line-height: 24px; 49 | letter-spacing: 1px; 50 | } 51 | 52 | .news-item-image { 53 | height: 280px; 54 | object-fit: cover; 55 | margin: 0 auto; 56 | } 57 | 58 | .news-item-title { 59 | display: none; 60 | } 61 | } 62 | 63 | @media only screen and (max-width: 767px) { 64 | .news-item-image { 65 | opacity: 0.5; 66 | } 67 | } -------------------------------------------------------------------------------- /src/assets/scss/_sidebar.scss: -------------------------------------------------------------------------------- 1 | .navbar { 2 | z-index: 1; 3 | position: fixed; 4 | background-color: $gray-70; 5 | transition: width 600ms ease; 6 | } 7 | 8 | .navbar-nav { 9 | list-style: none; 10 | padding: 0; 11 | margin: 0; 12 | display: flex; 13 | flex-direction: column; 14 | align-items: center; 15 | height: 100%; 16 | overflow: hidden; 17 | } 18 | 19 | .nav-item { 20 | width: 100%; 21 | } 22 | 23 | .nav-link { 24 | display: flex; 25 | align-items: center; 26 | height: 5rem; 27 | color: $medium-gray; 28 | text-decoration: none; 29 | transition: $transition-speed; 30 | } 31 | 32 | .nav-link:hover { 33 | background: $dark-gray; 34 | color: $light-gray; 35 | } 36 | 37 | .nav-link.-active { 38 | color: $light-gray; 39 | } 40 | 41 | .link-text { 42 | display: none; 43 | margin-left: 1rem; 44 | } 45 | 46 | .nav-link svg { 47 | width: 2rem; 48 | min-width: 2rem; 49 | margin: 0 1.5rem; 50 | } 51 | 52 | .logo { 53 | font-weight: bold; 54 | text-transform: uppercase; 55 | margin-bottom: 1rem; 56 | text-align: center; 57 | color: $light-gray; 58 | background: $dark-gray; 59 | font-size: 1.2rem; 60 | letter-spacing: 0.3ch; 61 | width: 100%; 62 | } 63 | 64 | .logo svg { 65 | display: block; 66 | } 67 | 68 | .logo-text { 69 | display: inline; 70 | position: absolute; 71 | left: -999px; 72 | transition: $transition-speed; 73 | } 74 | 75 | .navbar:hover .logo svg { 76 | display: none; 77 | } 78 | 79 | /* Small screens */ 80 | @media only screen and (max-width: 600px) { 81 | .navbar { 82 | bottom: 0; 83 | width: 100vw; 84 | height: $sidebar-mobile-height; 85 | } 86 | 87 | .nav-item { 88 | height: 100%; 89 | } 90 | 91 | .nav-link { 92 | flex-direction: column; 93 | height: 100%; 94 | 95 | svg { 96 | min-width: initial; 97 | align-items: center; 98 | width: $sidebar-mobile-icon; 99 | margin: 0 auto; 100 | } 101 | 102 | .link-text { 103 | margin: 6px 0 0 0; 104 | display: block; 105 | font-size: $font-size-12; 106 | } 107 | } 108 | 109 | .logo { 110 | display: none; 111 | } 112 | 113 | .navbar-nav { 114 | flex-direction: row; 115 | } 116 | 117 | .nav-link { 118 | justify-content: center; 119 | } 120 | 121 | main { 122 | margin: 0; 123 | padding-bottom: 60px; 124 | //min-height: 100vh; 125 | } 126 | } 127 | 128 | /* Large screens */ 129 | @media only screen and (min-width: 600px) { 130 | .navbar { 131 | top: 0; 132 | width: 5rem; 133 | height: 100vh; 134 | } 135 | 136 | .navbar:hover { 137 | width: 16rem; 138 | } 139 | 140 | .navbar:hover .link-text { 141 | display: inline; 142 | white-space: nowrap; 143 | } 144 | 145 | .navbar:hover .logo svg { 146 | margin-left: 11rem; 147 | } 148 | 149 | .navbar:hover .logo-text { 150 | left: 0px; 151 | } 152 | } 153 | 154 | .small-logo { 155 | margin: 0 auto; 156 | height: 35px; 157 | transition: $transition-speed; 158 | 159 | @media only screen and (min-width: map-get($map: $breakpoints, $key: "tablet")) { 160 | display: none; 161 | } 162 | } 163 | 164 | @media only screen and (min-width: map-get($map: $breakpoints, $key: "tablet")) { 165 | .navbar { 166 | top: 0; 167 | width: 16rem; 168 | height: 100vh; 169 | 170 | .logo-text { 171 | left: 0px; 172 | } 173 | } 174 | .linkt-text { 175 | display: inline; 176 | white-space: nowrap; 177 | } 178 | .nav-link { 179 | .link-text { 180 | margin: 6px 0 0 0; 181 | display: block; 182 | animation: fadeInLoad 2.5s; 183 | } 184 | } 185 | .logo { 186 | svg { 187 | display: none; 188 | } 189 | .nav-link { 190 | justify-content: center; 191 | 192 | background: $dark-gray; 193 | color: $light-gray; 194 | } 195 | .nav-link:hover { 196 | background: $gray-70; 197 | } 198 | .logo-text { 199 | position: relative; 200 | background: none; 201 | color: none; 202 | } 203 | .link-text { 204 | margin-left: 0; 205 | } 206 | } 207 | } 208 | @keyframes fadeInLoad { 209 | from { 210 | opacity: 0; 211 | } 212 | to { 213 | opacity: 1; 214 | } 215 | } 216 | 217 | //smartphones with width < 375px 218 | 219 | @media only screen and (max-width: 376px) { 220 | main{ 221 | padding-bottom: 90px; 222 | } 223 | } 224 | 225 | 226 | /* FIX NAVBAR FOR IPHONE WITH VIRTUAL BUTTON*/ 227 | 228 | /* iPhone X , XS, 11 Pro */ 229 | @media only screen and (min-device-width: 375px) and (max-device-height: 812px) and (-webkit-device-pixel-ratio: 3) { 230 | .navbar { 231 | bottom: 0; 232 | width: 100vw; 233 | height: 90px; 234 | } 235 | } 236 | 237 | /* iPhone XR, 11 */ 238 | @media only screen and (min-device-width : 414px) and (max-device-height : 896px) and (-webkit-device-pixel-ratio : 2) { 239 | .navbar { 240 | bottom: 0; 241 | width: 100vw; 242 | height: 90px; 243 | } 244 | } 245 | 246 | /* iPhone XS Max, 11 Pro Max */ 247 | @media only screen and (min-device-width : 414px) and (max-device-height : 896px) and (-webkit-device-pixel-ratio : 3) { 248 | .navbar { 249 | bottom: 0; 250 | width: 100vw; 251 | height: 90px; 252 | } 253 | } 254 | -------------------------------------------------------------------------------- /src/assets/scss/_variables.scss: -------------------------------------------------------------------------------- 1 | $blue-lighter: #a885fd; 2 | $black-lighter: #141414; 3 | $gray: #d8d8d8; 4 | $dark-gray: #141418; 5 | $medium-gray: #afafaf; 6 | $light-gray: #e6e6e6; 7 | $white-smoke: #f3f3f3; 8 | $section-bg: #fcfcfc; 9 | 10 | $white: #fff; 11 | $gray-10: #f8f8f8; 12 | $gray-20: #a4a4a4; 13 | $gray-30: #7f7f7f; 14 | $gray-40: #828282; 15 | $gray-50: #918e8c; 16 | $gray-60: #3a3a3a; 17 | $gray-70: #282832; 18 | $gray-80: #000000; 19 | $black: #000; 20 | 21 | $magenta: #fe008c; 22 | $blue: #50afe6; 23 | $light-blue: #f1f9ff; 24 | $light-green: #ecf7eb; 25 | $green: #0fb969; 26 | $dark-green: #004b50; 27 | $yellow: #ffc837; 28 | $light-yellow: #ffeb8c; 29 | $orange: #fa8728; 30 | $purple: #502350; 31 | $red: #ff0000; 32 | $logo-color: #ef7663; 33 | 34 | /* Fonts */ 35 | $font-size-40: 40px; 36 | $font-size-30: 30px; 37 | $font-size-26: 26px; 38 | $font-size-18: 18px; 39 | $font-size-16: 16px; 40 | $font-size-14: 14px; 41 | $font-size-12: 12px; 42 | 43 | /* Sidebar */ 44 | $sidebar-mobile-height: 60px; 45 | $sidebar-mobile-icon: 24px; 46 | 47 | $transition-speed: 600ms; 48 | $default-font-family: "Ubuntu", sans-serif; 49 | $default-font-size: $font-size-16; 50 | 51 | $breakpoints: ( 52 | "mobile": 576px, 53 | "mobile-xl": 768px, 54 | "tablet": 992px, 55 | "desktop": 1200px 56 | ); 57 | -------------------------------------------------------------------------------- /src/components/ArticleNewsHeader/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Style } from './styles'; 3 | 4 | const ArticleNewsHeader = (props) => { 5 | return ( 6 | 7 | 8 | {props.title} 9 | 10 | 11 | ); 12 | }; 13 | 14 | export default ArticleNewsHeader; 15 | -------------------------------------------------------------------------------- /src/components/ArticleNewsHeader/styles.js: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | export const ArticleBoxImage = styled.div` 4 | height: 134px; 5 | background-repeat: no-repeat; 6 | background-size: 100% 134px; 7 | width: 100%; 8 | display: flex; 9 | `; 10 | 11 | export const ArticleBoxTitle = styled.label` 12 | color: #fff; 13 | padding: 16px; 14 | font-weight: bold; 15 | font-size: 14px; 16 | line-height: 16px; 17 | background: rgba(0,0,0,0.5); 18 | display: flex; 19 | flex-direction: column-reverse; 20 | width: 100%; 21 | `; 22 | 23 | export const Style = { ArticleBoxTitle, ArticleBoxImage }; -------------------------------------------------------------------------------- /src/components/Button/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import * as styled from './styles.js'; 3 | 4 | const Button = (props) => { 5 | return ( 6 | <> 7 | {(() => { 8 | switch(props.styleButton) { 9 | case "sm-fi-btn": 10 | return {props.textButton}; 11 | case "md-fi-btn": 12 | return {props.textButton}; 13 | case "lg-fi-btn": 14 | return {props.textButton}; 15 | case "sm-un-btn": 16 | return {props.textButton}; 17 | case "md-un-btn": 18 | return {props.textButton}; 19 | case "lg-un-btn": 20 | return {props.textButton}; 21 | case "txt-btn": 22 | return {props.textButton}; 23 | case "sm-light-btn": 24 | return {props.textButton}; 25 | default: 26 | return
; 27 | } 28 | })()} 29 | 30 | ); 31 | }; 32 | 33 | export default Button; -------------------------------------------------------------------------------- /src/components/Button/styles.js: -------------------------------------------------------------------------------- 1 | import styled, { css } from 'styled-components'; 2 | 3 | export const SmallFilledButton = styled.button` 4 | text-transform: uppercase; 5 | border: 0px; 6 | padding: 8px 16px; 7 | border-radius: 4px; 8 | letter-spacing: 1px; 9 | font-size: 14px; 10 | font-weight: 500; 11 | ${props => 12 | props.disabled 13 | ? css`background: rgba(238, 119, 100, .50);` 14 | : css`background: #EE7764;` 15 | }; 16 | ${props => 17 | props.disabled 18 | ? css`color: rgba(245, 245, 245, .50);` 19 | : css`color: #FCFCFC;` 20 | }; 21 | height: 32px; 22 | ${props => 23 | props.disabled 24 | ? css`cursor: not-allowed;` 25 | : css`cursor: pointer;` 26 | }; 27 | outline: none; 28 | margin: 10px; 29 | 30 | &:active{ 31 | background: #E06653; 32 | } 33 | `; 34 | 35 | export const MediumFilledButton = styled(SmallFilledButton)` 36 | padding: 10px 20px; 37 | font-size: 16px; 38 | height: 40px; 39 | `; 40 | 41 | export const LargeFilledButton = styled(SmallFilledButton)` 42 | padding: 15px 24px; 43 | font-size: 16px; 44 | height: 48px; 45 | `; 46 | 47 | 48 | export const BackgroundDiv = styled.div` 49 | background: #303030; 50 | `; 51 | 52 | 53 | 54 | export const SmallUnfiledButton = styled.button` 55 | background: transparent; 56 | padding: 6px 16px; 57 | text-transform: uppercase; 58 | border: 0px; 59 | border-radius: 4px; 60 | letter-spacing: 1px; 61 | font-size: 14px; 62 | font-weight: 500; 63 | ${props => 64 | props.disabled 65 | ? css`box-shadow: 0 0 0 1px rgba(252, 252, 252, .50) inset;` 66 | : css`box-shadow: 0 0 0 1px #FCFCFC inset;` 67 | }; 68 | ${props => 69 | props.disabled 70 | ? css`color: rgba(252, 252, 252, .50);` 71 | : css`color: #FCFCFC;` 72 | }; 73 | height: 32px; 74 | ${props => 75 | props.disabled 76 | ? css`cursor: not-allowed;` 77 | : css`cursor: pointer;` 78 | }; 79 | outline: none; 80 | margin: 10px; 81 | 82 | &:active{ 83 | background: #fff; 84 | color: #EE7764; 85 | } 86 | `; 87 | 88 | export const MediumUnfiledButton = styled(SmallUnfiledButton)` 89 | padding: 10px 20px; 90 | font-size: 16px; 91 | height: 40px; 92 | `; 93 | 94 | export const LargeUnfiledButton = styled(SmallUnfiledButton)` 95 | padding: 15px 24px; 96 | font-size: 16px; 97 | height: 48px; 98 | `; 99 | 100 | 101 | export const TextButton = styled.button` 102 | background: transparent; 103 | padding: 6px 0px; 104 | text-transform: uppercase; 105 | border: 0px; 106 | letter-spacing: 1px; 107 | font-size: ${props => props.size + 'px'}; 108 | font-weight: 500; 109 | outline: none; 110 | ${props => 111 | props.disabled 112 | ? css`color: rgba(238, 119, 100, .50);` 113 | : css`color: #EE7764;` 114 | }; 115 | 116 | ${props => 117 | props.disabled 118 | ? css`cursor: not-allowed;` 119 | : css`cursor: pointer;` 120 | }; 121 | 122 | &:active{ 123 | color: #FA8875; 124 | } 125 | `; 126 | 127 | 128 | export const SmallLifiledButton = styled.button` 129 | padding: 6px 16px; 130 | text-transform: uppercase; 131 | border: 0px; 132 | border-radius: 4px; 133 | letter-spacing: 1px; 134 | font-size: 14px; 135 | font-weight: 500; 136 | ${props => 137 | props.disabled 138 | ? css`box-shadow: 0 0 0 1px rgba(252, 252, 252, .50) inset;` 139 | : css`box-shadow: 0 0 0 1px #FCFCFC inset;` 140 | }; 141 | ${props => 142 | props.disabled 143 | ? css`color: rgba(252, 252, 252, .50);` 144 | : css`color: #EE7764;` 145 | }; 146 | height: 32px; 147 | ${props => 148 | props.disabled 149 | ? css`cursor: not-allowed;` 150 | : css`cursor: pointer;` 151 | }; 152 | outline: none; 153 | 154 | &:active{ 155 | background: #ccc; 156 | color: #EE7764; 157 | } 158 | `; -------------------------------------------------------------------------------- /src/components/CardDonations/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Style } from './styles'; 3 | import Truncate from 'react-truncate'; 4 | 5 | const CardDonations = (props) => { 6 | return ( 7 | 8 | 9 | {props.title} 10 | 11 | 12 | {/**/} 13 | {props.content} 14 | {/**/} 15 | 16 | 17 | {props.footer} 18 | 19 | 20 | ); 21 | }; 22 | 23 | export default CardDonations; 24 | -------------------------------------------------------------------------------- /src/components/CardDonations/styles.js: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | export const CardBoxStyle = styled.div` 4 | /* background: ${props => props.theme.colors.primary}; */ 5 | color: #fff; 6 | font-size: 1em; 7 | padding: 1em; 8 | border: 1px solid ${props => props.theme.colors.primaryDark}; 9 | border-radius: ${props => props.theme.borderRadius}; 10 | display: flex; 11 | flex-direction: column; 12 | cursor: pointer; 13 | 14 | background: #232328; 15 | margin-bottom: 8px; 16 | 17 | position:relative; 18 | 19 | `; 20 | 21 | export const CardBoxTitle = styled.div` 22 | color: ${props => props.theme.colors.titleCard}; 23 | font-weight: 500; 24 | //font-size: 14px; 25 | line-height: 18px; 26 | 27 | @media all and (min-width: 768px) { 28 | //font-size: 1rem; 29 | font-size: 0.9rem; 30 | line-height: 1.5rem; 31 | } 32 | `; 33 | 34 | export const CardBoxContent = styled.div` 35 | color: ${props => props.theme.colors.contentCard}; 36 | font-size: 12px; 37 | margin: 8px 0; 38 | line-height: 18px; 39 | margin-bottom:32px; 40 | 41 | @media all and (min-width: 768px) { 42 | font-size: 0.875rem; 43 | line-height: 1.5rem; 44 | } 45 | `; 46 | 47 | export const CardBoxFooter = styled.div` 48 | color: ${props => props.theme.colors.footerCard}; 49 | font-weight: 300; 50 | font-size: 10px; 51 | line-height: 16px; 52 | display: flex; 53 | justify-content: space-between; 54 | 55 | position: absolute; 56 | bottom: 15px; 57 | `; 58 | 59 | export const Style = { 60 | CardBoxStyle, 61 | CardBoxTitle, 62 | CardBoxContent, 63 | CardBoxFooter 64 | }; 65 | -------------------------------------------------------------------------------- /src/components/CardNews/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Style } from './styles'; 3 | import Truncate from 'react-truncate'; 4 | 5 | const CardNews = (props) => { 6 | return ( 7 | 8 | 9 | {props.title} 10 | 11 | 12 | 13 | {props.content} 14 | 15 | 16 | 17 | {props.date.toLocaleDateString()}, {props.date.toLocaleTimeString()} 18 | {props.tag} 19 | 20 | 21 | ); 22 | }; 23 | 24 | export default CardNews; 25 | -------------------------------------------------------------------------------- /src/components/CardNews/styles.js: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | export const CardBoxStyle = styled.div` 4 | /* background: ${props => props.theme.colors.primary}; */ 5 | color: #fff; 6 | font-size: 1em; 7 | padding: 1em; 8 | border: 1px solid ${props => props.theme.colors.primaryDark}; 9 | border-radius: ${props => props.theme.borderRadius}; 10 | display: flex; 11 | flex-direction: column; 12 | cursor: pointer; 13 | 14 | background: #232328; 15 | margin-bottom: 8px; 16 | 17 | @media all and (min-width: 768px) { 18 | margin: 10px; 19 | max-width: 354px; 20 | } 21 | `; 22 | 23 | export const CardBoxTitle = styled.div` 24 | color: ${props => props.theme.colors.titleCard}; 25 | font-weight: 500; 26 | //font-size: 14px; 27 | line-height: 18px; 28 | 29 | @media all and (min-width: 768px) { 30 | //font-size: 1rem; 31 | font-size: 0.9rem; 32 | line-height: 1.5rem; 33 | } 34 | `; 35 | 36 | export const CardBoxContent = styled.div` 37 | color: ${props => props.theme.colors.contentCard}; 38 | font-size: 12px; 39 | margin: 8px 0; 40 | line-height: 18px; 41 | 42 | @media all and (min-width: 768px) { 43 | font-size: 0.875rem; 44 | line-height: 1.5rem; 45 | } 46 | `; 47 | 48 | export const CardBoxFooter = styled.div` 49 | color: ${props => props.theme.colors.footerCard}; 50 | font-weight: 300; 51 | font-size: 10px; 52 | line-height: 16px; 53 | display: flex; 54 | justify-content: space-between; 55 | `; 56 | 57 | export const Style = { 58 | CardBoxStyle, 59 | CardBoxTitle, 60 | CardBoxContent, 61 | CardBoxFooter 62 | }; 63 | -------------------------------------------------------------------------------- /src/components/CardStats/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Style } from "./styles"; 3 | 4 | const CardStats = props => { 5 | return ( 6 | 7 | {props.title} 8 | 9 | {(() => { 10 | switch (props.status) { 11 | case "recovered": 12 | return ( 13 | 14 | {props.count} 15 | 16 | ); 17 | case "confirmed": 18 | return ( 19 | 20 | {props.count} 21 | 22 | ); 23 | case "suspect": 24 | return ( 25 | 26 | {props.count} 27 | 28 | ); 29 | case "death": 30 | return ( 31 | {props.count} 32 | ); 33 | default: 34 | return
{props.count}
; 35 | } 36 | })()} 37 |
38 |
39 | ); 40 | }; 41 | 42 | export default CardStats; 43 | -------------------------------------------------------------------------------- /src/components/CardStats/styles.js: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | export const CardBoxStyle = styled.div` 4 | 5 | background: ${props => props.theme.colors.primary}; 6 | color: #fff; 7 | padding: 12px; 8 | /* border: 1px solid ${props => props.theme.colors.primaryDark}; */ 9 | border-radius: ${props => props.theme.borderRadius}; 10 | display: flex; 11 | flex-direction: column; 12 | 13 | @media all and (min-width: 600px) { 14 | padding: 16px; 15 | } 16 | `; 17 | 18 | export const Title = styled.span` 19 | font-size: 12px; 20 | 21 | @media all and (min-width: 600px) { 22 | font-size: 16px; 23 | } 24 | 25 | `; 26 | 27 | export const CardBoxStatsDefault = styled.div` 28 | font-size: 20px; 29 | font-weight: bold; 30 | line-height: 30px; 31 | color: ${props => props.theme.colors.statsDefault}; 32 | text-transform: uppercase; 33 | letter-spacing: 1px; 34 | 35 | `; 36 | 37 | export const CardBoxStatsConfirmed = styled.label` 38 | color: ${props => props.theme.colors.statsConfirmed}; 39 | `; 40 | 41 | export const CardBoxStatsRecovered = styled.label` 42 | color: ${props => props.theme.colors.statsRecovered}; 43 | `; 44 | 45 | export const CardBoxStatsSuspect = styled.label` 46 | color: ${props => props.theme.colors.statsSuspect}; 47 | `; 48 | 49 | export const CardBoxStatsDeath = styled.label` 50 | color: ${props => props.theme.colors.statsDeath}; 51 | `; 52 | 53 | export const Style = { 54 | CardBoxStyle, 55 | CardBoxStatsDefault, 56 | CardBoxStatsConfirmed, 57 | CardBoxStatsRecovered, 58 | CardBoxStatsSuspect, 59 | CardBoxStatsDeath, 60 | Title 61 | }; 62 | -------------------------------------------------------------------------------- /src/components/Charts/DailyCases/index.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import { Style } from '../styles'; 3 | import moment from 'moment'; 4 | 5 | import last30DaysService from '../../../services/last30Days'; 6 | 7 | import {Bar} from 'react-chartjs-2'; 8 | import Chart from 'chart.js'; 9 | 10 | const DailyCases = (props) => { 11 | 12 | const [responseAPI, setResponseAPI] = useState([]); 13 | 14 | const [lastDay, setLastDay] = useState(null); 15 | const [lastDayFormated, setLastDayFormated] = useState(null); 16 | 17 | const [labels, setLabels] = useState([]); 18 | const [values, setValues] = useState([]); 19 | 20 | const [graphic, setGraphic] = useState(null); 21 | 22 | 23 | useEffect(() => { 24 | getLastDay(); 25 | }, []); 26 | 27 | useEffect(() => { 28 | 29 | if(!lastDay || !lastDayFormated){ 30 | return 31 | } 32 | 33 | const maxDays = 20; 34 | 35 | const daysYMD = []; 36 | const daysMD = []; 37 | 38 | for(let index = 0; index <= maxDays; index++){ 39 | //pega o "i" dia antes do último retornado pela api 40 | let day = moment(lastDay).subtract(index, 'days'); 41 | //coloca no array o dia no formato da api y-m-d 42 | daysYMD.push(moment(day).format('YYYY-MM-DD')); 43 | 44 | //coloca no array o dia no formato dd/m 45 | daysMD.push(moment(day._d).format('l').split('/').reverse().slice(1).join('/')); 46 | 47 | } 48 | 49 | const newValues = daysYMD.map(day => { 50 | // let todayItem = responseAPI[0].totalCases; 51 | 52 | // console.log(todayItem); 53 | 54 | let totalNewCases = responseAPI.reduce((currentTotal, item) => { 55 | if(item.date == day){ 56 | return item.newCases; 57 | } 58 | return currentTotal 59 | }, 0); 60 | return totalNewCases; 61 | }); 62 | 63 | 64 | setLabels(daysMD); 65 | setValues(newValues); 66 | 67 | }, [lastDay, lastDayFormated]); 68 | 69 | useEffect(() => { 70 | if(!labels.length > 0 || !values.length > 0){ 71 | return 72 | } 73 | 74 | 75 | setGraphic( 76 | { 77 | labels: labels.reverse(), 78 | datasets: [ 79 | { 80 | backgroundColor: '#EF5350', 81 | hoverbackgroundColor: '#EF5350', 82 | data: values.reverse(), 83 | } 84 | ] 85 | } 86 | ); 87 | }, [labels, values]); 88 | 89 | async function getLastDay(){ 90 | const response = await last30DaysService.get().then(response => { 91 | return response.data; 92 | }); 93 | 94 | setResponseAPI(response); 95 | 96 | const lastDay = response[0]; 97 | 98 | const lastDayFormated = moment(lastDay.date).format('l').split('/').reverse().slice(1).join('/'); 99 | 100 | setLastDay(lastDay.date); 101 | setLastDayFormated(lastDayFormated); 102 | 103 | }; 104 | 105 | 106 | return( 107 | 108 | {props.title} 109 | 110 | { graphic && } 141 | 142 | 143 | 144 | ); 145 | 146 | } 147 | 148 | export default DailyCases; -------------------------------------------------------------------------------- /src/components/Charts/DailyDeaths/index.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import { Style } from '../styles'; 3 | import moment from 'moment'; 4 | 5 | import last30DaysService from '../../../services/last30Days'; 6 | 7 | import {Bar} from 'react-chartjs-2'; 8 | import Chart from 'chart.js'; 9 | 10 | const DailyDeaths = (props) => { 11 | const [responseAPI, setResponseAPI] = useState([]); 12 | 13 | const [lastDay, setLastDay] = useState(null); 14 | const [lastDayFormated, setLastDayFormated] = useState(null); 15 | 16 | const [labels, setLabels] = useState([]); 17 | const [values, setValues] = useState([]); 18 | 19 | const [graphic, setGraphic] = useState(null); 20 | 21 | 22 | useEffect(() => { 23 | getLastDay(); 24 | }, []); 25 | 26 | useEffect(() => { 27 | 28 | if(!lastDay || !lastDayFormated){ 29 | return 30 | } 31 | 32 | const maxDays = 20; 33 | 34 | const daysYMD = []; 35 | const daysMD = []; 36 | 37 | for(let index = 0; index <= maxDays; index++){ 38 | //pega o "i" dia antes do último retornado pela api 39 | let day = moment(lastDay).subtract(index, 'days'); 40 | //coloca no array o dia no formato da api y-m-d 41 | daysYMD.push(moment(day).format('YYYY-MM-DD')); 42 | 43 | //coloca no array o dia no formato dd/m 44 | daysMD.push(moment(day._d).format('l').split('/').reverse().slice(1).join('/')); 45 | 46 | } 47 | 48 | const newValues = daysYMD.map(day => { 49 | let totalNewDeaths = responseAPI.reduce((currentTotal, item) => { 50 | if(item.date == day){ 51 | return item.newDeaths; 52 | } 53 | return currentTotal 54 | }, 0); 55 | 56 | return totalNewDeaths; 57 | }); 58 | 59 | setLabels(daysMD); 60 | setValues(newValues); 61 | 62 | }, [lastDay, lastDayFormated]); 63 | 64 | useEffect(() => { 65 | if(!labels.length > 0 || !values.length > 0){ 66 | return 67 | } 68 | 69 | 70 | setGraphic( 71 | { 72 | labels: labels.reverse(), 73 | datasets: [ 74 | { 75 | backgroundColor: '#BDBDBD', 76 | hoverbackgroundColor: '#BDBDBD', 77 | data: values.reverse(), 78 | } 79 | ] 80 | } 81 | ); 82 | }, [labels, values]); 83 | 84 | async function getLastDay(){ 85 | const response = await last30DaysService.get().then(response => { 86 | return response.data; 87 | }); 88 | 89 | setResponseAPI(response); 90 | 91 | const lastDay = response[0]; 92 | 93 | const lastDayFormated = moment(lastDay.date).format('l').split('/').reverse().slice(1).join('/'); 94 | 95 | setLastDay(lastDay.date); 96 | setLastDayFormated(lastDayFormated); 97 | }; 98 | 99 | 100 | return( 101 | 102 | {props.title} 103 | 104 | { graphic && } 135 | 136 | 137 | 138 | ); 139 | 140 | } 141 | 142 | export default DailyDeaths; -------------------------------------------------------------------------------- /src/components/Charts/RegionCases/index.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import { Style } from '../styles'; 3 | import moment from 'moment'; 4 | 5 | import regionCasesService from '../../../services/regionCases'; 6 | 7 | import {Doughnut} from 'react-chartjs-2'; 8 | import Chart from 'chart.js'; 9 | 10 | const RegionCases = (props) => { 11 | const [responseAPI, setResponseAPI] = useState([]); 12 | 13 | const [lastDay, setLastDay] = useState(null); 14 | 15 | const [sul, setSul] = useState([]); 16 | const [sudeste, setSudeste] = useState([]); 17 | const [centroOeste, setCentroOeste] = useState([]); 18 | const [nordeste, setNordeste] = useState([]); 19 | const [norte, setNorte] = useState([]); 20 | 21 | const [graphic, setGraphic] = useState(null); 22 | 23 | useEffect(() => { 24 | getRegionCases(); 25 | }, [getRegionCases]); 26 | 27 | useEffect(() => { 28 | 29 | if(!lastDay){ 30 | return 31 | } 32 | 33 | const sulValue = responseAPI.reduce((currentTotal, item) => { 34 | 35 | if(item.date == lastDay && item.region == 'Sul' && item.codmun == null){ 36 | return currentTotal + item.totalCases 37 | } 38 | return currentTotal; 39 | }, 0); 40 | 41 | const sudesteValue = responseAPI.reduce((currentTotal, item) => { 42 | if(item.date == lastDay && item.region == 'Sudeste' && item.codmun == null){ 43 | return currentTotal + item.totalCases 44 | } 45 | return currentTotal; 46 | }, 0); 47 | 48 | const centroOesteValue = responseAPI.reduce((currentTotal, item) => { 49 | if(item.date == lastDay && item.region === 'Centro-Oeste' && item.codmun == null){ 50 | return currentTotal + item.totalCases; 51 | } 52 | return currentTotal; 53 | }, 0); 54 | 55 | const nordesteValue = responseAPI.reduce((currentTotal, item) => { 56 | if(item.date == lastDay && item.region == 'Nordeste' && item.codmun == null){ 57 | return currentTotal + item.totalCases 58 | } 59 | return currentTotal; 60 | }, 0); 61 | 62 | const norteValue = responseAPI.reduce((currentTotal, item) => { 63 | if(item.date == lastDay && item.region == 'Norte' && item.codmun == null){ 64 | return currentTotal + item.totalCases 65 | } 66 | return currentTotal; 67 | }, 0); 68 | 69 | setSul(sulValue); 70 | setSudeste(sudesteValue); 71 | setCentroOeste(centroOesteValue); 72 | setNordeste(nordesteValue); 73 | setNorte(norteValue); 74 | 75 | }, [lastDay, responseAPI]); 76 | 77 | useEffect(() => { 78 | 79 | setGraphic( 80 | { 81 | labels: ['Sul', 'Sudeste', 'Centro-oeste', 'Nordeste', 'Norte'], 82 | datasets: [ 83 | { 84 | backgroundColor: [ 85 | '#EF9350', 86 | '#50EFC9', 87 | '#6650EF', 88 | '#CC00FF', 89 | '#61DD27', 90 | ], 91 | borderWidth: 0.6, 92 | data: [sul, sudeste, centroOeste, nordeste, norte], 93 | 94 | } 95 | ], 96 | } 97 | ); 98 | }, [sul, sudeste, centroOeste, nordeste, norte]); 99 | 100 | async function getRegionCases(){ 101 | const response = await regionCasesService.get().then(response => { 102 | return response.data; 103 | }); 104 | 105 | setResponseAPI(response); 106 | 107 | const lastDay = response[1].date; 108 | 109 | setLastDay(lastDay); 110 | }; 111 | 112 | return( 113 | 114 | {props.title} 115 | 116 | { graphic && } 135 | 136 | 137 | 138 | ); 139 | 140 | } 141 | 142 | export default RegionCases; 143 | -------------------------------------------------------------------------------- /src/components/Charts/TotalCases/index.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import { Style } from '../styles'; 3 | import moment from 'moment'; 4 | 5 | import last30DaysService from '../../../services/last30Days'; 6 | 7 | import {Line} from 'react-chartjs-2'; 8 | import Chart from 'chart.js'; 9 | 10 | const TotalCases = (props) => { 11 | 12 | const [responseAPI, setResponseAPI] = useState([]); 13 | 14 | const [lastDayTCases, setLastDayTCases] = useState(null); 15 | const [lastDayFormatedTCases, setLastDayFormatedTCases] = useState(null); 16 | 17 | const [labelsTCases, setLabelsTCases] = useState([]); 18 | const [valuesTCases, setValuesTCases] = useState([]); 19 | 20 | const [graphicTCases, setGraphicTCases] = useState(null); 21 | 22 | useEffect(() => { 23 | getLastDay(); 24 | }, []); 25 | 26 | useEffect(() => { 27 | if(!lastDayTCases || !lastDayFormatedTCases){ 28 | return 29 | } 30 | 31 | const maxDays = 20; 32 | 33 | const daysYMD = []; 34 | const daysMD = []; 35 | 36 | for(let index = 0; index <= maxDays; index++){ 37 | let day = moment(lastDayTCases).subtract(index, 'days'); 38 | 39 | daysYMD.push(moment(day).format('YYYY-MM-DD')); 40 | 41 | daysMD.push(moment(day._d).format('l').split('/').reverse().slice(1).join('/')); 42 | } 43 | 44 | const newValues = daysYMD.map(day => { 45 | let totalNewCasesBr = responseAPI.reduce((currentTotal, item) => { 46 | if(item.date == day){ 47 | return currentTotal + item.totalCases 48 | } 49 | return currentTotal 50 | 51 | }, 0); 52 | 53 | return totalNewCasesBr 54 | }); 55 | 56 | setLabelsTCases(daysMD); 57 | setValuesTCases(newValues); 58 | 59 | }, [lastDayTCases, lastDayFormatedTCases]); 60 | 61 | useEffect(() => { 62 | if(!labelsTCases.length > 0 || !valuesTCases.length > 0){ 63 | return 64 | } 65 | 66 | setGraphicTCases( 67 | { 68 | labels: labelsTCases.reverse(), 69 | datasets: [ 70 | { 71 | fill: false, 72 | lineTension: 0.1, 73 | backgroundColor: '#EF5350', 74 | borderColor: '#EF5350', 75 | borderCapStyle: 'round', 76 | borderJoinStyle: 'miter', 77 | pointBorderColor: '#EF5350', 78 | pointBackgroundColor: '#EF5350', 79 | borderWidth: 4, 80 | pointBorderWidth: 2, 81 | pointHoverRadius: 5, 82 | pointRadius: 0, 83 | pointHitRadius: 10, 84 | data: valuesTCases.reverse(), 85 | } 86 | ] 87 | } 88 | ); 89 | }, [labelsTCases, valuesTCases]); 90 | 91 | async function getLastDay(){ 92 | const response = await last30DaysService.get().then(response => { 93 | return response.data; 94 | }); 95 | 96 | setResponseAPI(response); 97 | 98 | const lastDay = response[0]; 99 | 100 | const lastDayFormated = moment(lastDay.date).format('l').split('/').reverse().slice(1).join('/'); 101 | 102 | setLastDayTCases(lastDay.date); 103 | setLastDayFormatedTCases(lastDayFormated); 104 | 105 | }; 106 | 107 | 108 | return( 109 | 110 | {props.title} 111 | 112 | { graphicTCases && } 142 | 143 | 144 | 145 | ); 146 | 147 | } 148 | 149 | export default TotalCases; -------------------------------------------------------------------------------- /src/components/Charts/TotalDeaths/index.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import { Style } from '../styles'; 3 | import moment from 'moment'; 4 | 5 | import last30DaysService from '../../../services/last30Days'; 6 | 7 | import {Line} from 'react-chartjs-2'; 8 | import Chart from 'chart.js'; 9 | 10 | const TotalDeaths = (props) => { 11 | const [responseAPI, setResponseAPI] = useState([]); 12 | 13 | const [lastDayTDeaths, setLastDayTDeaths] = useState(null); 14 | const [lastDayFormatedTDeaths, setLastDayFormatedTDeaths] = useState(null); 15 | 16 | const [labelsTDeaths, setLabelsTDeaths] = useState([]); 17 | const [valuesTDeaths, setValuesTDeaths] = useState([]); 18 | 19 | const [graphicTDeaths, setGraphicTDeaths] = useState(null); 20 | 21 | useEffect(() => { 22 | getLastDay(); 23 | }, []); 24 | 25 | useEffect(() => { 26 | 27 | if(!lastDayTDeaths || !lastDayFormatedTDeaths){ 28 | return 29 | } 30 | 31 | const maxDays = 20; 32 | 33 | const daysYMD = []; 34 | const daysMD = []; 35 | 36 | for(let index = 0; index <= maxDays; index++){ 37 | //pega o "i" dia antes do último retornado pela api 38 | let day = moment(lastDayTDeaths).subtract(index, 'days'); 39 | //coloca no array o dia no formato da api y-m-d 40 | daysYMD.push(moment(day).format('YYYY-MM-DD')); 41 | 42 | //coloca no array o dia no formato dd/m 43 | daysMD.push(moment(day._d).format('l').split('/').reverse().slice(1).join('/')); 44 | 45 | } 46 | 47 | const newValues = daysYMD.map(day => { 48 | let totalDeaths = responseAPI.reduce((currentTotal, item) => { 49 | if(item.date == day){ 50 | return currentTotal + item.totalDeaths 51 | } 52 | return currentTotal 53 | 54 | }, 0); 55 | 56 | return totalDeaths; 57 | }); 58 | 59 | setLabelsTDeaths(daysMD); 60 | setValuesTDeaths(newValues); 61 | 62 | }, [lastDayTDeaths, lastDayFormatedTDeaths]); 63 | 64 | useEffect(() => { 65 | if(!labelsTDeaths.length > 0 || !valuesTDeaths.length > 0){ 66 | return 67 | } 68 | 69 | 70 | setGraphicTDeaths( 71 | { 72 | labels: labelsTDeaths.reverse(), 73 | datasets: [ 74 | { 75 | fill: false, 76 | lineTension: 0.1, 77 | backgroundColor: '#BDBDBD', 78 | borderColor: '#BDBDBD', 79 | borderCapStyle: 'round', 80 | borderJoinStyle: 'miter', 81 | pointBorderColor: '#BDBDBD', 82 | pointBackgroundColor: '#BDBDBD', 83 | borderWidth: 4, 84 | pointBorderWidth: 2, 85 | pointHoverRadius: 5, 86 | pointRadius: 0, 87 | pointHitRadius: 10, 88 | data: valuesTDeaths.reverse(), 89 | } 90 | ] 91 | } 92 | ); 93 | }, [labelsTDeaths, valuesTDeaths]); 94 | 95 | async function getLastDay(){ 96 | const response = await last30DaysService.get().then(response => { 97 | return response.data; 98 | }); 99 | 100 | setResponseAPI(response); 101 | 102 | const lastDay = response[0]; 103 | 104 | const lastDayFormated = moment(lastDay.date).format('l').split('/').reverse().slice(1).join('/'); 105 | 106 | setLastDayTDeaths(lastDay.date); 107 | setLastDayFormatedTDeaths(lastDayFormated); 108 | 109 | 110 | }; 111 | 112 | 113 | return( 114 | 115 | {props.title} 116 | 117 | {graphicTDeaths && } 147 | 148 | 149 | 150 | ); 151 | 152 | } 153 | 154 | export default TotalDeaths; -------------------------------------------------------------------------------- /src/components/Charts/styles.js: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | export const CardBoxStyle = styled.div` 4 | 5 | background: ${props => props.theme.colors.primary}; 6 | color: #fff; 7 | padding: 12px; 8 | /* border: 1px solid ${props => props.theme.colors.primaryDark}; */ 9 | border-radius: ${props => props.theme.borderRadius}; 10 | display: flex; 11 | flex-direction: column; 12 | 13 | @media all and (min-width: 600px) { 14 | padding: 16px; 15 | } 16 | `; 17 | 18 | export const Title = styled.span` 19 | font-size: 12px; 20 | margin-bottom: 1em; 21 | 22 | @media all and (min-width: 600px) { 23 | font-size: 16px; 24 | } 25 | 26 | `; 27 | 28 | export const CardBoxStatsDefault = styled.div` 29 | font-size: 20px; 30 | font-weight: bold; 31 | line-height: 30px; 32 | color: ${props => props.theme.colors.statsDefault}; 33 | text-transform: uppercase; 34 | letter-spacing: 1px; 35 | 36 | `; 37 | 38 | export const CardBoxStatsConfirmed = styled.label` 39 | color: ${props => props.theme.colors.statsConfirmed}; 40 | `; 41 | 42 | export const CardBoxStatsRecovered = styled.label` 43 | color: ${props => props.theme.colors.statsRecovered}; 44 | `; 45 | 46 | export const CardBoxStatsSuspect = styled.label` 47 | color: ${props => props.theme.colors.statsSuspect}; 48 | `; 49 | 50 | export const CardBoxStatsDeath = styled.label` 51 | color: ${props => props.theme.colors.statsDeath}; 52 | `; 53 | 54 | export const Style = { 55 | CardBoxStyle, 56 | CardBoxStatsDefault, 57 | CardBoxStatsConfirmed, 58 | CardBoxStatsRecovered, 59 | CardBoxStatsSuspect, 60 | CardBoxStatsDeath, 61 | Title 62 | }; 63 | -------------------------------------------------------------------------------- /src/components/Chips/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Style } from './styles'; 3 | import Dots from '../Dots' 4 | 5 | const Chips = (props) => { 6 | return ( 7 | 8 | 9 | 10 | 11 | {props.text} {props.lastUpdate} 12 | 13 | ); 14 | }; 15 | 16 | export default Chips; 17 | -------------------------------------------------------------------------------- /src/components/Chips/styles.js: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | export const ChipStyle = styled.div` 4 | background: ${props => props.theme.colors.primary}; 5 | color: #fff; 6 | font-size: 1em; 7 | padding: 8px 16px; 8 | margin: 0 5px; 9 | line-height: 0px; 10 | border-radius: 4px; 11 | display: flex; 12 | min-height: ${props => props.height || `47`}px; 13 | flex-direction: row; 14 | align-items: center; 15 | width: fit-content; 16 | ${props => props.onClick && `cursor: pointer;`} 17 | `; 18 | 19 | export const ColumnDot = styled.div` 20 | padding-right: 8px; 21 | `; 22 | 23 | export const Style = { ChipStyle, ColumnDot }; -------------------------------------------------------------------------------- /src/components/Circle/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Style } from './styles'; 3 | import Dots from '../Dots' 4 | 5 | const Circle = (props) => { 6 | return ( 7 | 8 | {props.isCluster 9 | ? {props.pointCount} 10 | : ( 11 | props.type === 'you' && 12 | 13 | ) 14 | } 15 | 16 | ); 17 | }; 18 | 19 | export default Circle; -------------------------------------------------------------------------------- /src/components/Circle/styles.js: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | const CircleStyle = styled.div` 4 | border-radius: 50%; 5 | display: flex; 6 | align-items: center; 7 | justify-content: center; 8 | width: ${props => props.width || "80"}px; 9 | height: ${props => props.height || "80"}px; 10 | ${props => props.type === 'you' && `background-color: ${props.theme.colors.dotYou}25;`} 11 | ${props => props.type === 'suspect' && `background-color: ${props.theme.colors.dotSuspect}25;`} 12 | ${props => props.type === 'confirmed' && `background-color: ${props.theme.colors.dotConfirmed}25;`} 13 | ${props => props.type === 'recovered' && `background-color: ${props.theme.colors.dotRecovered}25;`} 14 | `; 15 | 16 | 17 | const CirclePointsText = styled.div` 18 | font-size: 20px; 19 | font-weight: bold; 20 | line-height: 30px; 21 | color: #FFF; 22 | letter-spacing: 1px; 23 | `; 24 | 25 | export const Style = { CircleStyle, CirclePointsText }; -------------------------------------------------------------------------------- /src/components/Dots/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Style } from './styles'; 3 | 4 | const Dots = (props) => { 5 | return ( 6 | (() => { 7 | switch(props.dot) { 8 | case "recovered": 9 | return ; 10 | case "confirmed": 11 | return ; 12 | case "suspect": 13 | return ; 14 | case "you": 15 | return ; 16 | case "hidden": 17 | return ; 18 | default: 19 | return ; 20 | } 21 | })() 22 | ); 23 | }; 24 | 25 | export default Dots; -------------------------------------------------------------------------------- /src/components/Dots/styles.js: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | export const DotDefault = styled.div` 4 | background-color: ${props => props.theme.colors.dotDefault}; 5 | border: 1px solid ${props => props.theme.colors.dotBorder}; 6 | box-sizing: border-box; 7 | height: 8px; 8 | width: 8px; 9 | border-radius:50%; 10 | `; 11 | 12 | export const DotYou = styled.div` 13 | background-color: ${props => props.theme.colors.dotYou}; 14 | border: 1px solid ${props => props.theme.colors.dotBorder}; 15 | box-sizing: border-box; 16 | height: 8px; 17 | width: 8px; 18 | border-radius:50%; 19 | `; 20 | 21 | export const DotSuspect = styled.div` 22 | background-color: ${props => props.theme.colors.dotSuspect}; 23 | border: 1px solid ${props => props.theme.colors.dotBorder}; 24 | box-sizing: border-box; 25 | height: 8px; 26 | width: 8px; 27 | border-radius:50%; 28 | `; 29 | 30 | export const DotRecovered = styled.div` 31 | background-color: ${props => props.theme.colors.dotRecovered}; 32 | border: 1px solid ${props => props.theme.colors.dotBorder}; 33 | box-sizing: border-box; 34 | height: 8px; 35 | width: 8px; 36 | border-radius:50%; 37 | `; 38 | 39 | export const DotConfirmed = styled.div` 40 | background-color: ${props => props.theme.colors.dotConfirmed}; 41 | border: 1px solid ${props => props.theme.colors.dotBorder}; 42 | box-sizing: border-box; 43 | height: 8px; 44 | width: 8px; 45 | border-radius:50%; 46 | `; 47 | 48 | export const DotHidden = styled.div` 49 | display: none; 50 | `; 51 | 52 | export const Style = { DotDefault, DotYou, DotSuspect, DotRecovered, DotConfirmed, DotHidden }; 53 | -------------------------------------------------------------------------------- /src/components/ExpandableBox/index.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import { 3 | ArrowIosUpwardOutline, 4 | ArrowIosDownwardOutline 5 | } from "@styled-icons/evaicons-outline"; 6 | 7 | import { 8 | ExpandableBox as ExpandableBoxStyle, 9 | ExpandableBoxBody, 10 | ExpandableBoxHeader, 11 | ExpandableBoxHeaderIcon 12 | } from "./styles"; 13 | 14 | const ExpandableBox = props => { 15 | const [open, setOpen] = useState(false); 16 | 17 | return ( 18 | 19 | setOpen(!open)}> 20 | {!open ? props.header : props.headerExpaned} 21 | 22 | {open ? ( 23 | 24 | ) : ( 25 | 26 | )} 27 | 28 | 29 | 30 | {open && {props.body}} 31 | 32 | ); 33 | }; 34 | 35 | export default ExpandableBox; 36 | -------------------------------------------------------------------------------- /src/components/ExpandableBox/styles.js: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | export const ExpandableBox = styled.div` 4 | background: ${props => props.theme.colors.primary}; 5 | color: #fff; 6 | font-size: 1em; 7 | border: 1px solid ${props => props.theme.colors.primaryDark}; 8 | border-radius: ${props => props.theme.borderRadius}; 9 | display: flex; 10 | flex-direction: column; 11 | `; 12 | export const ExpandableBoxHeader = styled.div` 13 | font-size: 12px; 14 | display: flex; 15 | flex: 1; 16 | align-items: center; 17 | position: relative; 18 | padding: 0 1em; 19 | min-height: 50px; 20 | `; 21 | export const ExpandableBoxHeaderIcon = styled.div` 22 | position: absolute; 23 | right: 1em; 24 | cursor: pointer; 25 | `; 26 | export const ExpandableBoxBody = styled.div` 27 | display: flex; 28 | `; 29 | -------------------------------------------------------------------------------- /src/components/Header/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import LogoSvg from "~/assets/icons/small-log.svg"; 4 | import Notification from "~/assets/icons/bell.svg"; 5 | import { Container, AlignItem, Title, Icon, LeftIcon } from "./styles"; 6 | import { Link } from 'react-router-dom'; 7 | 8 | const Header = ({ leftIcon, title, rightIcon, actionLeftIcon }) => { 9 | return ( 10 | 11 | 12 | 13 | {title} 14 | 15 | 16 | 17 | 18 | 19 | ); 20 | }; 21 | 22 | export default Header; 23 | -------------------------------------------------------------------------------- /src/components/Header/styles.js: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | export const Container = styled.div` 4 | background-color: ${props => props.theme.colors.primary}; 5 | display: flex; 6 | justify-content: space-between; 7 | align-items: center; 8 | height: ${props => props.theme.header.heigth}; 9 | padding: 0 20px; 10 | 11 | @media all and (min-width: 600px) { 12 | height: ${props => props.theme.header.largeHeigth}; 13 | } 14 | `; 15 | 16 | export const Title = styled.span` 17 | color: ${props => props.theme.colors.textColor}; 18 | font-size: ${props => props.theme.header.title}; 19 | font-weight: bold; 20 | line-height: 24px; 21 | letter-spacing: 1px; 22 | margin-left: 10px; 23 | 24 | @media all and (min-width: 600px) { 25 | color ${props => props.theme.colors.largeHeaderTitle}; 26 | font-size: ${props => props.theme.header.largeTitle}; 27 | } 28 | `; 29 | 30 | export const AlignItem = styled.div` 31 | display: flex; 32 | align-items: center; 33 | `; 34 | 35 | export const Icon = styled.img` 36 | height: 24px; 37 | alt: "icon"; 38 | `; 39 | 40 | export const LeftIcon = styled(Icon)` 41 | @media all and (min-width: 600px) { 42 | display: none; 43 | } 44 | `; 45 | -------------------------------------------------------------------------------- /src/components/Input/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { ContainerBox, Input as InputStyle, InputIcon } from './styles' 3 | import { CloseOutline } from '@styled-icons/evaicons-outline/CloseOutline' 4 | 5 | const Input = (props) => { 6 | return ( 7 | 8 | {props.icon && {props.icon}} 9 | 10 | {props.closeIcon && 11 | props.onCloseClick && props.onCloseClick()} color={"white"} size={"24px"} /> 12 | } 13 | 14 | ); 15 | }; 16 | 17 | export default Input; 18 | -------------------------------------------------------------------------------- /src/components/Input/styles.js: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | export const ContainerBox = styled.div` 4 | background: ${props => props.theme.colors.primary}; 5 | color: #fff; 6 | font-size: 1em; 7 | border: 1px solid ${props => props.theme.colors.primaryDark}; 8 | border-radius: ${props => props.theme.borderRadius}; 9 | display: flex; 10 | flex-direction: row; 11 | height: 48px; 12 | align-items:center; 13 | padding-left: 1em; 14 | padding-right: 1em; 15 | `; 16 | 17 | export const Input = styled.input` 18 | padding: 0; 19 | margin: 0; 20 | color: white; 21 | background: transparent; 22 | border: none; 23 | outline: none; 24 | font-size: 16px; 25 | flex: 1; 26 | display: flex; 27 | 28 | ::-webkit-input-placeholder { 29 | font-style: italic; 30 | } 31 | `; 32 | 33 | export const InputIcon = styled.div` 34 | margin-right: .5em; 35 | ` 36 | -------------------------------------------------------------------------------- /src/components/Loading/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const Loading = ({ spinning = true, fullScreen, transparent }) => ( 4 |
5 |
6 | 7 |
8 |
9 | ); 10 | 11 | export default Loading; 12 | -------------------------------------------------------------------------------- /src/components/MapArea/styles.js: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | export const ContainerMarker = styled.div` 4 | `; 5 | 6 | export const ContainerChips = styled.div` 7 | display: flex; 8 | margin: 20px; 9 | 10 | @media (max-width: 600px) { 11 | margin-bottom: 50px; 12 | } 13 | 14 | `; -------------------------------------------------------------------------------- /src/components/MapBrazil/styles.js: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | export const ContainerMarker = styled.div` 4 | `; 5 | 6 | export const ContainerChips = styled.div` 7 | display: flex; 8 | margin: 20px; 9 | 10 | @media (max-width: 600px) { 11 | margin-bottom: 50px; 12 | } 13 | 14 | `; -------------------------------------------------------------------------------- /src/components/MapCities/styles.js: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | export const MapControl = styled.div` 4 | right: 0.5rem; 5 | top: 3.5rem; 6 | position: absolute; 7 | display: flex; 8 | justify-content: flex-start; 9 | flex-flow: column wrap; 10 | 11 | button { 12 | background: ${props => props.theme.colors.primary}; 13 | border-color: ${props => props.theme.colors.primary}; 14 | color: #fff; 15 | } 16 | 17 | @media all and (min-width: 600px) { 18 | right: 0.5rem; 19 | top: 5.5rem; 20 | } 21 | 22 | @media all and (min-width: 768px) { 23 | right: 15px; 24 | top: 100px; 25 | } 26 | `; -------------------------------------------------------------------------------- /src/components/MapHome/styles.js: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | export const MapControl = styled.div` 4 | right: 0.5rem; 5 | top: 6rem; 6 | position: absolute; 7 | display: flex; 8 | justify-content: flex-start; 9 | flex-flow: column wrap; 10 | 11 | button { 12 | background: ${props => props.theme.colors.primary}; 13 | border-color: ${props => props.theme.colors.primary}; 14 | color: #fff; 15 | } 16 | 17 | @media all and (min-width: 600px) { 18 | right: 0.5rem; 19 | top: 8rem; 20 | } 21 | 22 | @media all and (min-width: 768px) { 23 | right: 15px; 24 | top: 20px; 25 | } 26 | `; 27 | -------------------------------------------------------------------------------- /src/components/Marker/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Style } from './styles'; 3 | 4 | import { ReactComponent as HospitalIcon } from "~assets/icons/hospital-marker.svg"; 5 | 6 | const Icon = ({ type }) => { 7 | switch (type) { 8 | case 'hospital': 9 | return ; 10 | default: 11 | return null; 12 | } 13 | } 14 | 15 | const Marker = (props) => { 16 | return ( 17 | 18 | 19 | 20 | ); 21 | }; 22 | 23 | export default Marker; 24 | -------------------------------------------------------------------------------- /src/components/Marker/styles.js: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | const MarkerStyle = styled.div` 4 | display: flex; 5 | height: 30px; 6 | width: 30px; 7 | align-items: center; 8 | justify-content: center; 9 | `; 10 | 11 | export const Style = { MarkerStyle }; -------------------------------------------------------------------------------- /src/components/SocialShare/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const SocialShare = () => ( 4 |
5 | 6 | 7 | 8 | 9 |
10 | ); 11 | 12 | export default SocialShare; -------------------------------------------------------------------------------- /src/components/Switch/index.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import { Container, Track, Thumb } from './styles' 3 | 4 | const Switch = ({ onChange, value }) => { 5 | const [active, setActive] = React.useState(!!value || false); 6 | 7 | useEffect(() => { 8 | setActive(!!value); 9 | }, [value]); 10 | 11 | useEffect(() => { 12 | onChange && onChange(active); 13 | }, [onChange, active]); 14 | 15 | return ( 16 | 17 | 18 | setActive(!active)} 23 | /> 24 | 25 | 26 | ); 27 | }; 28 | 29 | export default Switch; 30 | -------------------------------------------------------------------------------- /src/components/Switch/styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export const Container = styled.div` 4 | display: inline-block; 5 | padding: 3px; 6 | `; 7 | 8 | export const Track = styled.div` 9 | position: relative; 10 | width: 34px; 11 | height: 14px; 12 | border-radius: 7px; 13 | background-color: #808080; 14 | `; 15 | 16 | export const Thumb = styled.button.attrs({ type: 'button'})` 17 | cursor: pointer; 18 | width: 20px; 19 | height: 20px; 20 | border: none; 21 | border-radius: 50%; 22 | background-color: #F1F1F1; 23 | box-shadow: 0px 2px 2px 0px rgba(0,0,0,0.3); 24 | 25 | position: absolute; 26 | top: 50%; 27 | left: 0; 28 | transform: 29 | translateY(-50%) 30 | translateX(${({active}) => active ? '17px' : '-3px'}); 31 | transition: transform ease-in 250ms; 32 | 33 | :focus { 34 | outline:0; 35 | } 36 | `; 37 | -------------------------------------------------------------------------------- /src/components/index.js: -------------------------------------------------------------------------------- 1 | import ExpandableBox from "./ExpandableBox"; 2 | import Input from "./Input"; 3 | import Button from "./Button"; 4 | import CardDonations from "./CardDonations"; 5 | import CardStats from "./CardStats"; 6 | import CardNews from "./CardNews"; 7 | import ArticleNewsHeader from "./ArticleNewsHeader"; 8 | import Dots from "./Dots"; 9 | import Chips from "./Chips"; 10 | import Circle from "./Circle"; 11 | import Switch from "./Switch"; 12 | import Header from "./Header"; 13 | import MapHome from "./MapHome"; 14 | import MapBrazil from "./MapBrazil"; 15 | import MapCities from "./MapCities"; 16 | import SocialShare from "./SocialShare"; 17 | import DailyCases from "./Charts/DailyCases"; 18 | import DailyDeaths from "./Charts/DailyDeaths"; 19 | import TotalCases from "./Charts/TotalCases"; 20 | import RegionCases from "./Charts/RegionCases"; 21 | import TotalDeaths from "./Charts/TotalDeaths"; 22 | import CasesAndDeaths from "./Charts/CasesAndDeaths"; 23 | import MapArea from "./MapArea"; 24 | import Marker from "./Marker"; 25 | import Loading from "./Loading"; 26 | export { 27 | Input, 28 | ExpandableBox, 29 | Button, 30 | CardDonations, 31 | CardStats, 32 | CardNews, 33 | ArticleNewsHeader, 34 | Dots, 35 | Chips, 36 | Circle, 37 | Switch, 38 | Header, 39 | MapHome, 40 | MapCities, 41 | SocialShare, 42 | DailyCases, 43 | DailyDeaths, 44 | TotalCases, 45 | RegionCases, 46 | TotalDeaths, 47 | CasesAndDeaths, 48 | MapArea, 49 | Marker, 50 | MapBrazil, 51 | Loading, 52 | }; 53 | -------------------------------------------------------------------------------- /src/i18n/index.js: -------------------------------------------------------------------------------- 1 | import i18n from "i18next"; 2 | import { initReactI18next } from "react-i18next"; 3 | 4 | import Backend from "i18next-xhr-backend"; 5 | 6 | import LanguageDetector from "i18next-browser-languagedetector"; 7 | 8 | const Languages = ["pt", "en"]; 9 | const debugging = process.env.NODE_ENV === "development"; 10 | i18n 11 | .use(Backend) 12 | .use(LanguageDetector) 13 | .use(initReactI18next) 14 | .init({ 15 | fallbackLng: "pt", 16 | debug: debugging, 17 | whitelist: Languages, 18 | 19 | interpolation: { 20 | escapeValue: false 21 | } 22 | }); 23 | 24 | export default i18n; 25 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React, { Suspense } from "react"; 2 | import ReactDOM from "react-dom"; 3 | import { Provider } from "react-redux"; 4 | import { Router } from "react-router-dom"; 5 | import { ThemeProvider } from "styled-components"; 6 | 7 | import App from "./App"; 8 | import store from "./store"; 9 | import history from "./services/history"; 10 | import "./i18n"; 11 | import theme from "./styles/theme"; 12 | import GlobalFonts from "./styles/fonts"; 13 | 14 | ReactDOM.render( 15 | 16 | 17 | 18 | 19 | Carregando...}> 20 | 21 | 22 | 23 | 24 | , 25 | document.getElementById("root") 26 | ); 27 | -------------------------------------------------------------------------------- /src/layout/Sidebar/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useTranslation } from "react-i18next"; 3 | 4 | import { Link, withRouter } from "react-router-dom"; 5 | 6 | import Logo from "~assets/images/logo.svg"; 7 | import { ReactComponent as NewsIcon } from "~assets/icons/newspaper.svg"; 8 | import { ReactComponent as NewsIconActive } from "~assets/icons/newspaper-active.svg"; 9 | import { ReactComponent as Map } from "~assets/icons/map.svg"; 10 | import { ReactComponent as Donations } from "~assets/icons/donations.svg"; 11 | import { ReactComponent as DonationsActive } from "~assets/icons/donations-active.svg"; 12 | import { ReactComponent as MapActive } from "~assets/icons/map-active.svg"; 13 | import { ReactComponent as City } from "~assets/icons/city.svg"; 14 | import { ReactComponent as CityActive } from "~assets/icons/city-active.svg"; 15 | import { ReactComponent as Area } from "~assets/icons/area.svg"; 16 | import { ReactComponent as AreaActive } from "~assets/icons/area-active.svg"; 17 | import { ReactComponent as Help } from "~assets/icons/help.svg"; 18 | import { ReactComponent as HelpActive } from "~assets/icons/help-active.svg"; 19 | import { ReactComponent as SmallLogo } from "~/assets/icons/small-log.svg"; 20 | import { ReactComponent as AboutActive } from "~assets/icons/about-active.svg"; 21 | import { ReactComponent as About } from "~/assets/icons/about.svg"; 22 | 23 | const Sidebar = props => { 24 | const { pathname } = props.location; 25 | const [t] = useTranslation(); 26 | 27 | const routes = [ 28 | { 29 | title: "menu.map", 30 | path: "/", 31 | icon: pathname === "/" ? : 32 | }, 33 | // { 34 | // title: "menu.cities", 35 | // path: "/cities", 36 | // icon: pathname === "/cities" ? : 37 | //}, 38 | { 39 | title: "menu.area", 40 | path: "/area", 41 | icon: pathname === "/area" ? : 42 | }, 43 | // { 44 | // title: "menu.help", 45 | // path: "/help", 46 | // icon: pathname === "/help" ? : 47 | // }, 48 | // { 49 | // title: "menu.news", 50 | // path: "/news", 51 | // icon: pathname === "/news" ? : 52 | // }, 53 | { 54 | title: "menu.donations", 55 | path: "/donations", 56 | icon: pathname === "/donations" ? : 57 | } 58 | ]; 59 | 60 | const routeStaticAbout = [ 61 | { 62 | title: "Sobre", 63 | path: "https://covidzero.com.br/sobre/", 64 | icon: pathname === "https://covidzero.com.br/sobre/" ? : 65 | } 66 | ]; 67 | 68 | return ( 69 | 70 | 107 | ); 108 | }; 109 | 110 | export default withRouter(Sidebar); 111 | -------------------------------------------------------------------------------- /src/layout/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Sidebar from "./Sidebar"; 3 | 4 | import "./scss/Layout.scss"; 5 | 6 | const Layout = ({ children }) => { 7 | return ( 8 | 9 | 10 | 11 |
{children}
12 |
13 | ); 14 | }; 15 | 16 | export default Layout; 17 | -------------------------------------------------------------------------------- /src/layout/scss/Layout.scss: -------------------------------------------------------------------------------- 1 | @import "../../assets/scss/variables"; 2 | @import "../../assets/scss/mixins"; 3 | @import "../../assets/scss/base"; 4 | @import "../../assets/scss/sidebar"; 5 | @import "../../assets/scss/news"; 6 | @import "../../assets/scss/cities"; 7 | @import "../../assets/scss/loading"; 8 | @import "../../assets/scss/socialShared"; 9 | @import "../../assets/scss/area"; 10 | @import "../../assets/scss/_contentPlaceholder"; 11 | -------------------------------------------------------------------------------- /src/pages/Area/index.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from "react"; 2 | import { useTranslation } from "react-i18next"; 3 | 4 | import * as Styled from "./styles.js"; 5 | import usePosition from "~/services/usePosition"; 6 | import { Header } from "~/components"; 7 | import { MapArea } from "~/components"; 8 | import API from "~/API"; 9 | 10 | 11 | export default function Area() { 12 | const [t] = useTranslation(); 13 | let { latitude, longitude, error } = usePosition(); 14 | 15 | let initialZoom 16 | 17 | if (error) { 18 | /* se não conseguir pegar o lat e lng do usário coloca do Brasil */ 19 | initialZoom = 4 20 | latitude = -14.2350044 21 | longitude = -51.9252815 22 | } else { 23 | initialZoom = 14 24 | } 25 | 26 | const initalCases = { 27 | cases: [] 28 | } 29 | const [citiesCases, setTotalCases] = useState(initalCases) 30 | 31 | 32 | return ( 33 | <> 34 |
35 | 36 | {((latitude && longitude) || error) && 37 | 38 | 44 | 45 | } 46 | 47 | 48 | ); 49 | } 50 | -------------------------------------------------------------------------------- /src/pages/Area/styles.js: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | 4 | export const ContainerMap = styled.div` 5 | width: 100%; 6 | height: 93vh; 7 | 8 | @media (max-width: 600px){ 9 | height: 77vh; 10 | } 11 | 12 | /* iPhone X , XS, 11 Pro */ 13 | @media only screen and (min-device-width: 375px) and (max-device-height: 812px) and (-webkit-device-pixel-ratio: 3) { 14 | height: 66vh; 15 | } 16 | 17 | /* iPhone XR, 11 */ 18 | @media only screen and (min-device-width : 414px) and (max-device-height : 896px) and (-webkit-device-pixel-ratio : 2) { 19 | height: 74vh; 20 | } 21 | 22 | /* iPhone XS Max, 11 Pro Max */ 23 | @media only screen and (min-device-width : 414px) and (max-device-height : 896px) and (-webkit-device-pixel-ratio : 3) { 24 | height: 75vh; 25 | } 26 | `; 27 | 28 | export const Container = styled.section` 29 | 30 | @media (min-width: 840px) { 31 | height: 100%; 32 | overflow: hidden; 33 | position: relative; 34 | top: 0; 35 | width: 100%; 36 | display: flex; 37 | flex-flow: row-reverse; 38 | } 39 | `; -------------------------------------------------------------------------------- /src/pages/Brazil/index.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from "react"; 2 | import { Cell, Grid, Row } from "@material/react-layout-grid"; 3 | import { useTranslation } from "react-i18next"; 4 | import ReactTooltip from "react-tooltip"; 5 | 6 | import * as Styled from "./styles.js"; 7 | 8 | import { CardStats, DailyCases, DailyDeaths, TotalCases, RegionCases, TotalDeaths, CasesAndDeaths } from "~/components"; 9 | import { Header } from "~/components"; 10 | import { MapBrazil } from "~/components"; 11 | import { Chips } from "~/components"; 12 | import API from "~/API"; 13 | 14 | import totalCasesService from "../../services/totalCases"; 15 | 16 | const Brazil = () => { 17 | const now = new Date(); 18 | const [t] = useTranslation(); 19 | const [content, setContent] = useState(""); 20 | const initalCases = { 21 | confirmed: 0, 22 | suspected: 0, 23 | recovered: 0, 24 | deaths: 0, 25 | cases: [] 26 | } 27 | 28 | const [totalCases, setTotalCases] = useState(initalCases) 29 | 30 | const [totalCasesStates, setTotalCasesStates] = useState(0); 31 | const [totalDeathsStates, setTotalDeathsStates] = useState(0); 32 | 33 | const sumStateCases = (stateCases) => { 34 | let totalCases = { 35 | confirmed: 0, 36 | suspected: 0, 37 | recovered: 0, 38 | deaths: 0, 39 | cases: stateCases 40 | }; 41 | 42 | stateCases.map(stateCases => { 43 | totalCases.confirmed = totalCases.confirmed + stateCases.cases.confirmed; 44 | totalCases.suspected = totalCases.suspected + stateCases.cases.suspected; 45 | totalCases.recovered = totalCases.recovered + stateCases.cases.recovered; 46 | totalCases.deaths = totalCases.deaths + stateCases.cases.deaths; 47 | }) 48 | 49 | return totalCases; 50 | } 51 | 52 | async function totalCasesState(){ 53 | const response = await totalCasesService.get().then(response => { 54 | return response.data; 55 | }); 56 | 57 | setTotalCasesStates(response[0].totalCases); 58 | setTotalDeathsStates(response[0].totalDeaths); 59 | 60 | } 61 | 62 | useEffect(() => { 63 | (async () => { 64 | const stateCases = await API.cases.getStatesCases(); 65 | setTotalCases(sumStateCases(stateCases)) 66 | } 67 | )() 68 | 69 | totalCasesState(); 70 | }, []) 71 | 72 | return ( 73 | <> 74 |
75 | 76 | 77 | 78 | 83 | {content} 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | {/* 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | */} 136 | 137 | 138 |

Somos um projeto OpenSource. Para acesso ao nosso código fonte e fontes utilizadas, clique aqui.

139 |
140 |
141 |
142 |
143 |
144 | 145 | ); 146 | }; 147 | 148 | export default Brazil; 149 | -------------------------------------------------------------------------------- /src/pages/Brazil/styles.js: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | export const Container = styled.section` 4 | @media (min-width: 840px) { 5 | height: 100%; 6 | overflow: hidden; 7 | position: relative; 8 | top: 0; 9 | width: 100%; 10 | display: flex; 11 | flex-flow: row-reverse; 12 | } 13 | `; 14 | 15 | export const ContainerMap = styled.div` 16 | height:100vh; 17 | width:100vw; 18 | 19 | @media (max-width:840px) { 20 | height:60vh; 21 | } 22 | `; 23 | 24 | export const MobileBottomIndicators = styled.div` 25 | @media (max-width: 600px) { 26 | position: relative; 27 | bottom: 9vh; 28 | width: 100%; 29 | } 30 | 31 | @media screen and (device-width: 768px) { 32 | position: relative; 33 | width: 90%; 34 | } 35 | 36 | /* iPad Pro 12.9" */ 37 | /* Portrait and Landscape */ 38 | @media only screen 39 | and (min-device-width: 1024px) 40 | and (max-device-width: 1366px) 41 | and (-webkit-min-device-pixel-ratio: 2) { 42 | position: relative; 43 | bottom: 9vh; 44 | width: 100%; 45 | } 46 | `; 47 | -------------------------------------------------------------------------------- /src/pages/Cities/styles.js: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | export const Container = styled.section` 4 | @media (min-width: 840px) { 5 | height: 100%; 6 | top: 0; 7 | width: 100%; 8 | display: flex; 9 | flex-flow: row-reverse; 10 | p { 11 | display: block; 12 | } 13 | } 14 | @media (max-width: 840px) { 15 | p { 16 | font-size: 16; 17 | color: #fff; 18 | font-weight: bold; 19 | } 20 | } 21 | `; 22 | 23 | export const ContainerMap = styled.div` 24 | @media (min-width: 840px) { 25 | flex: 100%; 26 | margin-top: 2%; 27 | } 28 | @media (max-width: 840px) { 29 | display: block; 30 | } 31 | 32 | svg { 33 | touch-action: pan-left pan-down; 34 | circle { 35 | transition: all .25s ease-in-out; 36 | cursor: pointer; 37 | 38 | &:hover { 39 | transform: scale(1.25); 40 | } 41 | 42 | &:active { 43 | transform: scale(1.75); 44 | } 45 | } 46 | `; 47 | -------------------------------------------------------------------------------- /src/pages/Donations/checkoutBoleto.js: -------------------------------------------------------------------------------- 1 | import React,{useState,useEffect} from "react"; 2 | import {useParams } from "react-router-dom"; 3 | import { useTranslation } from "react-i18next"; 4 | import { Header,Button,Loading } from "~/components"; 5 | 6 | import * as Styled from "./styles.js"; 7 | 8 | export default function CheckoutBoleto() { 9 | const [t] = useTranslation(); 10 | let { id } = useParams(); 11 | 12 | const [loadingStatus, setloadingStatus] = useState(true) 13 | 14 | useEffect(() => { 15 | setloadingStatus(false) 16 | 17 | }, []); 18 | 19 | 20 | return ( 21 | <> 22 | 23 |
24 | 25 | 26 | 27 | Obrigado pela sua doação, FIRST_NAME! 28 | 29 | Ao recebermos a confirmação do pagamento do Boleto Bancário, sua doação de 100.00 será repassada diretamente para a ONG ONG_NAME. 30 | 31 | 32 | 33 | 34 | 35 |
36 | 37 | Código de barras 38 | 39 | 40 | 41 | 42 | 43 | 12345.12345 12345.12345678901.123456 1 23 123456789012 44 | 45 | 46 | 47 | Vencimento 22/03/2020 48 | 49 | 50 | 51 |
66 | 67 |
68 |
69 |

Pagamento processado por

70 | 71 | 72 |
73 |

O pagamento será processado por Preme Pay e estará disponível em sua fatura como CovidZero. Ao realizar o pagamento você concorda com os termos de uso.

74 |
75 |
76 | 77 | 78 |

O CNPJ da ONG ONG_NAME é ONG_CNPJ. Com ele, você poderá deduzir valores dos seus impostos a serem pagos.

79 | 80 |

Você receberá um email com a confirmação da doação.

81 |

A CovidZero não receberá nenhuma comissão sobre essa doação.

82 |
83 | 84 |
85 |
86 | 87 | 88 | ); 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/pages/Donations/confirmedCaptable.js: -------------------------------------------------------------------------------- 1 | import React,{useState,useEffect} from "react"; 2 | import {useParams} from "react-router-dom"; 3 | 4 | import { useTranslation } from "react-i18next"; 5 | import { Header,Button,Loading } from "~/components"; 6 | import * as Styled from "./styles.js"; 7 | 8 | 9 | 10 | 11 | export default function CheckoutBoleto() { 12 | const [t] = useTranslation(); 13 | let { id } = useParams(); 14 | 15 | const [loadingStatus, setloadingStatus] = useState(true) 16 | 17 | useEffect(() => { 18 | setloadingStatus(false) 19 | 20 | }, []); 21 | 22 | 23 | return ( 24 | <> 25 | 26 |
27 | 28 | 29 | 30 | Obrigado pela sua doação, FIRST_NAME! 31 | 32 | 33 |
34 | 35 | 36 |
37 | 38 | 39 | 40 |

Sua doação de AMOUNT foi confirmada e o valor será repassado diretamente para a ONG ONG_NAME.

41 | 42 |

O CNPJ da ONG ONG_NAME é ONG_CNPJ. Com ele, você poderá deduzir valores dos seus impostos a serem pagos.

43 | 44 |

Você receberá um email com a confirmação da doação.

45 | 46 |

A CovidZero não recebeu nenhuma comissão sobre essa doação.

47 |
48 | 49 | 50 | 51 |
52 |
53 |

Pagamento processado por

54 | 55 |
56 |
57 | 58 |
59 | 60 | 61 | ); 62 | 63 | } 64 | 65 | -------------------------------------------------------------------------------- /src/pages/Donations/confirmedPreme.js: -------------------------------------------------------------------------------- 1 | import React,{useState,useEffect} from "react"; 2 | import {useParams} from "react-router-dom"; 3 | 4 | import { useTranslation } from "react-i18next"; 5 | import { Header,Button,Loading } from "~/components"; 6 | import history from "~/services/history"; 7 | import * as Styled from "./styles.js"; 8 | 9 | import API from "~/API"; 10 | 11 | import ProjectsJson from "./projects.json"; 12 | 13 | export default function CheckoutBoleto() { 14 | const [t] = useTranslation(); 15 | let { storeId,customerId,orderNumber} = useParams(); 16 | 17 | const [loadingStatus, setloadingStatus] = useState(true) 18 | 19 | const initalParamPreme={ 20 | storeId, 21 | customerId, 22 | orderNumber, 23 | token:"" 24 | } 25 | 26 | const initalProjects = { 27 | id:0, 28 | name:"", 29 | about:"", 30 | goal:0, 31 | quota_total:0, 32 | quota_value:0, 33 | 34 | photo:{url:false} 35 | } 36 | 37 | 38 | const [Projects, setProjects] = useState(initalProjects); 39 | const [paramPreme,setParamPreme] = useState(initalParamPreme); 40 | const [dataOrder,setDataOrder] = useState({ 41 | customer:{ 42 | firstName:'' 43 | }, 44 | payment:{ 45 | amount:'' 46 | } 47 | 48 | }); 49 | 50 | 51 | 52 | 53 | 54 | useEffect(() => { 55 | 56 | (async () => { 57 | 58 | const response= await API.donationsPreme.Authentication(); 59 | 60 | setParamPreme({...paramPreme,token:response.token}); 61 | setloadingStatus(false) 62 | 63 | })() 64 | 65 | 66 | const projectsJson=ProjectsJson.find(({ id }) => id==storeId); 67 | 68 | if(typeof projectsJson !="undefined"){ 69 | setProjects(projectsJson); 70 | }else{ 71 | history.push("/donations"); 72 | } 73 | 74 | 75 | 76 | },[paramPreme, storeId]); 77 | 78 | 79 | 80 | useEffect(() => { 81 | if(paramPreme.token!=""){ 82 | API.donationsPreme.ListOrder(paramPreme).then(response =>{ 83 | 84 | 85 | setDataOrder(response); 86 | 87 | }); 88 | 89 | 90 | } 91 | 92 | },[paramPreme, paramPreme.token]); 93 | 94 | 95 | 96 | return ( 97 | <> 98 | 99 | 100 |
101 | 102 | 103 | 104 | 105 | Obrigado pela sua doação, {dataOrder.customer.firstName}! 106 | 107 | 108 |
109 | 110 | 111 |
112 | 113 | 114 |

Sua doação de {Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(dataOrder.payment.amount)} foi confirmada e o valor será repassado diretamente para a ONG Ribon.

115 | 116 |

O CNPJ da ONG Ribon é 26.660.577/0001-13. Com ele, você poderá deduzir valores dos seus impostos a serem pagos.

117 | 118 | 119 |

Você receberá um email com a confirmação da doação.

120 | 121 |

A CovidZero não recebeu nenhuma comissão sobre essa doação.

122 |
123 | 124 | 125 | 126 |
127 |
128 |

Pagamento processado por

129 | 130 | 131 | 132 | 133 |
134 |
135 | 136 |
137 | 138 | 139 | ); 140 | 141 | } 142 | 143 | -------------------------------------------------------------------------------- /src/pages/Donations/form.js: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | 3 | const Form = (callback) => { 4 | 5 | 6 | const inital = { 7 | 8 | first_name:"", 9 | surname:"", 10 | cpf: "", 11 | birthdate:"", 12 | email: "", 13 | phone: "", 14 | address: { 15 | street:"", 16 | number:"", 17 | zipcode:"", 18 | district:"", 19 | city: "", 20 | state: "", 21 | country: "BRL" 22 | } 23 | 24 | } 25 | 26 | const [values, setValues] = useState(inital); 27 | 28 | 29 | return [{ values }]; 30 | }; 31 | 32 | export default Form; -------------------------------------------------------------------------------- /src/pages/Donations/index.js: -------------------------------------------------------------------------------- 1 | import React,{useEffect,useState} from "react"; 2 | import { useTranslation } from "react-i18next"; 3 | import history from "~/services/history"; 4 | import { Header,Button, CardDonations } from "~/components"; 5 | 6 | import * as Styled from "./styles.js"; 7 | import API from "~/API"; 8 | 9 | import ProjectsJson from "./projects.json"; 10 | 11 | export default function Donations() { 12 | const [t] = useTranslation(); 13 | 14 | const [allProjects, setAllProjects] = useState([]) 15 | 16 | 17 | 18 | useEffect(() => { 19 | (async () => { 20 | API.donationsCaptable.findAllProjects().then(response => setAllProjects(response)); 21 | } 22 | )() 23 | },[]); 24 | 25 | 26 | 27 | 28 | return ( 29 | <> 30 |
31 | 32 | 33 | 34 | 35 | 36 | {/* CapTable */} 37 | {allProjects.map((ret, index) => ( 38 | {ret.about}

} 41 | footer={ 42 |