diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 000000000..95466ace5 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,19 @@ +name: ci + +on: + pull_request: + +jobs: + ci: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install dependencies + run: npm ci + working-directory: next + + - name: Run Biome format check + run: ./node_modules/.bin/biome format . + working-directory: next diff --git a/next/axios.js b/next/axios.js index 412e33914..d849eedbb 100644 --- a/next/axios.js +++ b/next/axios.js @@ -36,4 +36,4 @@ export const setAccessToken = (token) => { if (!token || token === "null") return (axiosInstance.defaults.headers.common["Authorization"] = null); axiosInstance.defaults.headers.common["Authorization"] = `Token ${token}`; -}; \ No newline at end of file +}; diff --git a/next/biome.json b/next/biome.json new file mode 100644 index 000000000..cd76b3a4c --- /dev/null +++ b/next/biome.json @@ -0,0 +1,45 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", + "vcs": { + "enabled": false, + "clientKind": "git", + "useIgnoreFile": false + }, + "files": { + "ignoreUnknown": false, + "ignore": [] + }, + "formatter": { + "enabled": true, + "indentStyle": "space", + "ignore": [".next/"] + }, + "organizeImports": { + "enabled": true + }, + "linter": { + "enabled": false, + "ignore": [".next/"], + "rules": { + "recommended": true + } + }, + "javascript": { + "formatter": { + "enabled": true + } + }, + "json": { + "formatter": { + "enabled": false + } + }, + "css": { + "linter": { + "enabled": false + }, + "formatter": { + "enabled": false + } + } +} diff --git a/next/components/atoms/Button.js b/next/components/atoms/Button.js index cef1264c2..0eefc3ae4 100644 --- a/next/components/atoms/Button.js +++ b/next/components/atoms/Button.js @@ -1,6 +1,4 @@ -import { - Box, -} from "@chakra-ui/react"; +import { Box } from "@chakra-ui/react"; export default function Button({ children, onClick, ...props }) { return ( @@ -23,11 +21,11 @@ export default function Button({ children, onClick, ...props }) { gap="8px" lineHeight="20px" _hover={{ - backgroundColor:"#22703E" + backgroundColor: "#22703E", }} {...props} > {children} - ) -} \ No newline at end of file + ); +} diff --git a/next/components/atoms/Carousel.js b/next/components/atoms/Carousel.js index ebdc18e32..587a1f408 100644 --- a/next/components/atoms/Carousel.js +++ b/next/components/atoms/Carousel.js @@ -1,7 +1,6 @@ import { Swiper, SwiperSlide } from "swiper/react"; import { Navigation, Pagination, Autoplay, Mousewheel } from "swiper"; - import "swiper/css"; import "swiper/css/navigation"; import "swiper/css/pagination"; @@ -9,14 +8,14 @@ import "swiper/css/autoplay"; export default function Carousel({ settings, children }) { return ( - - {children && children.map((elm, i)=> { - return ( - - {elm} - - ) - })} + + {children && + children.map((elm, i) => { + return {elm}; + })} - ) -} \ No newline at end of file + ); +} diff --git a/next/components/atoms/CategoryIcon.js b/next/components/atoms/CategoryIcon.js index 329936b15..81c31f54c 100644 --- a/next/components/atoms/CategoryIcon.js +++ b/next/components/atoms/CategoryIcon.js @@ -1,13 +1,5 @@ import { Image } from "@chakra-ui/react"; export function CategoryIcon({ url, active, size = "50px", ...style }) { - return ( - - ); + return ; } diff --git a/next/components/atoms/Checkbox.js b/next/components/atoms/Checkbox.js index 0029ac250..ff6f00589 100644 --- a/next/components/atoms/Checkbox.js +++ b/next/components/atoms/Checkbox.js @@ -1,12 +1,15 @@ -import { - Checkbox, - Icon -} from '@chakra-ui/react'; +import { Checkbox, Icon } from "@chakra-ui/react"; -function CustomCheckbockIcon({ variant, isIndeterminate, isChecked, ...props }) { +function CustomCheckbockIcon({ + variant, + isIndeterminate, + isChecked, + ...props +}) { function variantIcon() { - if(isIndeterminate) return "M5.06135 11.0002C4.76599 11.0002 4.51496 10.9029 4.30826 10.7084C4.10157 10.514 3.99823 10.2778 3.99823 9.99984C3.99823 9.72193 4.10157 9.48573 4.30826 9.29124C4.51496 9.09676 4.76599 8.99951 5.06135 8.99951H14.9391C15.2344 8.99951 15.4855 9.09676 15.6922 9.29124C15.8988 9.48573 16.0022 9.72193 16.0022 9.99984C16.0022 10.2778 15.8988 10.514 15.6922 10.7084C15.4855 10.9029 15.2344 11.0002 14.9391 11.0002H5.06135Z" - return "M7.17894 10.9259L13.306 4.7988C13.5043 4.60057 13.7378 4.50146 14.0068 4.50146C14.2758 4.50146 14.5094 4.60057 14.7076 4.7988C14.9058 4.99702 15.0049 5.23196 15.0049 5.50364C15.0049 5.7753 14.9058 6.01024 14.7076 6.20846L7.87972 13.0444C7.6815 13.2427 7.44791 13.3418 7.17894 13.3418C6.90998 13.3418 6.67639 13.2427 6.47817 13.0444L3.2943 9.86058C3.09609 9.66236 2.99834 9.42742 3.00103 9.15576C3.00373 8.88408 3.10418 8.64914 3.30241 8.45091C3.50063 8.25269 3.73557 8.15358 4.00725 8.15358C4.27891 8.15358 4.51385 8.25269 4.71207 8.45091L7.17894 10.9259Z" + if (isIndeterminate) + return "M5.06135 11.0002C4.76599 11.0002 4.51496 10.9029 4.30826 10.7084C4.10157 10.514 3.99823 10.2778 3.99823 9.99984C3.99823 9.72193 4.10157 9.48573 4.30826 9.29124C4.51496 9.09676 4.76599 8.99951 5.06135 8.99951H14.9391C15.2344 8.99951 15.4855 9.09676 15.6922 9.29124C15.8988 9.48573 16.0022 9.72193 16.0022 9.99984C16.0022 10.2778 15.8988 10.514 15.6922 10.7084C15.4855 10.9029 15.2344 11.0002 14.9391 11.0002H5.06135Z"; + return "M7.17894 10.9259L13.306 4.7988C13.5043 4.60057 13.7378 4.50146 14.0068 4.50146C14.2758 4.50146 14.5094 4.60057 14.7076 4.7988C14.9058 4.99702 15.0049 5.23196 15.0049 5.50364C15.0049 5.7753 14.9058 6.01024 14.7076 6.20846L7.87972 13.0444C7.6815 13.2427 7.44791 13.3418 7.17894 13.3418C6.90998 13.3418 6.67639 13.2427 6.47817 13.0444L3.2943 9.86058C3.09609 9.66236 2.99834 9.42742 3.00103 9.15576C3.00373 8.88408 3.10418 8.64914 3.30241 8.45091C3.50063 8.25269 3.73557 8.15358 4.00725 8.15358C4.27891 8.15358 4.51385 8.25269 4.71207 8.45091L7.17894 10.9259Z"; } return ( @@ -19,16 +22,21 @@ function CustomCheckbockIcon({ variant, isIndeterminate, isChecked, ...props }) viewBox={isIndeterminate ? "0 0 16 18" : "0 0 18 18"} _focus={{ boxShadow: "none", - outline: "none" + outline: "none", }} {...props} > - ) + ); } -export default function CustomCheckbox({ children, hasIndeterminate = false , icon, ...props}) { +export default function CustomCheckbox({ + children, + hasIndeterminate = false, + icon, + ...props +}) { return ( - } + icon={} {...props} > {children} - ) -} \ No newline at end of file + ); +} diff --git a/next/components/atoms/ControlledInput.js b/next/components/atoms/ControlledInput.js index 0f1799cc8..f51917b30 100644 --- a/next/components/atoms/ControlledInput.js +++ b/next/components/atoms/ControlledInput.js @@ -3,7 +3,7 @@ import { InputGroup, InputRightAddon, InputRightElement, - InputLeftElement + InputLeftElement, } from "@chakra-ui/react"; import { useEffect, useState } from "react"; @@ -36,20 +36,20 @@ export function ControlledInput({ onChange={(e) => onChange(e.target.value)} onKeyDown={checkForEnter} variant="outline" - padding={{base: "24px 48px 24px 20px", lg: "24px 64px 24px 32px"}} - height={{base: "50px", lg: "80px"}} + padding={{ base: "24px 48px 24px 20px", lg: "24px 64px 24px 32px" }} + height={{ base: "50px", lg: "80px" }} backgroundColor="#FFFFFF" - borderRadius={{base: "18px", lg: "25px"}} + borderRadius={{ base: "18px", lg: "25px" }} placeholder={placeholder} _placeholder={{ - color: "#717571" + color: "#717571", }} boxShadow="0 1px 8px 1px rgba(64, 60, 67, 0.16) !important" border="0" fontFamily="Roboto" fontWeight="400" - fontSize={{base: "16px", lg: "20px"}} - lineHeight={{base: "24px", lg: "30px"}} + fontSize={{ base: "16px", lg: "20px" }} + lineHeight={{ base: "24px", lg: "30px" }} color="#252A32" {...inputStyle} /> @@ -76,16 +76,18 @@ export function DebouncedSimpleControlledInput({ fill, ...props }) { - const [skipFirstDebounced, setSkipFirstDebounced] = useState(true) + const [skipFirstDebounced, setSkipFirstDebounced] = useState(true); const [_value, _setValue] = useState(value); const [_timeout, _setTimeout] = useState(null); useEffect(() => { clearTimeout(_timeout); - _setTimeout(setTimeout(() => { - if(!skipFirstDebounced) onChange(_value) - setSkipFirstDebounced(false) - }, 1000)); + _setTimeout( + setTimeout(() => { + if (!skipFirstDebounced) onChange(_value); + setSkipFirstDebounced(false); + }, 1000), + ); }, [_value]); useEffect(() => { @@ -118,11 +120,11 @@ export function DebouncedSimpleControlledInput({ border="2px solid transparent !important" color="#464A51" _hover={{ - border:"2px solid transparent !important", - backgroundColor:"#DEDFE0", + border: "2px solid transparent !important", + backgroundColor: "#DEDFE0", }} _focus={{ - border:"2px solid #0068C5 !important", + border: "2px solid #0068C5 !important", backgroundColor: "#FFF", }} paddingLeft="52px !important" @@ -134,7 +136,7 @@ export function DebouncedSimpleControlledInput({ fontFamily="Roboto" fontWeight="400" borderRadius="14px" - _placeholder={{color: "#464A51", opacity: 1}} + _placeholder={{ color: "#464A51", opacity: 1 }} {...inputStyle} /> @@ -191,11 +193,11 @@ export function ControlledInputSimple({ border="2px solid transparent !important" color="#464A51" _hover={{ - border:"2px solid transparent !important", - backgroundColor:"#DEDFE0", + border: "2px solid transparent !important", + backgroundColor: "#DEDFE0", }} _focus={{ - border:"2px solid #0068C5 !important", + border: "2px solid #0068C5 !important", backgroundColor: "#FFF", }} paddingLeft="52px !important" @@ -207,9 +209,9 @@ export function ControlledInputSimple({ fontFamily="Roboto" fontWeight="400" borderRadius="14px" - _placeholder={{color: "#464A51", opacity: 1}} + _placeholder={{ color: "#464A51", opacity: 1 }} {...inputStyle} /> - ) -} \ No newline at end of file + ); +} diff --git a/next/components/atoms/DatasetCardTag.js b/next/components/atoms/DatasetCardTag.js index ef65d18b7..0a0fcda0c 100644 --- a/next/components/atoms/DatasetCardTag.js +++ b/next/components/atoms/DatasetCardTag.js @@ -1,5 +1,5 @@ -import Link from './Link'; -import { Tag } from '@chakra-ui/react'; +import Link from "./Link"; +import { Tag } from "@chakra-ui/react"; export function DatasetCardTag({ slug, name, locale, ...props }) { return ( diff --git a/next/components/atoms/DomainComponent.js b/next/components/atoms/DomainComponent.js index 04b53e16a..4e6c46861 100644 --- a/next/components/atoms/DomainComponent.js +++ b/next/components/atoms/DomainComponent.js @@ -1,11 +1,12 @@ -import { useRouter } from 'next/router'; +import { useRouter } from "next/router"; export default function DomainComponent({ domains = [], children }) { const router = useRouter(); - const hostname = typeof window !== 'undefined' ? window.location.hostname : ''; + const hostname = + typeof window !== "undefined" ? window.location.hostname : ""; // Check if current hostname matches any of the allowed domains const shouldRender = domains.includes(hostname); return shouldRender ? children : null; -} \ No newline at end of file +} diff --git a/next/components/atoms/FilterAccordion.js b/next/components/atoms/FilterAccordion.js index 7086595ad..58ad6554e 100644 --- a/next/components/atoms/FilterAccordion.js +++ b/next/components/atoms/FilterAccordion.js @@ -8,9 +8,9 @@ import { VStack, Text, HStack, - Skeleton + Skeleton, } from "@chakra-ui/react"; -import { useTranslation } from 'next-i18next'; +import { useTranslation } from "next-i18next"; import { useEffect, useState } from "react"; import Checkbox from "../atoms/Checkbox"; import { ControlledInputSimple } from "./ControlledInput"; @@ -20,11 +20,10 @@ export function BaseFilterAccordion({ fieldName, children, isOpen = null, - onChange = () => { }, + onChange = () => {}, alwaysOpen = false, - isHovering = true + isHovering = true, }) { - return ( @@ -33,7 +32,9 @@ export function BaseFilterAccordion({ @@ -53,13 +54,15 @@ export function BaseFilterAccordion({ {fieldName} - {!alwaysOpen ? : <>} + {!alwaysOpen ? ( + + ) : ( + <> + )} {(isOpen && isOpen === true) || (isOpen == null && isExpanded) ? ( - <> - {children} - + <>{children} ) : ( <> )} @@ -82,27 +85,27 @@ export function CheckboxFilterAccordion({ isActive = false, isOpen = null, canSearch = false, - isLoading + isLoading, }) { - const { t } = useTranslation('search'); - const [options , setOptions] = useState([]) + const { t } = useTranslation("search"); + const [options, setOptions] = useState([]); const [search, setSearch] = useState(""); - const [inputFocus, setInputFocus] = useState(false) + const [inputFocus, setInputFocus] = useState(false); useEffect(() => { - if (choices === null) return - if (choices.length === 0) return - setOptions(choices) - }, [choices]) + if (choices === null) return; + if (choices.length === 0) return; + setOptions(choices); + }, [choices]); useEffect(() => { - const allOptions = choices - if(search === "" || undefined) return setOptions(choices) - const result = allOptions.filter((c) => - c[displayField].toLowerCase().indexOf(search.toLowerCase()) != -1 - ) - setOptions(result) - }, [search]) + const allOptions = choices; + if (search === "" || undefined) return setOptions(choices); + const result = allOptions.filter( + (c) => c[displayField].toLowerCase().indexOf(search.toLowerCase()) != -1, + ); + setOptions(result); + }, [search]); return ( - {canSearch && + {canSearch && ( - } + )} - {options.length > 0 && options.map((c) => ( - - { onChange(e.target.value)}} - minWidth="18px" - minHeight="18px" - maxWidth="18px" - maxHeight="18px" - marginRight="14px" - flexShrink={0} - /> + {options.length > 0 && + options.map((c) => ( - {c[displayField]} - - - {c["count"] ? `(${c["count"]})` : `(0)`} + { + onChange(e.target.value); + }} + minWidth="18px" + minHeight="18px" + maxWidth="18px" + maxHeight="18px" + marginRight="14px" + flexShrink={0} + /> + + {c[displayField]} + + + {c["count"] ? `(${c["count"]})` : `(0)`} + - - ))} + ))} ); } - diff --git a/next/components/atoms/GreenTab.js b/next/components/atoms/GreenTab.js index 1c5bf8d3c..80b0dfe2a 100644 --- a/next/components/atoms/GreenTab.js +++ b/next/components/atoms/GreenTab.js @@ -15,17 +15,17 @@ export default function GreenTab({ children, ...style }) { padding="12px 24px 13px" _selected={{ color: "#2B8C4D", - fill:"#2B8C4D", + fill: "#2B8C4D", pointerEvents: "none", - borderBottom: "3px solid #2B8C4D" + borderBottom: "3px solid #2B8C4D", }} _hover={{ color: "#464A51", - fill: "#464A51" + fill: "#464A51", }} {...style} > {children} - ) + ); } diff --git a/next/components/atoms/HelpWidget.js b/next/components/atoms/HelpWidget.js index c5bc71c1e..ce62f172b 100644 --- a/next/components/atoms/HelpWidget.js +++ b/next/components/atoms/HelpWidget.js @@ -1,18 +1,18 @@ -import React from 'react'; +import React from "react"; import { Menu, MenuButton, MenuList, MenuItem, MenuDivider, - Tooltip + Tooltip, } from "@chakra-ui/react"; -import HelpIcon from "../../public/img/icons/helpIcon" +import HelpIcon from "../../public/img/icons/helpIcon"; -export default function HelpWidget({options, tooltip}) { +export default function HelpWidget({ options, tooltip }) { const optionsRender = (options) => { return options.map((option, i) => { - if(option.name){ + if (option.name) { const menuItemProps = { key: i, letterSpacing: "0.1px", @@ -23,8 +23,8 @@ export default function HelpWidget({options, tooltip}) { color: "#252A32", backgroundColor: "#FFF", padding: "0 16px 10px", - _focus: {backgroundColor: "transparent"}, - _hover: {backgroundColor: "transparent", opacity: "0.7"}, + _focus: { backgroundColor: "transparent" }, + _hover: { backgroundColor: "transparent", opacity: "0.7" }, }; if (option.url) { @@ -47,13 +47,13 @@ export default function HelpWidget({options, tooltip}) { fontSize: "12px", fontFamily: "Roboto", color: "#252A32", - } + }, })} ); } - } else { - return ; + } else { + return ; } }); }; @@ -62,7 +62,7 @@ export default function HelpWidget({options, tooltip}) { {({ isOpen }) => ( <> - )} - ) -} \ No newline at end of file + ); +} diff --git a/next/components/atoms/LanguageSelector.js b/next/components/atoms/LanguageSelector.js index 984143f5d..a3614caf2 100644 --- a/next/components/atoms/LanguageSelector.js +++ b/next/components/atoms/LanguageSelector.js @@ -1,4 +1,11 @@ -import { Menu, MenuButton, MenuList, MenuItem, Box, Text } from "@chakra-ui/react"; +import { + Menu, + MenuButton, + MenuList, + MenuItem, + Box, + Text, +} from "@chakra-ui/react"; import { useRouter } from "next/router"; import GlobeIcon from "../../public/img/icons/globeIcon"; import { ChevronDownIcon } from "@chakra-ui/icons"; @@ -11,28 +18,28 @@ export default function LanguageSelector({ theme = "light" }) { light: { colors: { text: "#464A51", - icon: "#464A51" + icon: "#464A51", }, text: { fontSize: "12px", lineHeight: "18px", ml: "6px", mr: "4px", - fontFamily: "Roboto" + fontFamily: "Roboto", }, icon: { width: "16px", - height: "16px" + height: "16px", }, chevron: { w: 3, - h: 3 - } + h: 3, + }, }, dark: { colors: { text: "#FFFFFF", - icon: "#FFFFFF" + icon: "#FFFFFF", }, text: { fontSize: "16px", @@ -40,17 +47,17 @@ export default function LanguageSelector({ theme = "light" }) { lineHeight: "20px", ml: "8px", mr: "4px", - fontFamily: "Roboto" + fontFamily: "Roboto", }, icon: { width: "20px", - height: "20px" + height: "20px", }, chevron: { w: 4, - h: 4 - } - } + h: 4, + }, + }, }; const changeLanguage = (locale) => { @@ -58,15 +65,15 @@ export default function LanguageSelector({ theme = "light" }) { }; const getCurrentLanguage = () => { - switch(locale) { - case 'pt': - return 'Português'; - case 'en': - return 'English'; - case 'es': - return 'Español'; + switch (locale) { + case "pt": + return "Português"; + case "en": + return "English"; + case "es": + return "Español"; default: - return 'Português'; + return "Português"; } }; @@ -103,24 +110,26 @@ export default function LanguageSelector({ theme = "light" }) { > {getCurrentLanguage()} - - changeLanguage('pt')} + changeLanguage("pt")} letterSpacing="0.1px" lineHeight="18px" fontWeight="400" @@ -129,13 +138,13 @@ export default function LanguageSelector({ theme = "light" }) { color="#252A32" backgroundColor="#FFF" padding="0 16px 10px" - _focus={{backgroundColor: "transparent"}} - _hover={{backgroundColor: "transparent", opacity: "0.7"}} + _focus={{ backgroundColor: "transparent" }} + _hover={{ backgroundColor: "transparent", opacity: "0.7" }} > Português - changeLanguage('en')} + changeLanguage("en")} letterSpacing="0.1px" lineHeight="18px" fontWeight="400" @@ -144,13 +153,13 @@ export default function LanguageSelector({ theme = "light" }) { color="#252A32" backgroundColor="#FFF" padding="0 16px 10px" - _focus={{backgroundColor: "transparent"}} - _hover={{backgroundColor: "transparent", opacity: "0.7"}} + _focus={{ backgroundColor: "transparent" }} + _hover={{ backgroundColor: "transparent", opacity: "0.7" }} > English - changeLanguage('es')} + changeLanguage("es")} letterSpacing="0.1px" lineHeight="18px" fontWeight="400" @@ -159,8 +168,8 @@ export default function LanguageSelector({ theme = "light" }) { color="#252A32" backgroundColor="#FFF" padding="0 16px 10px" - _focus={{backgroundColor: "transparent"}} - _hover={{backgroundColor: "transparent", opacity: "0.7"}} + _focus={{ backgroundColor: "transparent" }} + _hover={{ backgroundColor: "transparent", opacity: "0.7" }} > Español @@ -169,4 +178,4 @@ export default function LanguageSelector({ theme = "light" }) { )} ); -} \ No newline at end of file +} diff --git a/next/components/atoms/Link.js b/next/components/atoms/Link.js index ee5b9f2cf..133a50ef0 100644 --- a/next/components/atoms/Link.js +++ b/next/components/atoms/Link.js @@ -1,6 +1,6 @@ import { Text } from "@chakra-ui/react"; -import NextLink from 'next/link'; -import { useRouter } from 'next/router'; +import NextLink from "next/link"; +import { useRouter } from "next/router"; import { useEffect, useState } from "react"; export default function Link({ @@ -49,7 +49,7 @@ export default function Link({ } return ( - + +
- ) -} \ No newline at end of file + ); +} diff --git a/next/components/atoms/ObservationLevelTable.js b/next/components/atoms/ObservationLevelTable.js index 8d2bda794..2076aac71 100644 --- a/next/components/atoms/ObservationLevelTable.js +++ b/next/components/atoms/ObservationLevelTable.js @@ -7,16 +7,19 @@ import { Th, Td, } from "@chakra-ui/react"; -import { useTranslation } from 'next-i18next'; -import { useRouter } from 'next/router'; +import { useTranslation } from "next-i18next"; +import { useRouter } from "next/router"; import { capitalize } from "lodash"; export default function ObservationLevel({ resource }) { - const { t } = useTranslation('dataset'); + const { t } = useTranslation("dataset"); const router = useRouter(); const { locale } = router; - const headers = [t('observationLevelTable.entityHeader'), t('observationLevelTable.columnsHeader')]; + const headers = [ + t("observationLevelTable.entityHeader"), + t("observationLevelTable.columnsHeader"), + ]; function sortElements(a, b) { if (a.order < b.order) { @@ -30,31 +33,34 @@ export default function ObservationLevel({ resource }) { let array = []; const keys = Object.keys(resource?.observationLevels); - const sortedLevels = Object.values(resource?.observationLevels).sort(sortElements); + const sortedLevels = Object.values(resource?.observationLevels).sort( + sortElements, + ); sortedLevels.forEach((value) => { const valueEntity = () => { - if(value.entity[`name${capitalize(locale)}`]) return value.entity[`name${capitalize(locale)}`]; - if(value.entity.name) return value.entity.name; - return t('observationLevelTable.notProvided'); - } + if (value.entity[`name${capitalize(locale)}`]) + return value.entity[`name${capitalize(locale)}`]; + if (value.entity.name) return value.entity.name; + return t("observationLevelTable.notProvided"); + }; const valueColumns = () => { - let columns = [] + let columns = []; - if(value?.columns[0]) { + if (value?.columns[0]) { Object.values(value.columns).map((column) => { - columns.push(column?.name) - }) + columns.push(column?.name); + }); } else { - columns = [t('observationLevelTable.notProvided')] + columns = [t("observationLevelTable.notProvided")]; } - return columns.join(", ") - } + return columns.join(", "); + }; - const newValue = [valueEntity(), valueColumns()] - array.push(newValue) - }) + const newValue = [valueEntity(), valueColumns()]; + array.push(newValue); + }); return ( {array.map((elm, i) => ( - + - ) -} \ No newline at end of file + ); +} diff --git a/next/components/atoms/PayPalButton.js b/next/components/atoms/PayPalButton.js index 0be640275..b5346b377 100644 --- a/next/components/atoms/PayPalButton.js +++ b/next/components/atoms/PayPalButton.js @@ -1,6 +1,6 @@ -import { useEffect } from 'react'; -import Script from 'next/script'; -import { useRouter } from 'next/router'; +import { useEffect } from "react"; +import Script from "next/script"; +import { useRouter } from "next/router"; const PayPalButton = () => { const router = useRouter(); @@ -10,9 +10,11 @@ const PayPalButton = () => { const renderButton = () => { if (window.paypal && window.paypal.HostedButtons) { const buttonConfig = getButtonConfig(locale); - window.paypal.HostedButtons({ - hostedButtonId: buttonConfig.id, - }).render(`#paypal-container-${buttonConfig.id}`); + window.paypal + .HostedButtons({ + hostedButtonId: buttonConfig.id, + }) + .render(`#paypal-container-${buttonConfig.id}`); } }; @@ -32,12 +34,12 @@ const PayPalButton = () => { const getButtonConfig = (locale) => { switch (locale) { - case 'en': - return { id: '7Z8VZRT49598E', localeParam: 'en_US' }; - case 'es': - return { id: '9T4KS6AZABF92', localeParam: 'es_ES' }; + case "en": + return { id: "7Z8VZRT49598E", localeParam: "en_US" }; + case "es": + return { id: "9T4KS6AZABF92", localeParam: "es_ES" }; default: - return { id: '9XUDXZSNZFS84', localeParam: 'pt_BR' }; + return { id: "9XUDXZSNZFS84", localeParam: "pt_BR" }; } }; diff --git a/next/components/atoms/ReadMore.js b/next/components/atoms/ReadMore.js index caa9dff61..6ab9042df 100644 --- a/next/components/atoms/ReadMore.js +++ b/next/components/atoms/ReadMore.js @@ -1,16 +1,13 @@ -import { - Flex, - Text, -} from "@chakra-ui/react"; +import { Flex, Text } from "@chakra-ui/react"; import { useState, useEffect, useRef } from "react"; -import { useTranslation } from 'next-i18next'; +import { useTranslation } from "next-i18next"; import BodyText from "./Text/BodyText"; -export default function ReadMore({ children, id, ...props}) { - const [isReadMore, setIsReadMore] = useState(false) - const [isOverflowing, setIsOverflowing] = useState(false) - const textRef = useRef(null) - const { t } = useTranslation('dataset'); +export default function ReadMore({ children, id, ...props }) { + const [isReadMore, setIsReadMore] = useState(false); + const [isOverflowing, setIsOverflowing] = useState(false); + const textRef = useRef(null); + const { t } = useTranslation("dataset"); const modifiedChildren = ` ${children.trim()} @@ -29,27 +26,29 @@ export default function ReadMore({ children, id, ...props}) { " onmouseover="this.style.color='#0057A4'" onmouseout="this.style.color='#0068C5'" - >${t('readLess')}` + >${t("readLess")}`; useEffect(() => { if (textRef.current) { - const { clientHeight, scrollHeight } = textRef.current - setIsOverflowing(scrollHeight > clientHeight) + const { clientHeight, scrollHeight } = textRef.current; + setIsOverflowing(scrollHeight > clientHeight); } - }, [children]) + }, [children]); useEffect(() => { - const readLess = document.getElementById(id) - if (readLess) readLess.addEventListener('click', toggleReadMore) - return () => { if (readLess) readLess.removeEventListener('click', toggleReadMore)} - }, [isReadMore]) + const readLess = document.getElementById(id); + if (readLess) readLess.addEventListener("click", toggleReadMore); + return () => { + if (readLess) readLess.removeEventListener("click", toggleReadMore); + }; + }, [isReadMore]); const toggleReadMore = () => { - setIsReadMore(!isReadMore) - } + setIsReadMore(!isReadMore); + }; return ( - + - {isOverflowing ? - - : + {isOverflowing ? ( + + ) : ( children - } + )} - {isOverflowing && + {isOverflowing && ( - ...{t('readMore')} + + ... + + {t("readMore")} - } + )} - ) + ); } diff --git a/next/components/atoms/ShadowBox.js b/next/components/atoms/ShadowBox.js index e65e17117..d9d0548af 100644 --- a/next/components/atoms/ShadowBox.js +++ b/next/components/atoms/ShadowBox.js @@ -10,7 +10,6 @@ export function ShadowBox({ titleStyle, ...props }) { - return ( - {image && - + {image && ( + {image} - } + )} - + {title} {children} diff --git a/next/components/atoms/SimpleTable.js b/next/components/atoms/SimpleTable.js index ddb0276ad..611049b4b 100644 --- a/next/components/atoms/SimpleTable.js +++ b/next/components/atoms/SimpleTable.js @@ -8,19 +8,9 @@ import { Td, } from "@chakra-ui/react"; -export function SimpleTable({ - headers, - values, - containerStyle, - valuesTable -}) { - +export function SimpleTable({ headers, values, containerStyle, valuesTable }) { return ( - + {headers.map((h, index) => ( @@ -39,9 +29,7 @@ export function SimpleTable({ borderBottom="1px solid #DEDFE0 !important" boxSizing="content-box" > -
- {h} -
+
{h}
))} @@ -73,5 +61,5 @@ export function SimpleTable({
- ) + ); } diff --git a/next/components/atoms/Tag.js b/next/components/atoms/Tag.js index 2ea13cfb9..55776e6b2 100644 --- a/next/components/atoms/Tag.js +++ b/next/components/atoms/Tag.js @@ -1,6 +1,6 @@ import { Tag, TagLabel, TagCloseButton } from "@chakra-ui/react"; -export function TagFilter({text, handleClick}) { +export function TagFilter({ text, handleClick }) { return ( handleClick()} /> - ) -} \ No newline at end of file + ); +} diff --git a/next/components/atoms/Text/BodyText.js b/next/components/atoms/Text/BodyText.js index 225ecadb6..6b9f9e0a5 100644 --- a/next/components/atoms/Text/BodyText.js +++ b/next/components/atoms/Text/BodyText.js @@ -15,7 +15,11 @@ const typographyStyles = { }, }; -export default function BodyText ({ children, typography = "medium", ...props }) { +export default function BodyText({ + children, + typography = "medium", + ...props +}) { const { fontSize, lineHeight } = typographyStyles[typography]; return ( @@ -30,4 +34,4 @@ export default function BodyText ({ children, typography = "medium", ...props }) {children}
); -}; \ No newline at end of file +} diff --git a/next/components/atoms/Text/Display.js b/next/components/atoms/Text/Display.js index 7b8727242..b2db57f31 100644 --- a/next/components/atoms/Text/Display.js +++ b/next/components/atoms/Text/Display.js @@ -15,7 +15,7 @@ const typographyStyles = { }, }; -export default function Display ({ children, typography = "medium", ...props }) { +export default function Display({ children, typography = "medium", ...props }) { const { fontSize, lineHeight } = typographyStyles[typography]; return ( @@ -30,4 +30,4 @@ export default function Display ({ children, typography = "medium", ...props }) {children} ); -}; \ No newline at end of file +} diff --git a/next/components/atoms/Text/LabelText.js b/next/components/atoms/Text/LabelText.js index 57af167df..f40344fe7 100644 --- a/next/components/atoms/Text/LabelText.js +++ b/next/components/atoms/Text/LabelText.js @@ -20,10 +20,14 @@ const typographyStyles = { "x-large": { fontSize: "20px", lineHeight: "30px", - } + }, }; -export default function LabelText ({ children, typography = "medium", ...props }) { +export default function LabelText({ + children, + typography = "medium", + ...props +}) { const { fontSize, lineHeight } = typographyStyles[typography]; return ( @@ -38,4 +42,4 @@ export default function LabelText ({ children, typography = "medium", ...props } {children} ); -}; \ No newline at end of file +} diff --git a/next/components/atoms/Text/TitleText.js b/next/components/atoms/Text/TitleText.js index 6659e2dc3..7e0967a4f 100644 --- a/next/components/atoms/Text/TitleText.js +++ b/next/components/atoms/Text/TitleText.js @@ -12,10 +12,14 @@ const typographyStyles = { large: { fontSize: "28px", lineHeight: "42px", - } + }, }; -export default function TitleText ({ children, typography = "medium", ...props }) { +export default function TitleText({ + children, + typography = "medium", + ...props +}) { const { fontSize, lineHeight } = typographyStyles[typography]; return ( @@ -30,4 +34,4 @@ export default function TitleText ({ children, typography = "medium", ...props } {children} ); -}; \ No newline at end of file +} diff --git a/next/components/atoms/Toggle.js b/next/components/atoms/Toggle.js index f9d74fe00..fa14d0250 100644 --- a/next/components/atoms/Toggle.js +++ b/next/components/atoms/Toggle.js @@ -1,7 +1,12 @@ import { Switch } from "@chakra-ui/react"; import styles from "../../styles/toggle.module.css"; -export default function Toggle({ value, onChange, className = "toggle", ...props }) { +export default function Toggle({ + value, + onChange, + className = "toggle", + ...props +}) { return ( - ) -} \ No newline at end of file + ); +} diff --git a/next/components/molecules/Card.js b/next/components/molecules/Card.js index e25ab0e74..b044e0902 100644 --- a/next/components/molecules/Card.js +++ b/next/components/molecules/Card.js @@ -1,8 +1,4 @@ -import { - Box, - HStack, - Flex -} from "@chakra-ui/react"; +import { Box, HStack, Flex } from "@chakra-ui/react"; export default function Card({ children, @@ -10,7 +6,6 @@ export default function Card({ spacing = 5, padding = "25px 25px 25px 25px", }) { - return ( - ) + ); } diff --git a/next/components/molecules/DataInformationQuery.js b/next/components/molecules/DataInformationQuery.js index 51e358f9f..c79cbd43c 100644 --- a/next/components/molecules/DataInformationQuery.js +++ b/next/components/molecules/DataInformationQuery.js @@ -12,7 +12,7 @@ import { Stack, useDisclosure, ModalCloseButton, - Spinner + Spinner, } from "@chakra-ui/react"; import { useState, useEffect, useRef } from "react"; import hljs from "highlight.js/lib/core"; @@ -20,8 +20,8 @@ import sqlHighlight from "highlight.js/lib/languages/sql"; import pythonHighlight from "highlight.js/lib/languages/python"; import rHighlight from "highlight.js/lib/languages/r"; import cookies from "js-cookie"; -import 'highlight.js/styles/obsidian.css' -import { useTranslation } from 'next-i18next'; +import "highlight.js/styles/obsidian.css"; +import { useTranslation } from "next-i18next"; import { useRouter } from "next/router"; import TitleText from "../atoms/Text/TitleText"; @@ -33,13 +33,10 @@ import Toggle from "../atoms/Toggle"; import TableColumns from "./TableColumns"; import { SectionPrice } from "../../pages/prices"; import { ModalGeneral } from "./uiUserPage"; -import { AlertDiscalimerBox} from "./DisclaimerBox"; +import { AlertDiscalimerBox } from "./DisclaimerBox"; import { triggerGAEvent, formatBytes } from "../../utils"; -import { - getBigTableQuery -} from "../../pages/api/tables" - +import { getBigTableQuery } from "../../pages/api/tables"; import { CopySolidIcon } from "../../public/img/icons/copyIcon"; import DownloadIcon from "../../public/img/icons/downloadIcon"; @@ -49,32 +46,32 @@ import CheckIcon from "../../public/img/icons/checkIcon"; import Link from "../atoms/Link"; export function CodeHighlight({ language, children }) { - const { t } = useTranslation('dataset'); - const textRef = useRef(null) - const [isOverflowing, setIsOverflowing] = useState(false) - const [isExpanded, setIsExpanded] = useState(true) + const { t } = useTranslation("dataset"); + const textRef = useRef(null); + const [isOverflowing, setIsOverflowing] = useState(false); + const [isExpanded, setIsExpanded] = useState(true); - const [highlightedCode, setHighlightedCode] = useState("") - const { hasCopied, onCopy } = useClipboard(children) + const [highlightedCode, setHighlightedCode] = useState(""); + const { hasCopied, onCopy } = useClipboard(children); useEffect(() => { - if(language === "sql") hljs.registerLanguage("sql", sqlHighlight) - if(language === "python") hljs.registerLanguage("python", pythonHighlight) - if(language === "r") hljs.registerLanguage("r", rHighlight) + if (language === "sql") hljs.registerLanguage("sql", sqlHighlight); + if (language === "python") hljs.registerLanguage("python", pythonHighlight); + if (language === "r") hljs.registerLanguage("r", rHighlight); - const highlighted = hljs.highlight(children, { language:language }).value - setHighlightedCode(highlighted) - }, [children, language]) + const highlighted = hljs.highlight(children, { language: language }).value; + setHighlightedCode(highlighted); + }, [children, language]); useEffect(() => { if (textRef.current) { - setIsOverflowing(false) - setIsExpanded(true) - const { clientHeight } = textRef.current - setIsOverflowing(clientHeight > 190) - if(clientHeight > 190) setIsExpanded(false) + setIsOverflowing(false); + setIsExpanded(true); + const { clientHeight } = textRef.current; + setIsOverflowing(clientHeight > 190); + if (clientHeight > 190) setIsExpanded(false); } - }, [highlightedCode]) + }, [highlightedCode]); return ( - {hasCopied ? t('table.copied') : t('table.copy')} - {hasCopied ? + {hasCopied ? t("table.copied") : t("table.copy")} + {hasCopied ? ( - : + ) : ( - } + )} @@ -154,8 +151,8 @@ export function CodeHighlight({ language, children }) { fill="#878A8E" color="#878A8E" _hover={{ - fill:"#9D9FA3", - color:"#9D9FA3" + fill: "#9D9FA3", + color: "#9D9FA3", }} > - - {isExpanded ? t('table.collapse') : t('table.expand')} + + {isExpanded ? t("table.collapse") : t("table.expand")} )} - ) + ); } export default function DataInformationQuery({ resource }) { - const { t } = useTranslation('dataset'); + const { t } = useTranslation("dataset"); const { locale } = useRouter(); - const [tabAccessIndex, setTabAccessIndex] = useState(0) - const [tabIndex, setTabIndex] = useState(0) - const [downloadPermitted, setDownloadPermitted] = useState(false) - const [downloadWarning, setDownloadWarning] = useState("") - const [checkedColumns, setCheckedColumns] = useState([]) - const [numberColumns, setNumberColumns] = useState(0) - const [sqlCode, setSqlCode] = useState("") - const [insufficientChecks, setInsufficientChecks] = useState(false) - const [includeTranslation, setIncludeTranslation] = useState(true) - const [hasLoadingColumns, setHasLoadingColumns] = useState(true) - const [isLoadingCode, setIsLoadingCode] = useState(false) - const [isLoadingSpin, setIsLoadingSpin] = useState(false) - const [hasLoadingResponse, setHasLoadingResponse] = useState(false) - const plansModal = useDisclosure() - - const [gcpProjectID, setGcpProjectID] = useState("") - const [gcpDatasetID, setGcpDatasetID] = useState("") - const [gcpTableId, setGcpTableId] = useState("") + const [tabAccessIndex, setTabAccessIndex] = useState(0); + const [tabIndex, setTabIndex] = useState(0); + const [downloadPermitted, setDownloadPermitted] = useState(false); + const [downloadWarning, setDownloadWarning] = useState(""); + const [checkedColumns, setCheckedColumns] = useState([]); + const [numberColumns, setNumberColumns] = useState(0); + const [sqlCode, setSqlCode] = useState(""); + const [insufficientChecks, setInsufficientChecks] = useState(false); + const [includeTranslation, setIncludeTranslation] = useState(true); + const [hasLoadingColumns, setHasLoadingColumns] = useState(true); + const [isLoadingCode, setIsLoadingCode] = useState(false); + const [isLoadingSpin, setIsLoadingSpin] = useState(false); + const [hasLoadingResponse, setHasLoadingResponse] = useState(false); + const plansModal = useDisclosure(); + + const [gcpProjectID, setGcpProjectID] = useState(""); + const [gcpDatasetID, setGcpDatasetID] = useState(""); + const [gcpTableId, setGcpTableId] = useState(""); const isUserPro = () => { - let user - if(cookies.get("userBD")) user = JSON.parse(cookies.get("userBD")) + let user; + if (cookies.get("userBD")) user = JSON.parse(cookies.get("userBD")); - if(user?.isSubscriber) return user?.isSubscriber - return false - } + if (user?.isSubscriber) return user?.isSubscriber; + return false; + }; useEffect(() => { - if(resource?.dataset?._id === "e083c9a2-1cee-4342-bedc-535cbad6f3cd") setIncludeTranslation(false) - }, [resource.dataset]) + if (resource?.dataset?._id === "e083c9a2-1cee-4342-bedc-535cbad6f3cd") + setIncludeTranslation(false); + }, [resource.dataset]); useEffect(() => { if (resource?.uncompressedFileSize) { @@ -215,92 +211,99 @@ export default function DataInformationQuery({ resource }) { const limit1GB = 1 * 1024 * 1024 * 1024; if (resource?.uncompressedFileSize < limit100MB) { - setDownloadPermitted(true) - setDownloadWarning("free") + setDownloadPermitted(true); + setDownloadWarning("free"); } else if (resource?.uncompressedFileSize < limit1GB) { - setDownloadPermitted(isUserPro()) - setDownloadWarning("100mbBetween1gb") + setDownloadPermitted(isUserPro()); + setDownloadWarning("100mbBetween1gb"); } else { - setDownloadWarning("biggest1gb") + setDownloadWarning("biggest1gb"); } } if (resource?.cloudTables?.[0]) { - setGcpProjectID(resource.cloudTables[0]?.gcpProjectId || "") - setGcpDatasetID(resource.cloudTables[0]?.gcpDatasetId || "") - setGcpTableId(resource.cloudTables[0]?.gcpTableId || "") + setGcpProjectID(resource.cloudTables[0]?.gcpProjectId || ""); + setGcpDatasetID(resource.cloudTables[0]?.gcpDatasetId || ""); + setGcpTableId(resource.cloudTables[0]?.gcpTableId || ""); } - }, [resource.uncompressedFileSize, resource.cloudTables]) + }, [resource.uncompressedFileSize, resource.cloudTables]); useEffect(() => { - if(resource._id === undefined) return - setIsLoadingCode(true) - setHasLoadingResponse(false) - setSqlCode("") - setInsufficientChecks(false) - }, [resource._id, checkedColumns, includeTranslation]) + if (resource._id === undefined) return; + setIsLoadingCode(true); + setHasLoadingResponse(false); + setSqlCode(""); + setInsufficientChecks(false); + }, [resource._id, checkedColumns, includeTranslation]); useEffect(() => { - if(hasLoadingResponse === true) { - setIsLoadingSpin(true) - SqlCodeString() + if (hasLoadingResponse === true) { + setIsLoadingSpin(true); + SqlCodeString(); } - }, [hasLoadingResponse]) + }, [hasLoadingResponse]); useEffect(() => { - if(sqlCode !== "") scrollFocus() - }, [sqlCode]) + if (sqlCode !== "") scrollFocus(); + }, [sqlCode]); function scrollFocus() { - let idTab - - if (tabIndex === 0) idTab = "SQL_section" - else if (tabIndex === 1) idTab = "python_section" - else if (tabIndex === 2) idTab = "r_section" - else return - - const targetElement = document.getElementById(idTab) - + let idTab; + + if (tabIndex === 0) idTab = "SQL_section"; + else if (tabIndex === 1) idTab = "python_section"; + else if (tabIndex === 2) idTab = "r_section"; + else return; + + const targetElement = document.getElementById(idTab); + if (targetElement) { - const { top } = targetElement.getBoundingClientRect() - const heightScreen = window.innerHeight - const positionTarget = top + window.pageYOffset - + const { top } = targetElement.getBoundingClientRect(); + const heightScreen = window.innerHeight; + const positionTarget = top + window.pageYOffset; + window.scrollTo({ - top: positionTarget - (heightScreen / 2), + top: positionTarget - heightScreen / 2, behavior: "smooth", - }) + }); } } async function SqlCodeString() { - const result = await getBigTableQuery(resource._id, checkedColumns, includeTranslation) - if(result === null) return - setSqlCode(result.trim()) - setIsLoadingCode(false) - setIsLoadingSpin(false) + const result = await getBigTableQuery( + resource._id, + checkedColumns, + includeTranslation, + ); + if (result === null) return; + setSqlCode(result.trim()); + setIsLoadingCode(false); + setIsLoadingSpin(false); } const handleAccessIndexes = (index) => { - const categoryValues = [t('table.bigQueryAndPackages'), t('table.download')]; - setTabAccessIndex(index) - triggerGAEvent("category_click", categoryValues[index]) - } + const categoryValues = [ + t("table.bigQueryAndPackages"), + t("table.download"), + ]; + setTabAccessIndex(index); + triggerGAEvent("category_click", categoryValues[index]); + }; const handleCategoryIndexes = (index) => { - const categoryValues = ["SQL", "Python", "R"] - setTabIndex(index) - triggerGAEvent("category_click", categoryValues[index]) - } + const categoryValues = ["SQL", "Python", "R"]; + setTabIndex(index); + triggerGAEvent("category_click", categoryValues[index]); + }; const queryLanguage = () => { const language = { - 0 : "SQL", - 1 : "Python", - 2 : "R" - } - return language[tabIndex] ? language[tabIndex] : "" - } + 0: "SQL", + 1: "Python", + 2: "R", + }; + return language[tabIndex] ? language[tabIndex] : ""; + }; return ( - - {t('table.compareThePlans')} + + {t("table.compareThePlans")} - + - {t('table.bigQueryAndPackages')} - {t('table.download')} + {t("table.bigQueryAndPackages")} + {t("table.download")} - - + + - {tabAccessIndex === 0 ? t('table.selectColumns') : t('table.checkColumns')} + {tabAccessIndex === 0 + ? t("table.selectColumns") + : t("table.checkColumns")} @@ -387,7 +379,12 @@ export default function DataInformationQuery({ resource }) { /> - - {t('table.infoTranslationNotAvailable', { returnObjects: true })[0]} - {t('table.infoTranslationNotAvailable', { returnObjects: true })[1]} - {t('table.infoTranslationNotAvailable', { returnObjects: true })[2]} - {t('table.infoTranslationNotAvailable', { returnObjects: true })[3]} - {t('table.infoTranslationNotAvailable', { returnObjects: true })[4]} + + { + t("table.infoTranslationNotAvailable", { + returnObjects: true, + })[0] + } + + { + t("table.infoTranslationNotAvailable", { + returnObjects: true, + })[1] + } + + { + t("table.infoTranslationNotAvailable", { + returnObjects: true, + })[2] + } + + { + t("table.infoTranslationNotAvailable", { + returnObjects: true, + })[3] + } + + { + t("table.infoTranslationNotAvailable", { + returnObjects: true, + })[4] + } @@ -428,16 +457,29 @@ export default function DataInformationQuery({ resource }) { flexDirection="row" alignItems="center" gap="16px" - pointerEvents={resource?.dataset?._id === "e083c9a2-1cee-4342-bedc-535cbad6f3cd" ? "none" : ""} + pointerEvents={ + resource?.dataset?._id === + "e083c9a2-1cee-4342-bedc-535cbad6f3cd" + ? "none" + : "" + } > setIncludeTranslation(!includeTranslation)} - />{t('table.translateInstitutionalCodes')} + /> + + {t("table.translateInstitutionalCodes")} + - {checkedColumns.length > 0 && resource.uncompressedFileSize && resource.uncompressedFileSize/(1024 * 1024 * 1024) > 5 && - - 0 && + resource.uncompressedFileSize && + resource.uncompressedFileSize / (1024 * 1024 * 1024) > 5 && ( + - {t('table.warningLargeTable', { returnObjects: true })[0]} - {formatBytes(resource.uncompressedFileSize)} - {t('table.warningLargeTable', { returnObjects: true })[1]} - {t('table.warningLargeTable', { returnObjects: true })[2]} - {t('table.warningLargeTable', { returnObjects: true })[3]} - - {numberColumns === checkedColumns.length && t('table.warningLargeTableOptimize')} - - - } - - {insufficientChecks && + + {t("table.warningLargeTable", { returnObjects: true })[0]} + + {formatBytes(resource.uncompressedFileSize)} + + {t("table.warningLargeTable", { returnObjects: true })[1]} + + {t("table.warningLargeTable", { returnObjects: true })[2]} + + {t("table.warningLargeTable", { returnObjects: true })[3]} + + {numberColumns === checkedColumns.length && + t("table.warningLargeTableOptimize")} + + + )} + + {insufficientChecks && ( - } + )} @@ -528,7 +588,7 @@ export default function DataInformationQuery({ resource }) { - {isUserPro() === false && downloadWarning === "free" && + {isUserPro() === false && downloadWarning === "free" && ( - {t('table.infoDataAvailability', { returnObjects: true })[0]} + {t("table.infoDataAvailability", { returnObjects: true })[0]} - {t('table.infoDataAvailability', { returnObjects: true })[1]} - . - - } - {isUserPro() === false && downloadWarning === "100mbBetween1gb" && - - {t('table.warningPaidPlanRequired', { returnObjects: true })[0]} - - {t('table.warningPaidPlanRequired', { returnObjects: true })[1]} + { + t("table.infoDataAvailability", { + returnObjects: true, + })[1] + } - {t('table.warningPaidPlanRequired', { returnObjects: true })[2]} + . - } - {downloadWarning === "biggest1gb" && + )} + {isUserPro() === false && + downloadWarning === "100mbBetween1gb" && ( + + { + t("table.warningPaidPlanRequired", { + returnObjects: true, + })[0] + } + + { + t("table.warningPaidPlanRequired", { + returnObjects: true, + })[1] + } + + { + t("table.warningPaidPlanRequired", { + returnObjects: true, + })[2] + } + + )} + {downloadWarning === "biggest1gb" && ( - } + )} R - + - {t('table.bigQueryInstructions')} + {t("table.bigQueryInstructions")} @@ -668,21 +754,23 @@ export default function DataInformationQuery({ resource }) { isLoaded={!isLoadingCode} > - {t('table.firstTimeBigQuery')} + {t("table.firstTimeBigQuery")} - {t('table.followStepByStep')} + {t("table.followStepByStep")} @@ -718,11 +806,11 @@ export default function DataInformationQuery({ resource }) { cursor="pointer" color="#2B8C4D" _hover={{ - color:"#22703E" + color: "#22703E", }} > - {t('table.accessBigQuery')} + {t("table.accessBigQuery")} @@ -737,9 +825,7 @@ export default function DataInformationQuery({ resource }) { width="100%" isLoaded={!isLoadingCode} > - - {sqlCode} - + {sqlCode} @@ -759,7 +845,7 @@ export default function DataInformationQuery({ resource }) { isLoaded={!isLoadingCode} > - {t('table.pythonInstructions')} + {t("table.pythonInstructions")} @@ -771,22 +857,24 @@ export default function DataInformationQuery({ resource }) { width="100%" isLoaded={!isLoadingCode} > - - {t('table.firstTimePython')} + + {t("table.firstTimePython")} - {t('table.followStepByStep')} + {t("table.followStepByStep")} @@ -800,7 +888,8 @@ export default function DataInformationQuery({ resource }) { width="100%" isLoaded={!isLoadingCode} > - {`import basedosdados as bd + + {`import basedosdados as bd billing_id = @@ -829,9 +918,9 @@ bd.read_sql(query = query, billing_project_id = billing_id)`} isLoaded={!isLoadingCode} > - {t('table.rInstructions')} + {t("table.rInstructions")} - + - - {t('table.firstTimeR')} + + {t("table.firstTimeR")} - {t('table.followStepByStep')} + {t("table.followStepByStep")} @@ -870,7 +961,8 @@ bd.read_sql(query = query, billing_project_id = billing_id)`} width="100%" isLoaded={!isLoadingCode} > - {` + + {` # Defina o seu projeto no Google Cloud set_billing_id("") @@ -891,5 +983,5 @@ read_sql(query, billing_project_id = get_billing_id()) - ) + ); } diff --git a/next/components/molecules/DisclaimerBox.js b/next/components/molecules/DisclaimerBox.js index 6532f8d8f..5c815bb32 100644 --- a/next/components/molecules/DisclaimerBox.js +++ b/next/components/molecules/DisclaimerBox.js @@ -1,34 +1,31 @@ -import { - Stack, - Box, -} from "@chakra-ui/react"; +import { Stack, Box } from "@chakra-ui/react"; import BodyText from "../atoms/Text/BodyText"; import InfoIcon from "../../public/img/icons/infoIcon"; import WarningIcon from "../../public/img/icons/warningIcon"; import ExclamationIcon from "../../public/img/icons/exclamationIcon"; import { SolidSuccessIcon } from "../../public/img/icons/successIcon"; -export function AlertDiscalimerBox({ type = "info", text, children, ...props }) { +export function AlertDiscalimerBox({ + type = "info", + text, + children, + ...props +}) { const backgroundColor = { info: "#E4F2FF", warning: "#FFF8DF", error: "#F6E3E3", - success: "#D5E8DB" - } + success: "#D5E8DB", + }; const borderColor = { info: "#0068C5", warning: "#F9C50B", error: "#BF3434", - success: "#2B8C4D" - } + success: "#2B8C4D", + }; return ( - + - {type === "info" && + {type === "info" && ( - } + )} - {type === "warning" && - - } + )} - {type === "error" && + {type === "error" && ( - } + )} - {type === "success" && + {type === "success" && ( - } + )} {text} {children} - ) -} \ No newline at end of file + ); +} diff --git a/next/components/molecules/ExpandableTable.js b/next/components/molecules/ExpandableTable.js index 670c0abcf..4193a269d 100644 --- a/next/components/molecules/ExpandableTable.js +++ b/next/components/molecules/ExpandableTable.js @@ -1,22 +1,18 @@ -import { Button, VStack } from '@chakra-ui/react'; -import { useState } from 'react'; -import { SimpleTable } from '../atoms/SimpleTable'; +import { Button, VStack } from "@chakra-ui/react"; +import { useState } from "react"; +import { SimpleTable } from "../atoms/SimpleTable"; -export function ExpandableTable({ - headers, - values, - containerStyle, -}) { +export function ExpandableTable({ headers, values, containerStyle }) { const [expanded, setExpanded] = useState(false); if (values.length <= 5) - return ( + return ( - ) + ); return ( @@ -34,11 +30,11 @@ export function ExpandableTable({ marginTop="5px !important" minHeight="30px !important" maxHeight="30px !important" - _hover={{backgroundColor:"", opacity:"0.6"}} + _hover={{ backgroundColor: "", opacity: "0.6" }} onClick={() => setExpanded(!expanded)} > {expanded ? "Ver menos" : "Ver mais"} - ) + ); } diff --git a/next/components/molecules/Footer.js b/next/components/molecules/Footer.js index 4296fbc76..51199b614 100644 --- a/next/components/molecules/Footer.js +++ b/next/components/molecules/Footer.js @@ -1,13 +1,8 @@ -import { - HStack, - Stack, - VStack, - Box -} from "@chakra-ui/react"; +import { HStack, Stack, VStack, Box } from "@chakra-ui/react"; import Link from "../atoms/Link"; -import { isMobileMod } from "../../hooks/useCheckMobile.hook" -import { useTranslation } from 'next-i18next'; -import { useRouter } from 'next/router'; +import { isMobileMod } from "../../hooks/useCheckMobile.hook"; +import { useTranslation } from "next-i18next"; +import { useRouter } from "next/router"; import Display from "../atoms/Text/Display"; import LabelText from "../atoms/Text/LabelText"; import BodyText from "../atoms/Text/BodyText"; @@ -28,13 +23,11 @@ function SectionCategories({ title, children, ...props }) { {title} - - {children} - + {children} ); } @@ -42,15 +35,15 @@ function SectionCategories({ title, children, ...props }) { const IconKey = { width: "24px", height: "24px", - fill: "#FFF" -} + fill: "#FFF", +}; function SocialLink({ href, icon }) { return ( {icon} - ) + ); } function FooterLink(props) { @@ -64,96 +57,64 @@ function FooterLink(props) { href={props.href} {...props} /> - ) + ); } -function TextFooterSimple({children, ...props}) { +function TextFooterSimple({ children, ...props }) { return ( - + {children} - ) + ); } export default function Footer({ template, ocult = false }) { - const { t } = useTranslation('common'); + const { t } = useTranslation("common"); const { locale } = useRouter(); - if(template === "simple") return ( - - - - - - {t('footer.copyright', { year: new Date().getFullYear() })} - - - - - - - - - {t('footer.termsOfUse')} - - - - - {t('footer.privacyPolicy')} - - - + if (template === "simple") + return ( + + + + - {t('footer.contact')} + {t("footer.copyright", { year: new Date().getFullYear() })} - - - + + + + + + + {t("footer.termsOfUse")} + + + {t("footer.privacyPolicy")} + + + {t("footer.contact")} + + + + - - ) + ); - if(ocult === true) return null + if (ocult === true) return null; return ( - - + - {t('footer.title')} + {t("footer.title")} - + - {t('footer.products.searchEngine')} + {t("footer.products.searchEngine")} - - {t('footer.products.publicDatalake')} + {t("footer.products.publicDatalake")} - - {t('footer.products.DBPro')} + + {t("footer.products.DBPro")} - {locale === 'pt' && ( + {locale === "pt" && ( - {t('footer.products.DBEdu')} + {t("footer.products.DBEdu")} )} - - {locale === 'pt' && ( - + + {locale === "pt" && ( + - {t('footer.services.dataCapture')} + {t("footer.services.dataCapture")} - {t('footer.services.dataAnalytics')} + {t("footer.services.dataAnalytics")} - {t('footer.services.dataConsulting')} + {t("footer.services.dataConsulting")} - {t('footer.services.caseStudies')} + {t("footer.services.caseStudies")} )} - - + - {t('footer.resources.documentation')} + {t("footer.resources.documentation")} - {t('footer.resources.youtubeVideos')} - - - {t('footer.resources.blog')} - - - {t('footer.resources.faq')} + {t("footer.resources.youtubeVideos")} + {t("footer.resources.blog")} + {t("footer.resources.faq")} - + - {t('footer.institutional.aboutUs')} + {t("footer.institutional.aboutUs")} - {t('footer.institutional.transparency')} + {t("footer.institutional.transparency")} - {locale === 'pt' && ( + {locale === "pt" && ( <> - {t('footer.institutional.newsletter')} + {t("footer.institutional.newsletter")} - {t('footer.institutional.careers')} + {t("footer.institutional.careers")} )} - {t('footer.institutional.termsAndPrivacy')} + {t("footer.institutional.termsAndPrivacy")} - {t('footer.institutional.contact')} + {t("footer.institutional.contact")} - - {t('footer.institutional.supportProject')} + {t("footer.institutional.supportProject")} @@ -290,7 +268,7 @@ export default function Footer({ template, ocult = false }) { @@ -300,7 +278,7 @@ export default function Footer({ template, ocult = false }) { maxWidth="1440px" margin="0 auto" justifyContent="space-between" - flexDirection={{base: "column-reverse", lg: "row"}} + flexDirection={{ base: "column-reverse", lg: "row" }} alignItems="center" spacing={0} > @@ -308,17 +286,13 @@ export default function Footer({ template, ocult = false }) { spacing={0} textAlign="center" maxWidth="1440px" - flexDirection={{base: "column", lg: "row"}} + flexDirection={{ base: "column", lg: "row" }} alignItems="flex-start" - marginTop={{base: "16px", lg: "0"}} + marginTop={{ base: "16px", lg: "0" }} > - - {t('footer.copyright', { year: new Date().getFullYear() })} + + {t("footer.copyright", { year: new Date().getFullYear() })} - {t('footer.termsOfUse')} + {t("footer.termsOfUse")} - {t('footer.privacyPolicy')} + {t("footer.privacyPolicy")} @@ -345,22 +319,58 @@ export default function Footer({ template, ocult = false }) { - }/> - }/> - }/> - }/> - }/> - }/> - }/> - }/> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> diff --git a/next/components/molecules/GeoTree.js b/next/components/molecules/GeoTree.js index f2eae0844..ef3ac5832 100644 --- a/next/components/molecules/GeoTree.js +++ b/next/components/molecules/GeoTree.js @@ -1,66 +1,86 @@ import { useState } from "react"; export function GeoTree(props, schema) { - const n_levels = 5; - let [chosen_levels, set_chosen_levels] = useState(_id_to_levels(props.formData, n_levels)); + const n_levels = 5; + let [chosen_levels, set_chosen_levels] = useState( + _id_to_levels(props.formData, n_levels), + ); - let tree = Object.values(schema); - tree.forEach(x => { x.level = x.id.split('.').length - 1; }); + let tree = Object.values(schema); + tree.forEach((x) => { + x.level = x.id.split(".").length - 1; + }); - let selects = []; + let selects = []; - const update_chosen_levels = (level) => (e) => { - let new_chosen_levels = Array(n_levels).fill('', 0); - for (let i = 0; i < level; i++) - new_chosen_levels[i] = chosen_levels[i]; - new_chosen_levels[level] = e.target.value; - set_chosen_levels(new_chosen_levels); - props.onChange(_build_id(new_chosen_levels)); - }; + const update_chosen_levels = (level) => (e) => { + let new_chosen_levels = Array(n_levels).fill("", 0); + for (let i = 0; i < level; i++) new_chosen_levels[i] = chosen_levels[i]; + new_chosen_levels[level] = e.target.value; + set_chosen_levels(new_chosen_levels); + props.onChange(_build_id(new_chosen_levels)); + }; - for (let i = 0; i < n_levels; i++) { - let options = tree.filter(x => x.level === i && (i === 0 || (chosen_levels[i - 1] !== '' && x.id.startsWith(chosen_levels[i - 1])))); - options = options.map(x => ); - options.unshift(); - selects.push( - - ); - } - - const formid = props.idSchema['$id']; + for (let i = 0; i < n_levels; i++) { + let options = tree.filter( + (x) => + x.level === i && + (i === 0 || + (chosen_levels[i - 1] !== "" && + x.id.startsWith(chosen_levels[i - 1]))), + ); + options = options.map((x) => ( + + )); + options.unshift( + , + ); + selects.push( + , + ); + } + const formid = props.idSchema["$id"]; - return ( -
- - {selects} - - -
- ); + return ( +
+ + {selects} + +
+ ); } function _build_id(levels) { - let lvls = levels.filter(w => w !== ''); - if (lvls.length === 0) - return ''; - return lvls.slice(-1)[0]; + let lvls = levels.filter((w) => w !== ""); + if (lvls.length === 0) return ""; + return lvls.slice(-1)[0]; } function _id_to_levels(id, n_levels) { - if (id === undefined || id === null) - return Array(n_levels).fill(''); - let out = []; - for (let i = 0; i < id.length; i++) - if (id[i] === '.') - out.push(id.slice(0, i)); - out.push(id); - while (out.length < n_levels) - out.push(''); - return out; + if (id === undefined || id === null) return Array(n_levels).fill(""); + let out = []; + for (let i = 0; i < id.length; i++) + if (id[i] === ".") out.push(id.slice(0, i)); + out.push(id); + while (out.length < n_levels) out.push(""); + return out; } diff --git a/next/components/molecules/ImgCrop.js b/next/components/molecules/ImgCrop.js index 5a7b7cb8b..271df24a8 100644 --- a/next/components/molecules/ImgCrop.js +++ b/next/components/molecules/ImgCrop.js @@ -8,63 +8,54 @@ import { ModalFooter, ModalCloseButton, Text, - Box -} from '@chakra-ui/react'; -import { useState, useEffect, useRef } from 'react'; -import ReactCrop, { - centerCrop, - makeAspectCrop -} from 'react-image-crop'; -import cookies from 'js-cookie'; + Box, +} from "@chakra-ui/react"; +import { useState, useEffect, useRef } from "react"; +import ReactCrop, { centerCrop, makeAspectCrop } from "react-image-crop"; +import cookies from "js-cookie"; import { useTranslation } from "react-i18next"; -import { Button } from './uiUserPage'; +import { Button } from "./uiUserPage"; -import updatePictureProfile from '../../pages/api/user/updatePictureProfile' -import 'react-image-crop/dist/ReactCrop.css'; +import updatePictureProfile from "../../pages/api/user/updatePictureProfile"; +import "react-image-crop/dist/ReactCrop.css"; import styles from "../../styles/imgCrop.module.css"; -export default function CropImage ({ - isOpen, - onClose, - src, - id, - username, -}) { - const { t } = useTranslation('user'); - const imgRef = useRef(null) - const [completedCrop, setCompletedCrop] = useState() - const [crop, setCrop] = useState() - const [isLoading, setIsLoading] = useState(false) +export default function CropImage({ isOpen, onClose, src, id, username }) { + const { t } = useTranslation("user"); + const imgRef = useRef(null); + const [completedCrop, setCompletedCrop] = useState(); + const [crop, setCrop] = useState(); + const [isLoading, setIsLoading] = useState(false); function onImageLoad(e) { - const { naturalWidth: width, naturalHeight: height } = e.currentTarget - + const { naturalWidth: width, naturalHeight: height } = e.currentTarget; + const nCrop = centerCrop( makeAspectCrop( { - unit: '%', + unit: "%", width: 90, }, 1 / 1, width, - height + height, ), width, - height - ) - - setCrop(nCrop) + height, + ); + + setCrop(nCrop); } useEffect(() => { - setCompletedCrop() - }, [!!isOpen]) + setCompletedCrop(); + }, [!!isOpen]); async function handlerUpdatePicture() { - setIsLoading(true) - const image = imgRef.current + setIsLoading(true); + const image = imgRef.current; - if (!image || !completedCrop) return null + if (!image || !completedCrop) return null; const scaleX = image.naturalWidth / image.width; const scaleY = image.naturalHeight / image.height; @@ -72,12 +63,12 @@ export default function CropImage ({ const offscreen = new OffscreenCanvas( completedCrop.width * scaleX, completedCrop.height * scaleY, - ) + ); - const ctx = offscreen.getContext("2d") + const ctx = offscreen.getContext("2d"); if (!ctx) { - throw new Error("No 2d context") + throw new Error("No 2d context"); } ctx.drawImage( @@ -90,49 +81,54 @@ export default function CropImage ({ 0, offscreen.width, offscreen.height, - ) + ); - const maxSizeKB = 1000 - let quality = 1.0 - const maxIterations = 10 + const maxSizeKB = 1000; + let quality = 1.0; + const maxIterations = 10; for (let i = 0; i < maxIterations; i++) { - const tempCanvas = document.createElement('canvas') - tempCanvas.width = offscreen.width - tempCanvas.height = offscreen.height - const tempCtx = tempCanvas.getContext('2d') - tempCtx.drawImage(offscreen, 0, 0) + const tempCanvas = document.createElement("canvas"); + tempCanvas.width = offscreen.width; + tempCanvas.height = offscreen.height; + const tempCtx = tempCanvas.getContext("2d"); + tempCtx.drawImage(offscreen, 0, 0); - const compressedDataUrl = tempCanvas.toDataURL("image/jpeg", quality) - const sizeKB = compressedDataUrl.length / 1024 + const compressedDataUrl = tempCanvas.toDataURL("image/jpeg", quality); + const sizeKB = compressedDataUrl.length / 1024; if (sizeKB <= maxSizeKB) { break; } - quality -= 0.1 + quality -= 0.1; } const picture = await new Promise((resolve) => { - offscreen.convertToBlob({ - type: "image/jpeg", - quality - }).then((pic) => { - resolve(pic) - }) - }) - - const filePic = new File([picture], `${username}.jpeg`, {type: "image/jpeg"}) - - const reg = new RegExp("(?<=:).*") - const [ uid ] = reg.exec(id) - - const res = await updatePictureProfile(uid, filePic) - if(res?.status === 200) { - const userData = await fetch(`/api/user/getUser?p=${btoa(uid)}`, { method: "GET" }) - .then(res => res.json()) - cookies.set('userBD', JSON.stringify(userData)) - window.location.reload() + offscreen + .convertToBlob({ + type: "image/jpeg", + quality, + }) + .then((pic) => { + resolve(pic); + }); + }); + + const filePic = new File([picture], `${username}.jpeg`, { + type: "image/jpeg", + }); + + const reg = new RegExp("(?<=:).*"); + const [uid] = reg.exec(id); + + const res = await updatePictureProfile(uid, filePic); + if (res?.status === 200) { + const userData = await fetch(`/api/user/getUser?p=${btoa(uid)}`, { + method: "GET", + }).then((res) => res.json()); + cookies.set("userBD", JSON.stringify(userData)); + window.location.reload(); } } @@ -143,11 +139,19 @@ export default function CropImage ({ isCentered margin="24px !important" > - - + + {t('username.imgCropTitle')} + > + {t("username.imgCropTitle")} + @@ -175,7 +181,7 @@ export default function CropImage ({ margin="24px 0" overflow="hidden" > - {!!src && + {!!src && ( setCrop(c)} @@ -184,44 +190,44 @@ export default function CropImage ({ keepSelection={true} circularCrop > - + - } + )} - + - ) + ); } diff --git a/next/components/molecules/Menu.js b/next/components/molecules/Menu.js index 08d125b88..842fbac5e 100644 --- a/next/components/molecules/Menu.js +++ b/next/components/molecules/Menu.js @@ -19,14 +19,14 @@ import { Menu, MenuButton, MenuList, - MenuItem + MenuItem, } from "@chakra-ui/react"; import { useEffect, useRef, useState } from "react"; -import { useRouter } from "next/router" -import { useTranslation } from 'next-i18next'; +import { useRouter } from "next/router"; +import { useTranslation } from "next-i18next"; import cookies from "js-cookie"; import MenuDropdown from "./MenuDropdown"; -import { useCheckMobile } from "../../hooks/useCheckMobile.hook" +import { useCheckMobile } from "../../hooks/useCheckMobile.hook"; import { ControlledInputSimple } from "../atoms/ControlledInput"; import Link from "../atoms/Link"; import Button from "../atoms/Button"; @@ -54,33 +54,33 @@ function useIsMobileMod() { } function MenuDrawer({ userData, isOpen, onClose, links }) { - const { t } = useTranslation('menu'); + const { t } = useTranslation("menu"); const { locale } = useRouter(); const router = useRouter(); return ( - + - {locale === 'en' ? ( + {locale === "en" ? ( router.push('/search')} + onClick={() => router.push("/search")} /> ) : ( router.push('/search')} + onClick={() => router.push("/search")} /> )} {Object.entries(links).map(([key, elm]) => { - if(key === "Button") { - return elm.map(b => + if (key === "Button") { + return elm.map((b) => ( - ) + )); } if (typeof elm === "object") { return ( @@ -100,7 +100,7 @@ function MenuDrawer({ userData, isOpen, onClose, links }) { - - {elm.map((c) => { - if(c.name === undefined) return null + + {elm.map((c) => { + if (c.name === undefined) return null; - return ( - {c.icon && c.icon} {c.name} - ) - })} - + return ( + + {c.icon && c.icon} {c.name} + + ); + })} +
- ) + ); } else { return ( {key} + > + {key} - ) + ); } })} @@ -159,7 +162,11 @@ function MenuDrawer({ userData, isOpen, onClose, links }) { {userData ? ( <> ) : ( - + - {t('enter', { ns: 'menu' })} + {t("enter", { ns: "menu" })} - + - {t('register', { ns: 'menu' })} + {t("register", { ns: "menu" })} )} @@ -203,41 +210,53 @@ function MenuDrawer({ userData, isOpen, onClose, links }) { ); } -function MenuDrawerUser({ userData, isOpen, onClose, isUserPro, haveInterprisePlan }) { +function MenuDrawerUser({ + userData, + isOpen, + onClose, + isUserPro, + haveInterprisePlan, +}) { const router = useRouter(); - const { t } = useTranslation('menu'); + const { t } = useTranslation("menu"); const { locale } = useRouter(); const links = [ - {name: t('public_profile'), value: "profile"}, - {name: t('account'), value: "account"}, - {name: t('password'), value: "new_password"}, - {name: t('plans_and_payment'), value: "plans_and_payment"}, - isUserPro && {name: t('bigquery'), value: "big_query"}, - haveInterprisePlan && {name: t('access'), value: "accesses"}, - ] + { name: t("public_profile"), value: "profile" }, + { name: t("account"), value: "account" }, + { name: t("password"), value: "new_password" }, + { name: t("plans_and_payment"), value: "plans_and_payment" }, + isUserPro && { name: t("bigquery"), value: "big_query" }, + haveInterprisePlan && { name: t("access"), value: "accesses" }, + ]; return ( - + - {locale === 'en' ? ( + {locale === "en" ? ( router.push('/search')} + onClick={() => router.push("/search")} /> ) : ( router.push('/search')} + onClick={() => router.push("/search")} /> )} - + {userData?.username || ""} - {userData?.email || ""} + + {userData?.email || ""} + {isUserPro - ? (userData?.plan === "bd_pro_empresas" - ? t('DBEnterprise') + ? userData?.plan === "bd_pro_empresas" + ? t("DBEnterprise") : userData?.plan === "bd_pro" - ? t('DBPro') - : null) - : t('DBFree') - } + ? t("DBPro") + : null + : t("DBFree")} @@ -284,14 +305,17 @@ function MenuDrawerUser({ userData, isOpen, onClose, isUserPro, haveInterprisePl - - - - {t('settings')} - + + + {t("settings")} @@ -309,17 +333,22 @@ function MenuDrawerUser({ userData, isOpen, onClose, isUserPro, haveInterprisePl color="#71757A" fontWeight="400" onClick={() => { - onClose() - router.push({pathname: `/user/${userData.username}`, query: elm.value})} - } - >{elm.name} - ) + onClose(); + router.push({ + pathname: `/user/${userData.username}`, + query: elm.value, + }); + }} + > + {elm.name} + + ); })} - + { - cookies.remove('userBD', { path: '/' }) - cookies.remove('token', { path: '/' }) - router.push('/') + cookies.remove("userBD", { path: "/" }); + cookies.remove("token", { path: "/" }); + router.push("/"); }} > - - - {t('exit')} + + + {t("exit")} - ) + ); } -function MenuUser ({ userData, onOpen, onClose, isUserPro }) { - const timerRef = useRef() - const [isOpenMenu, setIsOpenMenu] = useState(false) - const { t } = useTranslation('menu'); +function MenuUser({ userData, onOpen, onClose, isUserPro }) { + const timerRef = useRef(); + const [isOpenMenu, setIsOpenMenu] = useState(false); + const { t } = useTranslation("menu"); const isMobile = useIsMobileMod(); const router = useRouter(); const btnMouseEnterEvent = () => { - setIsOpenMenu(true) - } + setIsOpenMenu(true); + }; const btnMouseLeaveEvent = () => { timerRef.current = setTimeout(() => { - setIsOpenMenu(false) - }, 100) - } + setIsOpenMenu(false); + }, 100); + }; const menuListMouseEnterEvent = () => { - clearTimeout(timerRef.current) - timerRef.current = undefined - setIsOpenMenu(true) - } + clearTimeout(timerRef.current); + timerRef.current = undefined; + setIsOpenMenu(true); + }; const menuListMouseLeaveEvent = () => { - setIsOpenMenu(false) - } + setIsOpenMenu(false); + }; - if(isMobile) { + if (isMobile) { return ( - ) + ); } else { return ( - + - + @@ -437,7 +462,7 @@ function MenuUser ({ userData, onOpen, onClose, isUserPro }) { textAlign="center" alignItems="center" padding="16px" - _hover={{ backgroundColor: "transparent"}} + _hover={{ backgroundColor: "transparent" }} > {userData?.username ? userData?.username : ""} - + {userData?.email ? userData?.email : ""} @@ -475,13 +501,12 @@ function MenuUser ({ userData, onOpen, onClose, isUserPro }) { marginTop="10px" > {isUserPro - ? (userData?.plan === "bd_pro_empresas" - ? t('DBEnterprise') + ? userData?.plan === "bd_pro_empresas" + ? t("DBEnterprise") : userData?.plan === "bd_pro" - ? t('DBPro') - : null) - : t('DBFree') - } + ? t("DBPro") + : null + : t("DBFree")} @@ -494,12 +519,10 @@ function MenuUser ({ userData, onOpen, onClose, isUserPro }) { _hover={{ backgroundColor: "transparent", opacity: "0.7" }} onClick={() => router.push(`/user/${userData.username}`)} > - - - {t('settings')} - + + {t("settings")} - + { - cookies.remove('userBD', { path: '/' }) - cookies.remove('token', { path: '/' }) - router.push('/') + cookies.remove("userBD", { path: "/" }); + cookies.remove("token", { path: "/" }); + router.push("/"); }} > - - - {t('exit')} - + + {t("exit")} - ) + ); } } -function SearchInputUser ({ user }) { - const { t } = useTranslation('menu'); - const inputMobileRef = useRef(null) - const [search, setSearch] = useState("") - const [showInput, setShowInput] = useState(false) - const [inputFocus, setInputFocus] = useState(false) +function SearchInputUser({ user }) { + const { t } = useTranslation("menu"); + const inputMobileRef = useRef(null); + const [search, setSearch] = useState(""); + const [showInput, setShowInput] = useState(false); + const [inputFocus, setInputFocus] = useState(false); const isMobile = useIsMobileMod(); const router = useRouter(); function openSearchLink() { - if(search.trim() === "") return - triggerGAEvent("search", search.trim()) - triggerGAEvent("search_menu", search.trim()) + if (search.trim() === "") return; + triggerGAEvent("search", search.trim()); + triggerGAEvent("search_menu", search.trim()); router.push(`/search?q=${search.trim()}`); } const handleClickOutside = (event) => { - if (inputMobileRef.current && !inputMobileRef.current.contains(event.target)) { + if ( + inputMobileRef.current && + !inputMobileRef.current.contains(event.target) + ) { setShowInput(false); } - } + }; useEffect(() => { if (showInput) { - document.addEventListener('click', handleClickOutside) + document.addEventListener("click", handleClickOutside); } else { - document.removeEventListener('click', handleClickOutside) + document.removeEventListener("click", handleClickOutside); } - + return () => { - document.removeEventListener('click', handleClickOutside) - } - }, [showInput]) + document.removeEventListener("click", handleClickOutside); + }; + }, [showInput]); - if (isMobile) return ( - + if (isMobile) + return ( - + { + e.preventDefault(); + openSearchLink(); + }} + > + + + } + /> + + + { - e.preventDefault(); - openSearchLink(); - }} - > - - - } + width="18px" + height="18px" + marginLeft="auto !important" + cursor="pointer" + onClick={() => { + setShowInput(true); + setTimeout(() => { + inputMobileRef.current.focus(); + }, 0); + }} /> - - { - setShowInput(true) - setTimeout(() => { - inputMobileRef.current.focus() - }, 0) - }} - /> - - ) + ); return ( @@ -626,7 +655,7 @@ function SearchInputUser ({ user }) { onEnterPress={openSearchLink} inputFocus={inputFocus} changeInputFocus={setInputFocus} - placeholder={t('search_data')} + placeholder={t("search_data")} fill="#464A51" icon={ - ) + ); } function DesktopLinks({ @@ -655,22 +684,25 @@ function DesktopLinks({ position = false, path, userTemplate = false, - isUserPro + isUserPro, }) { const isMobile = useIsMobileMod(); - const { t } = useTranslation('common', 'menu'); + const { t } = useTranslation("common", "menu"); const { locale } = useRouter(); - function LinkMenuDropDown ({ url, text, icon }) { - const [flag, setFlag] = useBoolean() + function LinkMenuDropDown({ url, text, icon }) { + const [flag, setFlag] = useBoolean(); - if(url === undefined && text === undefined) return + if (url === undefined && text === undefined) + return ( + + ); return ( + > {icon && icon} {text} - + - ) + ); } return ( @@ -695,12 +732,19 @@ function DesktopLinks({ gap="24px" transition="1s" marginLeft={ - path === "/" ? - !position ? "0 !important" : "28px !important" - : "28px !important" + path === "/" + ? !position + ? "0 !important" + : "28px !important" + : "28px !important" } > - + {Object.entries(links).map(([k, v], i) => { if (k === "Button") { return v.map((b, j) => ( @@ -715,7 +759,7 @@ function DesktopLinks({ {b.name} - )) + )); } if (typeof v === "object") { @@ -734,9 +778,9 @@ function DesktopLinks({ lineHeight="20px" borderRadius="10px" padding="32px" - _first={{ paddingTop: "10px"}} - _last={{ paddingBottom: "10px"}} - boxShadow= "0 1px 8px 1px rgba(64, 60, 67, 0.16)" + _first={{ paddingTop: "10px" }} + _last={{ paddingBottom: "10px" }} + boxShadow="0 1px 8px 1px rgba(64, 60, 67, 0.16)" > {v.map((elm, j) => ( ))} - ) + ); } return ( @@ -760,45 +804,79 @@ function DesktopLinks({ > {k} - ) + ); })} - {userTemplate && !isMobile && - - } + {userTemplate && !isMobile && ( + + )} - {(path === "/search" || path === "/dataset/[dataset]" || path === "/user/[username]") && + {(path === "/search" || + path === "/dataset/[dataset]" || + path === "/user/[username]") && ( {t('tooltip.faq')}}, - {name: t('tooltip.documentation'), url: - locale === "en" ? "https://basedosdados.github.io/sdk/en" : - locale === "es" ? "https://basedosdados.github.io/sdk/es" : - "https://basedosdados.github.io/sdk" + { + name: t("tooltip.faq"), + component: {t("tooltip.faq")}, }, - {name: t('tooltip.youtubeVideos'), url: "https://www.youtube.com/c/BasedosDados/featured"}, - {name: t('tooltip.installPackages'), url: - locale === "en" ? "https://basedosdados.github.io/sdk/en/access_data_packages/" : - locale === "es" ? "https://basedosdados.github.io/sdk/es/access_data_packages/" : - "https://basedosdados.github.io/sdk/access_data_packages/" + { + name: t("tooltip.documentation"), + url: + locale === "en" + ? "https://basedosdados.github.io/sdk/en" + : locale === "es" + ? "https://basedosdados.github.io/sdk/es" + : "https://basedosdados.github.io/sdk", + }, + { + name: t("tooltip.youtubeVideos"), + url: "https://www.youtube.com/c/BasedosDados/featured", + }, + { + name: t("tooltip.installPackages"), + url: + locale === "en" + ? "https://basedosdados.github.io/sdk/en/access_data_packages/" + : locale === "es" + ? "https://basedosdados.github.io/sdk/es/access_data_packages/" + : "https://basedosdados.github.io/sdk/access_data_packages/", + }, + { + name: t("tooltip.howToCite"), + component: ( + {t("tooltip.howToCite")} + ), + }, + { + name: t("tooltip.whatAreDirectories"), + component: ( + + {t("tooltip.whatAreDirectories")} + + ), }, - {name: t('tooltip.howToCite'), component: {t('tooltip.howToCite')}}, - {name: t('tooltip.whatAreDirectories'), component: {t('tooltip.whatAreDirectories')}}, {}, - {name: t('tooltip.discordCommunity'), url: "https://discord.gg/huKWpsVYx4"}, - {name: t('tooltip.contactUs'), component: {t('tooltip.contactUs')}}, + { + name: t("tooltip.discordCommunity"), + url: "https://discord.gg/huKWpsVYx4", + }, + { + name: t("tooltip.contactUs"), + component: ( + {t("tooltip.contactUs")} + ), + }, ]} /> - } + )} {userData ? ( - + ) : ( <> @@ -812,12 +890,12 @@ function DesktopLinks({ fontWeight="400" gap="8px" _hover={{ - opacity: 0.7 + opacity: 0.7, }} > - {t('enter', { ns: 'menu' })} + {t("enter", { ns: "menu" })} - + - {t('register', { ns: 'menu' })} + {t("register", { ns: "menu" })} )} - ) + ); } -export default function MenuNav({ simpleTemplate = false, userTemplate = false }) { - const { t } = useTranslation('menu'); - const router = useRouter() - const { locale } = router - const [userBD, setUserBD] = useState(null) - const [isLoading, setIsLoading] = useState(true) +export default function MenuNav({ + simpleTemplate = false, + userTemplate = false, +}) { + const { t } = useTranslation("menu"); + const router = useRouter(); + const { locale } = router; + const [userBD, setUserBD] = useState(null); + const [isLoading, setIsLoading] = useState(true); const isMobile = useIsMobileMod(); - const menuDisclosure = useDisclosure() - const menuUserMobile = useDisclosure() - const divRef = useRef() - const [isScrollDown, setIsScrollDown] = useState(false) - const [userData, setUserData] = useState(null) + const menuDisclosure = useDisclosure(); + const menuUserMobile = useDisclosure(); + const divRef = useRef(); + const [isScrollDown, setIsScrollDown] = useState(false); + const [userData, setUserData] = useState(null); - const [lastScrollY, setLastScrollY] = useState(0) - const [menuVisible, setMenuVisible] = useState(true) + const [lastScrollY, setLastScrollY] = useState(0); + const [menuVisible, setMenuVisible] = useState(true); const isUserPro = () => { - let user - if(cookies.get("userBD")) user = JSON.parse(cookies.get("userBD")) + let user; + if (cookies.get("userBD")) user = JSON.parse(cookies.get("userBD")); - if(user?.isSubscriber) return user?.isSubscriber - return false - } + if (user?.isSubscriber) return user?.isSubscriber; + return false; + }; const haveInterprisePlan = () => { - let user - if(cookies.get("userBD")) user = JSON.parse(cookies.get("userBD")) - return user?.proSubscription === "bd_pro_empresas" - } + let user; + if (cookies.get("userBD")) user = JSON.parse(cookies.get("userBD")); + return user?.proSubscription === "bd_pro_empresas"; + }; useEffect(() => { - const cookieUserBD = cookies.get("userBD") - setUserBD(cookieUserBD || null) - setIsLoading(false) - }, []) + const cookieUserBD = cookies.get("userBD"); + setUserBD(cookieUserBD || null); + setIsLoading(false); + }, []); const handleScroll = () => { - const currentScrollY = window.scrollY + const currentScrollY = window.scrollY; if (currentScrollY > lastScrollY) { - setMenuVisible(false) + setMenuVisible(false); } else { - setMenuVisible(true) + setMenuVisible(true); } - setLastScrollY(currentScrollY) - } + setLastScrollY(currentScrollY); + }; useEffect(() => { - if(router.pathname !== "/dataset/[dataset]") return - window.addEventListener('scroll', handleScroll) + if (router.pathname !== "/dataset/[dataset]") return; + window.addEventListener("scroll", handleScroll); return () => { - window.removeEventListener('scroll', handleScroll) - } - }, [lastScrollY, router.pathname]) + window.removeEventListener("scroll", handleScroll); + }; + }, [lastScrollY, router.pathname]); useEffect(() => { - if(isLoading) return - if(userBD !== null && userBD !== "undefined") { + if (isLoading) return; + if (userBD !== null && userBD !== "undefined") { try { - const res = JSON.parse(userBD) + const res = JSON.parse(userBD); setUserData({ email: res.email, username: res.username, picture: res.picture || "", - plan: res?.proSubscription - }) + plan: res?.proSubscription, + }); } catch (error) { - console.error("Error parsing user data:", error) - setUserData(null) + console.error("Error parsing user data:", error); + setUserData(null); } } else { - setUserData(null) + setUserData(null); } - }, [userBD, isLoading]) + }, [userBD, isLoading]); let links; if (locale === "pt") { links = { - [t('data')]: `/search`, - [t('solutions')]: [ + [t("data")]: `/search`, + [t("solutions")]: [ { - icon: , - name: [t('exclusive_data')], - href: "https://info.basedosdados.org/bd-pro" + icon: , + name: [t("exclusive_data")], + href: "https://info.basedosdados.org/bd-pro", }, { - icon: , - name: [t('data_courses')], - href: "https://info.basedosdados.org/bd-edu-cursos" + icon: , + name: [t("data_courses")], + href: "https://info.basedosdados.org/bd-edu-cursos", }, { - icon: , - name: [t('services')], - href: "/services" + icon: , + name: [t("services")], + href: "/services", }, ], - [t('prices')]: "/prices", - [t('resources')]: [ - {name: [t('documentation')], href: "https://basedosdados.github.io/sdk"}, - {name: [t('youtube_videos')], href: "https://www.youtube.com/c/BasedosDados/featured"}, - {name: "Blog", href: "/blog"}, - {name: [t('faq')], href: "/faq"} + [t("prices")]: "/prices", + [t("resources")]: [ + { + name: [t("documentation")], + href: "https://basedosdados.github.io/sdk", + }, + { + name: [t("youtube_videos")], + href: "https://www.youtube.com/c/BasedosDados/featured", + }, + { name: "Blog", href: "/blog" }, + { name: [t("faq")], href: "/faq" }, ], - [t('institutional')]: [ - {name: [t('about_us')], href: "/about-us"}, - {name: [t('transparency')], href: "/transparency"}, - {name: [t('newsletter')], href: "https://info.basedosdados.org/newsletter"}, - {name: [t('jobs')], href: "https://info.basedosdados.org/carreiras"}, + [t("institutional")]: [ + { name: [t("about_us")], href: "/about-us" }, + { name: [t("transparency")], href: "/transparency" }, + { + name: [t("newsletter")], + href: "https://info.basedosdados.org/newsletter", + }, + { name: [t("jobs")], href: "https://info.basedosdados.org/carreiras" }, ], - [t('contact')]: "/contact", - Button: [] - } + [t("contact")]: "/contact", + Button: [], + }; } else if (locale === "en") { links = { - [t('data')]: `/search`, - [t('solutions')]: [ + [t("data")]: `/search`, + [t("solutions")]: [ { - icon: , - name: [t('exclusive_data')], - href: "https://info.basedosdados.org/en/bd-pro" - } + icon: , + name: [t("exclusive_data")], + href: "https://info.basedosdados.org/en/bd-pro", + }, ], - [t('prices')]: "/prices", - [t('resources')]: [ - {name: [t('documentation')], href: "https://basedosdados.github.io/sdk/en"}, - {name: [t('youtube_videos')], href: "https://www.youtube.com/c/BasedosDados/featured"}, - {name: "Blog", href: "/blog"}, - {name: [t('faq')], href: "/faq"} + [t("prices")]: "/prices", + [t("resources")]: [ + { + name: [t("documentation")], + href: "https://basedosdados.github.io/sdk/en", + }, + { + name: [t("youtube_videos")], + href: "https://www.youtube.com/c/BasedosDados/featured", + }, + { name: "Blog", href: "/blog" }, + { name: [t("faq")], href: "/faq" }, ], - [t('institutional')]: [ - {name: [t('about_us')], href: "/about-us"}, - {name: [t('transparency')], href: "/transparency"}, + [t("institutional")]: [ + { name: [t("about_us")], href: "/about-us" }, + { name: [t("transparency")], href: "/transparency" }, ], - [t('contact')]: "/contact", - Button: [] - } + [t("contact")]: "/contact", + Button: [], + }; } else if (locale === "es") { links = { - [t('data')]: `/search`, - [t('solutions')]: [ + [t("data")]: `/search`, + [t("solutions")]: [ { - icon: , - name: [t('exclusive_data')], - href: "https://info.basedosdados.org/es/bd-pro" - } + icon: , + name: [t("exclusive_data")], + href: "https://info.basedosdados.org/es/bd-pro", + }, ], - [t('prices')]: "/prices", - [t('resources')]: [ - {name: [t('documentation')], href: "https://basedosdados.github.io/sdk/es"}, - {name: [t('youtube_videos')], href: "https://www.youtube.com/c/BasedosDados/featured"}, - {name: "Blog", href: "/blog"}, - {name: [t('faq')], href: "/faq"} + [t("prices")]: "/prices", + [t("resources")]: [ + { + name: [t("documentation")], + href: "https://basedosdados.github.io/sdk/es", + }, + { + name: [t("youtube_videos")], + href: "https://www.youtube.com/c/BasedosDados/featured", + }, + { name: "Blog", href: "/blog" }, + { name: [t("faq")], href: "/faq" }, ], - [t('institutional')]: [ - {name: [t('about_us')], href: "/about-us"}, - {name: [t('transparency')], href: "/transparency"}, + [t("institutional")]: [ + { name: [t("about_us")], href: "/about-us" }, + { name: [t("transparency")], href: "/transparency" }, ], - [t('contact')]: "/contact", - Button: [] - } + [t("contact")]: "/contact", + Button: [], + }; } useEffect(() => { const handleScroll = () => { - if (window.scrollY >= 225) setIsScrollDown(true) - if (window.scrollY <= 225) setIsScrollDown(false) + if (window.scrollY >= 225) setIsScrollDown(true); + if (window.scrollY <= 225) setIsScrollDown(false); if (!divRef.current || !divRef.current.style) return; if (window.scrollY <= 30) divRef.current.style.boxShadow = "none"; @@ -1021,7 +1123,7 @@ export default function MenuNav({ simpleTemplate = false, userTemplate = false } return () => { document.removeEventListener("scroll", handleScroll); }; - }, []) + }, []); if (isLoading) { return null; @@ -1029,11 +1131,7 @@ export default function MenuNav({ simpleTemplate = false, userTemplate = false } return ( <> - + - + - {locale === 'en' ? ( - + {locale === "en" ? ( + ) : ( - + )} - {simpleTemplate ? - <> - : + {simpleTemplate ? ( + <> + ) : ( - } + )} - {userTemplate && isMobile && - - } + {userTemplate && isMobile && ( + + )} - {isMobile && userData && + {isMobile && userData && ( - } - - ) + ); } diff --git a/next/components/molecules/MenuDropdown.js b/next/components/molecules/MenuDropdown.js index ed1b3087f..c7b3ae612 100644 --- a/next/components/molecules/MenuDropdown.js +++ b/next/components/molecules/MenuDropdown.js @@ -1,33 +1,27 @@ import React, { useRef, useState } from "react"; -import { - Box, - Menu, - MenuButton, - MenuList, - Button -} from "@chakra-ui/react" -import ChevronIcon from "../../public/img/icons/chevronIcon" +import { Box, Menu, MenuButton, MenuList, Button } from "@chakra-ui/react"; +import ChevronIcon from "../../public/img/icons/chevronIcon"; export default function MenuDropdown({ title, children, ...style }) { const timerRef = useRef(); const [isOpenMenu, setIsOpenMenu] = useState(false); const btnMouseEnterEvent = () => { - setIsOpenMenu(true) - } + setIsOpenMenu(true); + }; const btnMouseLeaveEvent = () => { timerRef.current = setTimeout(() => { - setIsOpenMenu(false) - }, 100) - } + setIsOpenMenu(false); + }, 100); + }; const menuListMouseEnterEvent = () => { - clearTimeout(timerRef.current) - timerRef.current = undefined - setIsOpenMenu(true) - } + clearTimeout(timerRef.current); + timerRef.current = undefined; + setIsOpenMenu(true); + }; const menuListMouseLeaveEvent = () => { - setIsOpenMenu(false) - } + setIsOpenMenu(false); + }; return ( @@ -52,7 +46,7 @@ export default function MenuDropdown({ title, children, ...style }) { marginLeft="6px" transform={"rotate(90deg)"} /> - + - ) -} \ No newline at end of file + ); +} diff --git a/next/components/molecules/SchemaForm.js b/next/components/molecules/SchemaForm.js index 03eacc62b..9a205b5fa 100644 --- a/next/components/molecules/SchemaForm.js +++ b/next/components/molecules/SchemaForm.js @@ -1,11 +1,7 @@ import { useEffect, useState } from "react"; import { useMutation, useQuery } from "react-query"; // import Form from "@rjsf/core"; -import { - CircularProgress, - Center, - VStack, -} from "@chakra-ui/react"; +import { CircularProgress, Center, VStack } from "@chakra-ui/react"; import { useToast } from "@chakra-ui/toast"; import Head from "next/head"; import { GeoTree } from "./GeoTree"; @@ -21,18 +17,14 @@ export function SchemaForm({ return data; }, }) { - const [spatialCoverageTree, setSpatialCoverageTree] = useState({}) + const [spatialCoverageTree, setSpatialCoverageTree] = useState({}); useEffect(() => { - getSpatialCovarageTree() - .then(res => setSpatialCoverageTree(res)) - },[]) + getSpatialCovarageTree().then((res) => setSpatialCoverageTree(res)); + }, []); const toast = useToast(); - let { data: schema = {}, isLoading } = useQuery( - "schema", - loadSchemaFunction - ); + let { data: schema = {}, isLoading } = useQuery("schema", loadSchemaFunction); const updateMutation = useMutation(updateFunction, { onSuccess({ data }) { toast({ @@ -73,18 +65,18 @@ export function SchemaForm({ //// Geo stuff const uiSchema = { - spatial_coverage:{ + spatial_coverage: { items: { - 'ui:field' : 'GeoTree' - } + "ui:field": "GeoTree", + }, }, - number_rows: {"ui:widget": "hidden"} - } - const fields = {GeoTree: (props) => GeoTree(props, spatialCoverageTree)} + number_rows: { "ui:widget": "hidden" }, + }; + const fields = { GeoTree: (props) => GeoTree(props, spatialCoverageTree) }; ///// - if (schema.schema === undefined) schema = {schema: schema} // TODO: remove this after changing all endpoints + if (schema.schema === undefined) schema = { schema: schema }; // TODO: remove this after changing all endpoints return ( <> @@ -113,7 +105,7 @@ export function SchemaForm({ updateMutation.mutate( prepareData({ ..._data, - }) + }), ); toast({ title: "Salvando...", diff --git a/next/components/molecules/TableColumns.js b/next/components/molecules/TableColumns.js index 05d34658e..02647f457 100644 --- a/next/components/molecules/TableColumns.js +++ b/next/components/molecules/TableColumns.js @@ -11,58 +11,62 @@ import { Box, Text, Skeleton, -} from '@chakra-ui/react'; -import { useState, useEffect } from 'react'; -import { useRouter } from 'next/router'; -import FuzzySearch from 'fuzzy-search'; -import Latex from 'react-latex-next'; -import cookies from 'js-cookie'; -import { ControlledInputSimple } from '../atoms/ControlledInput'; -import Checkbox from '../atoms/Checkbox'; -import { triggerGAEvent, formatBytes } from '../../utils'; -import { useTranslation } from 'next-i18next'; -import { capitalize } from 'lodash'; - -import InternalError from '../../public/img/internalError' -import InfoIcon from '../../public/img/icons/infoIcon'; -import DownloadIcon from '../../public/img/icons/downloadIcon'; -import SearchIcon from '../../public/img/icons/searchIcon'; -import RedirectIcon from '../../public/img/icons/redirectIcon'; -import 'katex/dist/katex.min.css'; +} from "@chakra-ui/react"; +import { useState, useEffect } from "react"; +import { useRouter } from "next/router"; +import FuzzySearch from "fuzzy-search"; +import Latex from "react-latex-next"; +import cookies from "js-cookie"; +import { ControlledInputSimple } from "../atoms/ControlledInput"; +import Checkbox from "../atoms/Checkbox"; +import { triggerGAEvent, formatBytes } from "../../utils"; +import { useTranslation } from "next-i18next"; +import { capitalize } from "lodash"; + +import InternalError from "../../public/img/internalError"; +import InfoIcon from "../../public/img/icons/infoIcon"; +import DownloadIcon from "../../public/img/icons/downloadIcon"; +import SearchIcon from "../../public/img/icons/searchIcon"; +import RedirectIcon from "../../public/img/icons/redirectIcon"; +import "katex/dist/katex.min.css"; function SearchColumn({ isLoaded, resource, columns }) { - const { t } = useTranslation('dataset'); - const [inputFocus, setInputFocus] = useState(false) - const [search, setSearch] = useState("") - const [value, setValue] = useState("") - const [_timeout, _setTimeout] = useState(null) + const { t } = useTranslation("dataset"); + const [inputFocus, setInputFocus] = useState(false); + const [search, setSearch] = useState(""); + const [value, setValue] = useState(""); + const [_timeout, _setTimeout] = useState(null); useEffect(() => { - clearTimeout(_timeout) - isLoaded(true) - if(value.trim() === "") { - isLoaded(false) - return columns(resource) + clearTimeout(_timeout); + isLoaded(true); + if (value.trim() === "") { + isLoaded(false); + return columns(resource); } - _setTimeout(setTimeout(() => { - const result = searcherColumn.search(search.trim()) - if(result.length > 0) { - columns(result) - } else { - columns(resource) - } - isLoaded(false) - }, 500)) - }, [value]) + _setTimeout( + setTimeout(() => { + const result = searcherColumn.search(search.trim()); + if (result.length > 0) { + columns(result); + } else { + columns(resource); + } + isLoaded(false); + }, 500), + ); + }, [value]); useEffect(() => { - setValue(search) - }, [search]) + setValue(search); + }, [search]); - const searcherColumn = new FuzzySearch ( - resource, ["node.name", "node.description"], {sort: true} - ) + const searcherColumn = new FuzzySearch( + resource, + ["node.name", "node.description"], + { sort: true }, + ); return ( - } + icon={} /> - ) + ); } export default function TableColumns({ @@ -95,172 +93,186 @@ export default function TableColumns({ numberColumns, template, }) { - const router = useRouter() - const { query, locale } = router - const [resource, setResource] = useState({}) - const [columns, setColumns] = useState({}) - const [isError, setIsError] = useState(false) - const [isLoading, setIsLoading] = useState(true) - const [isSearchLoading, setIsSearchLoading] = useState(true) - const { t } = useTranslation('dataset'); + const router = useRouter(); + const { query, locale } = router; + const [resource, setResource] = useState({}); + const [columns, setColumns] = useState({}); + const [isError, setIsError] = useState(false); + const [isLoading, setIsLoading] = useState(true); + const [isSearchLoading, setIsSearchLoading] = useState(true); + const { t } = useTranslation("dataset"); - const isChecked = (columnSlug) => checkedColumns.includes(columnSlug) + const isChecked = (columnSlug) => checkedColumns.includes(columnSlug); const isUserPro = () => { - let user - if(cookies.get("userBD")) user = JSON.parse(cookies.get("userBD")) + let user; + if (cookies.get("userBD")) user = JSON.parse(cookies.get("userBD")); - if(user?.isSubscriber) return user?.isSubscriber - return false - } + if (user?.isSubscriber) return user?.isSubscriber; + return false; + }; const handleCheckboxChange = (columnSlug) => { if (isChecked(columnSlug)) { - onChangeCheckedColumns(checkedColumns.filter(slug => slug !== columnSlug)) + onChangeCheckedColumns( + checkedColumns.filter((slug) => slug !== columnSlug), + ); } else { - onChangeCheckedColumns([...checkedColumns, columnSlug]) + onChangeCheckedColumns([...checkedColumns, columnSlug]); } - } + }; const handleMasterCheckboxChange = () => { - if(checkedColumns.length > 0) return onChangeCheckedColumns([]) - const allColumnSlugs = resource.map(column => column.node.name) + if (checkedColumns.length > 0) return onChangeCheckedColumns([]); + const allColumnSlugs = resource.map((column) => column.node.name); if (checkedColumns.length === allColumnSlugs.length) { - onChangeCheckedColumns([]) + onChangeCheckedColumns([]); } else { - onChangeCheckedColumns(allColumnSlugs) + onChangeCheckedColumns(allColumnSlugs); } - } + }; useEffect(() => { - if(tableId === undefined) return + if (tableId === undefined) return; const featchColumns = async () => { - setHasLoading(true) + setHasLoading(true); try { const url = `/api/tables/getTableColumns?id=${tableId}&locale=${locale}`; - const response = await fetch(url, { method: "GET" }) - const result = await response.json() - - if(result.success) { - setResource(result.resource.sort(sortElements)) - numberColumns(result.resource.length) - setColumns(result.resource.sort(sortElements)) - setHasLoading(false) - setIsSearchLoading(false) - setIsError(false) + const response = await fetch(url, { method: "GET" }); + const result = await response.json(); + + if (result.success) { + setResource(result.resource.sort(sortElements)); + numberColumns(result.resource.length); + setColumns(result.resource.sort(sortElements)); + setHasLoading(false); + setIsSearchLoading(false); + setIsError(false); } else { - console.error(result.error) - setIsError(true) + console.error(result.error); + setIsError(true); } - } catch (error) { - console.error(error) - setIsError(true) + console.error(error); + setIsError(true); } finally { - setIsLoading(false) + setIsLoading(false); } - } + }; - featchColumns() - },[tableId, locale]) + featchColumns(); + }, [tableId, locale]); useEffect(() => { - setIsLoading(hasLoading) - }, [hasLoading]) + setIsLoading(hasLoading); + }, [hasLoading]); const headers = [ { - pt: t('column.name'), - tooltip: t('column.nameTooltip') + pt: t("column.name"), + tooltip: t("column.nameTooltip"), }, { - pt: template === "download" ? t('column.translationTable') : t('column.needsTranslation'), - tooltip: template === "download" ? t('column.translationTableTooltip') : t('column.needsTranslationTooltip') + pt: + template === "download" + ? t("column.translationTable") + : t("column.needsTranslation"), + tooltip: + template === "download" + ? t("column.translationTableTooltip") + : t("column.needsTranslationTooltip"), }, { - pt: t('column.description'), - tooltip: t('column.descriptionTooltip') + pt: t("column.description"), + tooltip: t("column.descriptionTooltip"), }, { - pt: t('column.bigQueryType'), - tooltip: t('column.bigQueryTypeTooltip') + pt: t("column.bigQueryType"), + tooltip: t("column.bigQueryTypeTooltip"), }, { - pt: t('column.temporalCoverage'), - tooltip: t('column.temporalCoverageTooltip') + pt: t("column.temporalCoverage"), + tooltip: t("column.temporalCoverageTooltip"), }, { - pt: t('column.measurementUnit'), - tooltip: t('column.measurementUnitTooltip') + pt: t("column.measurementUnit"), + tooltip: t("column.measurementUnitTooltip"), }, { - pt: t('column.sensitiveData'), - tooltip: t('column.sensitiveDataTooltip') + pt: t("column.sensitiveData"), + tooltip: t("column.sensitiveDataTooltip"), }, { - pt: t('column.observations'), - tooltip: t('column.observationsTooltip') - } - ] + pt: t("column.observations"), + tooltip: t("column.observationsTooltip"), + }, + ]; function sortElements(a, b) { if (a.node.order < b.node.order) { - return -1 + return -1; } if (a.node.order > b.node.order) { - return 1 + return 1; } - return 0 + return 0; } function HasDownloadPermitted(value) { - let downloadPermitted = false - let downloadWarning = "" + let downloadPermitted = false; + let downloadWarning = ""; if (value) { const limit100MB = 100 * 1024 * 1024; const limit1GB = 1 * 1024 * 1024 * 1024; if (value < limit100MB) { - downloadPermitted = true - downloadWarning = "free" + downloadPermitted = true; + downloadWarning = "free"; } else if (value < limit1GB) { - downloadPermitted = isUserPro() - downloadWarning = "100mbBetween1gb" + downloadPermitted = isUserPro(); + downloadWarning = "100mbBetween1gb"; } else { - downloadPermitted = false - downloadWarning = "biggest1gb" + downloadPermitted = false; + downloadWarning = "biggest1gb"; } } return { - downloadPermitted : downloadPermitted, - downloadWarning : downloadWarning - } + downloadPermitted: downloadPermitted, + downloadWarning: downloadWarning, + }; } function DictionaryDownload() { async function downloadTable() { - const result = await fetch(`/api/tables/getDictionaryTable?p=${btoa(query.dataset)}`, {method: "GET"}) - .then(res => res.json()) + const result = await fetch( + `/api/tables/getDictionaryTable?p=${btoa(query.dataset)}`, + { method: "GET" }, + ).then((res) => res.json()); - if(result?.error) return + if (result?.error) return; - let cloudTables = result?.cloudTables?.edges[0]?.node - const downloadInfo = HasDownloadPermitted(result?.uncompressedFileSize) + let cloudTables = result?.cloudTables?.edges[0]?.node; + const downloadInfo = HasDownloadPermitted(result?.uncompressedFileSize); - triggerGAEvent("download_da_tabela",`{ - gcp: ${cloudTables?.gcpProjectId+"."+cloudTables?.gcpDatasetId+"."+cloudTables?.gcpTableId}, + triggerGAEvent( + "download_da_tabela", + `{ + gcp: ${cloudTables?.gcpProjectId + "." + cloudTables?.gcpDatasetId + "." + cloudTables?.gcpTableId}, tamanho: ${formatBytes(result.uncompressedFileSize) || ""}, dataset: ${query.dataset}, table: ${resource?._id}, columnDownload: true - }`) + }`, + ); - window.open(`/api/tables/downloadTable?p=${btoa(cloudTables?.gcpDatasetId)}&q=${btoa(cloudTables?.gcpTableId)}&d=${btoa(downloadInfo.downloadPermitted)}&s=${btoa(downloadInfo.downloadWarning)}`) + window.open( + `/api/tables/downloadTable?p=${btoa(cloudTables?.gcpDatasetId)}&q=${btoa(cloudTables?.gcpTableId)}&d=${btoa(downloadInfo.downloadPermitted)}&s=${btoa(downloadInfo.downloadWarning)}`, + ); } return ( @@ -275,60 +287,68 @@ export default function TableColumns({ color="#0068C5" fill="#0068C5" _hover={{ - color:"#0057A4", - fill:"#0057A4" + color: "#0057A4", + fill: "#0057A4", }} > - {t('column.downloadTranslationTable')} - + {t("column.downloadTranslationTable")} + - {t('column.dictionary')} + {t("column.dictionary")} - ) + ); } function TranslationTable({ value, dictionary }) { - const downloadInfo = HasDownloadPermitted(value?.table?.uncompressedFileSize) - const cloudValues = value?.table?.cloudTables?.edges?.[0]?.node - - const gcpProjectID = cloudValues?.gcpProjectId || "" - const gcpDatasetID = cloudValues?.gcpDatasetId || "" - const gcpTableId = cloudValues?.gcpTableId || "" - - const datasetName = value?.table?.dataset?.name || "" - const tableName = value?.table?.name || "" - - if(gcpDatasetID === "br_bd_diretorios_data_tempo") return t('column.noTranslationNeeded') - if(gcpDatasetID === "br_bd_diretorios_brasil") { - if(gcpTableId === "empresa" || gcpTableId === "cep") return t('column.noTranslationNeeded') + const downloadInfo = HasDownloadPermitted( + value?.table?.uncompressedFileSize, + ); + const cloudValues = value?.table?.cloudTables?.edges?.[0]?.node; + + const gcpProjectID = cloudValues?.gcpProjectId || ""; + const gcpDatasetID = cloudValues?.gcpDatasetId || ""; + const gcpTableId = cloudValues?.gcpTableId || ""; + + const datasetName = value?.table?.dataset?.name || ""; + const tableName = value?.table?.name || ""; + + if (gcpDatasetID === "br_bd_diretorios_data_tempo") + return t("column.noTranslationNeeded"); + if (gcpDatasetID === "br_bd_diretorios_brasil") { + if (gcpTableId === "empresa" || gcpTableId === "cep") + return t("column.noTranslationNeeded"); } - if(value?.name === "ddd") return t('column.noTranslationNeeded') + if (value?.name === "ddd") return t("column.noTranslationNeeded"); return ( - {value === null ? - - {t('column.noTranslationNeeded')} + {value === null ? ( + + {t("column.noTranslationNeeded")} - : + ) : ( { - if(!downloadInfo.downloadPermitted) return - triggerGAEvent("download_da_tabela",`{ - gcp: ${gcpProjectID+"."+gcpDatasetID+"."+gcpTableId}, + if (!downloadInfo.downloadPermitted) return; + triggerGAEvent( + "download_da_tabela", + `{ + gcp: ${gcpProjectID + "." + gcpDatasetID + "." + gcpTableId}, tamanho: ${formatBytes(value?.table?.uncompressedFileSize) || ""}, dataset: ${value?.table?.dataset?._id}, table: ${value?.table?._id}, columnDownload: true - }`) + }`, + ); }} flexDirection="row" alignItems="center" @@ -336,44 +356,41 @@ export default function TableColumns({ color="#0068C5" fill="#0068C5" _hover={{ - color:"#0057A4", - fill:"#0057A4" + color: "#0057A4", + fill: "#0057A4", }} > - {value?.table?.isClosed || !downloadInfo.downloadPermitted - ? + {value?.table?.isClosed || !downloadInfo.downloadPermitted ? ( <> - {t('column.accessTranslationTable')} - + {t("column.accessTranslationTable")} + - : + ) : ( <> - {t('column.downloadTranslationTable')} - + {t("column.downloadTranslationTable")} + - } + )} + + + {datasetName} - {tableName} - {datasetName} - {tableName} - } + )} - {dictionary === true && - - } + {dictionary === true && } - ) + ); } const measurementUnit = (value) => { - if(!value) return t('column.notProvided') + if (!value) return t("column.notProvided"); - const splitValue = value.split(/([^a-z])/) - const translated = (value) => value.map((elm) => elm) + const splitValue = value.split(/([^a-z])/); + const translated = (value) => value.map((elm) => elm); - return ( - {`$${translated(splitValue).join("")}$`} - ) - } + return {`$${translated(splitValue).join("")}$`}; + }; function TableHeader({ header, ...props }) { return ( @@ -430,7 +447,11 @@ export default function TableColumns({ - ) + ); } - function TableValue({children, ...props}) { + function TableValue({ children, ...props }) { return ( {children} - ) + ); } function TranslationColumnException({ value }) { - const cloudValues = value?.node?.directoryPrimaryKey?.table?.cloudTables?.edges?.[0]?.node - const gcpDatasetID = cloudValues?.gcpDatasetId || "" - const gcpTableId = cloudValues?.gcpTableId || "" - - if(gcpDatasetID === "br_bd_diretorios_data_tempo") return t('column.no') - if(gcpDatasetID === "br_bd_diretorios_brasil") { - if(gcpTableId === "empresa" || gcpTableId === "cep") return t('column.no') + const cloudValues = + value?.node?.directoryPrimaryKey?.table?.cloudTables?.edges?.[0]?.node; + const gcpDatasetID = cloudValues?.gcpDatasetId || ""; + const gcpTableId = cloudValues?.gcpTableId || ""; + + if (gcpDatasetID === "br_bd_diretorios_data_tempo") return t("column.no"); + if (gcpDatasetID === "br_bd_diretorios_brasil") { + if (gcpTableId === "empresa" || gcpTableId === "cep") + return t("column.no"); } - if(value?.node?.name === "ddd") return t('column.no') - if(value?.node?.coveredByDictionary === true) return t('column.yes') - if(value?.node?.directoryPrimaryKey?._id) return t('column.yes') - if(value?.node?.coveredByDictionary === false) return t('column.no') - return t('column.notProvided') + if (value?.node?.name === "ddd") return t("column.no"); + if (value?.node?.coveredByDictionary === true) return t("column.yes"); + if (value?.node?.directoryPrimaryKey?._id) return t("column.yes"); + if (value?.node?.coveredByDictionary === false) return t("column.no"); + return t("column.notProvided"); } - if(isError) return ( - - - - ) + if (isError) + return ( + + + + ); return ( @@ -532,7 +553,7 @@ export default function TableColumns({ - {template === "checks" && + {template === "checks" && ( - } + )} - {headers.map((elm, i) => ( - i != 0 && - ))} + {headers.map( + (elm, i) => i != 0 && , + )} - {columns.length > 0 && columns.map((elm,i) => ( - - {template === "checks" && - + {template === "checks" && ( + + )} + + + {elm?.node?.namePt || + elm?.node?.name || + elm?.node?.[`name${capitalize(locale)}`] || + t("column.notProvided")} - handleCheckboxChange(elm.node[`name${capitalize(locale)}`] || elm.node.name)} - /> - - - - } + - - {elm?.node?.namePt || elm?.node?.name || elm?.node?.[`name${capitalize(locale)}`] || t('column.notProvided')} - - - - - {template === "download" ? - - : - - } - - - - {elm?.node?.[`description${capitalize(locale)}`] || elm?.node?.description || t('column.notProvided')} - - - - {elm?.node?.bigqueryType?.name ? elm.node.bigqueryType.name : t('column.notProvided')} - - - - {elm?.node?.temporalCoverage?.start && elm?.node?.temporalCoverage?.end ? - elm.node.temporalCoverage.start +" - "+ elm.node.temporalCoverage.end - : - t('column.notProvided') - } - - - - {elm?.node?.measurementUnit ? - measurementUnit(elm.node.measurementUnit) - : - t('column.notProvided') - } - - - - { - elm?.node?.containsSensitiveData === true ? t('column.yes') - : - elm?.node?.containsSensitiveData === false ? t('column.no') - : - t('column.notProvided') - } - - - - {elm?.node?.[`observations${capitalize(locale)}`] || elm?.node?.observations || t('column.notProvided')} - - - ))} + + {template === "download" ? ( + + ) : ( + + )} + + + + {elm?.node?.[`description${capitalize(locale)}`] || + elm?.node?.description || + t("column.notProvided")} + + + + {elm?.node?.bigqueryType?.name + ? elm.node.bigqueryType.name + : t("column.notProvided")} + + + + {elm?.node?.temporalCoverage?.start && + elm?.node?.temporalCoverage?.end + ? elm.node.temporalCoverage.start + + " - " + + elm.node.temporalCoverage.end + : t("column.notProvided")} + + + + {elm?.node?.measurementUnit + ? measurementUnit(elm.node.measurementUnit) + : t("column.notProvided")} + + + + {elm?.node?.containsSensitiveData === true + ? t("column.yes") + : elm?.node?.containsSensitiveData === false + ? t("column.no") + : t("column.notProvided")} + + + + {elm?.node?.[`observations${capitalize(locale)}`] || + elm?.node?.observations || + t("column.notProvided")} + + + ))}
- + 0} - hasIndeterminate={checkedColumns.length !== resource.length && checkedColumns.length > 0} + isIndeterminate={ + checkedColumns.length !== resource.length && + checkedColumns.length > 0 + } + hasIndeterminate={ + checkedColumns.length !== resource.length && + checkedColumns.length > 0 + } />
0 && + columns.map((elm, i) => ( +
+ + + handleCheckboxChange( + elm.node[`name${capitalize(locale)}`] || + elm.node.name, + ) + } + /> + + +
- ) + ); } diff --git a/next/components/molecules/TemporalCoverageDisplay.js b/next/components/molecules/TemporalCoverageDisplay.js index e1642555c..4fbe0ea57 100644 --- a/next/components/molecules/TemporalCoverageDisplay.js +++ b/next/components/molecules/TemporalCoverageDisplay.js @@ -4,11 +4,11 @@ import { Box, Tooltip, useDisclosure, - ModalCloseButton + ModalCloseButton, } from "@chakra-ui/react"; import { useState, useEffect } from "react"; import cookies from "js-cookie"; -import { useTranslation } from 'next-i18next'; +import { useTranslation } from "next-i18next"; import { SectionPrice } from "../../pages/prices"; import { ModalGeneral } from "./uiUserPage"; import TitleText from "../atoms/Text/TitleText"; @@ -16,52 +16,49 @@ import BodyText from "../atoms/Text/BodyText"; import RedirectIcon from "../../public/img/icons/redirectIcon"; import CheckIcon from "../../public/img/icons/checkIcon"; -export function TemporalCoverageBar ({ value }) { - const { t } = useTranslation(['dataset', 'prices']); - const [values, setValues] = useState({}) - const plansModal = useDisclosure() +export function TemporalCoverageBar({ value }) { + const { t } = useTranslation(["dataset", "prices"]); + const [values, setValues] = useState({}); + const plansModal = useDisclosure(); const isUserPro = () => { - let user - if(cookies.get("userBD")) user = JSON.parse(cookies.get("userBD")) + let user; + if (cookies.get("userBD")) user = JSON.parse(cookies.get("userBD")); - if(user?.isSubscriber) return user?.isSubscriber - return false - } + if (user?.isSubscriber) return user?.isSubscriber; + return false; + }; const TextData = ({ string, ...style }) => { return ( - + {string} - ) - } + ); + }; useEffect(() => { - if (value === null || value === undefined) return setValues(null) + if (value === null || value === undefined) return setValues(null); - let newValue = {} + let newValue = {}; - if(value["2"]?.type === "closed") newValue["3"] = value["2"].date + if (value["2"]?.type === "closed") newValue["3"] = value["2"].date; - if(value["0"]?.type === "open") newValue["0"] = value["0"].date - if(value["0"]?.type === "closed") newValue["2"] = value["0"].date + if (value["0"]?.type === "open") newValue["0"] = value["0"].date; + if (value["0"]?.type === "closed") newValue["2"] = value["0"].date; - if(value["1"]?.type === "open") newValue["1"] = value["1"].date - if(value["1"]?.type === "closed") newValue["3"] = value["1"].date + if (value["1"]?.type === "open") newValue["1"] = value["1"].date; + if (value["1"]?.type === "closed") newValue["3"] = value["1"].date; - setValues(newValue) - }, [value]) + setValues(newValue); + }, [value]); - if(values === null) return + if (values === null) + return ; return ( - - - {t('temporalCoverageBar.comparePlans')} + + {t("temporalCoverageBar.comparePlans")} - + - {t('temporalCoverageBar.free')} + {t("temporalCoverageBar.free")} { - if(isUserPro()) return - plansModal.onOpen()} - } + if (isUserPro()) return; + plansModal.onOpen(); + }} > - {t('temporalCoverageBar.paid')} - {isUserPro() ? - - : - - } + {t("temporalCoverageBar.paid")} + {isUserPro() ? ( + + ) : ( + + )} - + - ) -} \ No newline at end of file + ); +} diff --git a/next/components/molecules/ThemeCatalog.js b/next/components/molecules/ThemeCatalog.js index 6a64fb606..73e86731b 100644 --- a/next/components/molecules/ThemeCatalog.js +++ b/next/components/molecules/ThemeCatalog.js @@ -1,370 +1,417 @@ -import { - VStack, - Center, - Box, - Image, - Tooltip, - Skeleton, - SkeletonText, - Text -} from "@chakra-ui/react"; -import React, { useState, useEffect } from "react"; -import axios from 'axios'; -import { useTranslation } from 'next-i18next'; -import { useRouter } from 'next/router'; -import { capitalize } from "lodash"; -import { useMediaQuery } from "@chakra-ui/react"; -import { useCheckMobile } from "../../hooks/useCheckMobile.hook"; -import { triggerGAEvent } from "../../utils"; - -import Carousel from "../atoms/Carousel"; -import DatasetThemeCatalogCard from "../organisms/DatasetThemeCatalogCard"; -import RemoveIcon from "../../public/img/icons/removeIcon"; -import styles from "../../styles/themeCatalog.module.css"; - -function Themes ({ - loading, - responsive, - onSelectTheme, - selectedTheme=[], - listThemes, - locale, -}) { - const [screenQuery, setScreenQuery] = useState(0) - - useEffect(() => { - if(responsive.mobileQuery) - return setScreenQuery(4) - if(responsive.baseQuery) - return setScreenQuery(6) - if(responsive.mediumQuery) - return setScreenQuery(9) - if(responsive.lgQuery) - return setScreenQuery(10) - - return setScreenQuery(10) - },[responsive]) - - const found = (value) => { - return selectedTheme.find(res => res === value) - } - - return ( -
- - {loading ? - new Array(screenQuery).fill(0).map((elm, i) => ( - - )) - : - listThemes ? - Object.values(listThemes).map((elm) => ( -
onSelectTheme(elm.node.slug)} - cursor="pointer" - width={responsive.mobileQuery ? "65px" : "100px" } - minWidth={responsive.mobileQuery ? "65px" : "100px" } - height={responsive.mobileQuery ? "65px" : "100px" } - minHeight={responsive.mobileQuery ? "65px" : "100px" } - borderRadius={responsive.mobileQuery ? "12px" : "16px" } - backgroundColor={ found(elm.node.slug) ? "#2B8C4D" : "FFF"} - boxShadow="0px 1px 8px 1px rgba(64, 60, 67, 0.16)" - _hover={{ transform:"scale(1.1)", backgroundColor:"#2B8C4D" }} - transition="all 0.5s" - margin="10px 0" - > - - {elm.node[`name${capitalize(locale)}`] - - -
- )) - : - new Array(screenQuery).fill(0).map((elm, i) => ( - - )) - } -
-
- ) -} - -const SkeletonWaitCard = () => { - return ( - - - - - - - - - - - - - - - - ) -} - -function CardThemes ({ responsive, datasetsCards = [], loading, locale }) { - const { t } = useTranslation('common'); - const [screenQuery, setScreenQuery] = useState(0) - - useEffect(() => { - if(responsive.mobileQuery) - return setScreenQuery(1) - if(responsive.baseQuery) - return setScreenQuery(2) - if(responsive.mediumQuery) - return setScreenQuery(3) - - return setScreenQuery(4) - },[responsive]) - - return ( - - {!loading && datasetsCards?.length === 0 && -
- - {t('noDatasetsFound', { returnObjects: true })[0]} - {useCheckMobile() ? null :
} - {t('noDatasetsFound', { returnObjects: true })[1]} -
-
- } -
- - {loading ? - new Array(screenQuery).fill(0).map((elm, i) => ( - - )) - : - datasetsCards.length === 0 ? - new Array(screenQuery).fill(0).map((elm, i) => ( - - )) - : - datasetsCards.map((elm, i) => ( - - )) - } - -
-
- ) -} - -export default function ThemeCatalog ({ data, locale }) { - const router = useRouter() - const [listThemes, setListThemes] = useState([]) - const [defaultDatasetsCards, setDefaultDatasetCards] = useState([]) - const [fetchThemesTimeout, setFetchThemesTimeout] = useState(null) - - const [datasetsCards, setDatasetsCards] = useState([]) - const [selectedTheme, setSelectedTheme] = useState([]) - const [loading, setLoading] = useState(true) - const [loadingTheme, setLoadingTheme] = useState(true) - - const mobileCheck = useCheckMobile() - const [mobileQuery, setMobileQuery] = useState(false) - const [baseQuery] = useMediaQuery("(max-width: 938px)") - const [mediumQuery] = useMediaQuery("(max-width: 1250px)") - const [lgQuery] = useMediaQuery("(max-width: 1366px)") - - useEffect(() => { - setMobileQuery(mobileCheck) - setListThemes(data.themes) - setDefaultDatasetCards(data.defaultDataset) - setLoading(false) - setLoadingTheme(false) - },[data]) - - useEffect(() => { - if(selectedTheme.length > 0) { - if(fetchThemesTimeout) clearTimeout(fetchThemesTimeout) - setLoading(true) - - const fetchFunc = setTimeout(async () => { - try { - const response = await axios.get('/api/themes/getDatasetsByThemes', { - params: { themes: selectedTheme.join(','), locale } - }); - setDatasetsCards(response.data); - setLoading(false); - } catch (error) { - console.error('Error fetching datasets by themes:', error); - setLoading(false); - } - }, 500) - - setFetchThemesTimeout(fetchFunc) - } else { - setDatasetsCards(defaultDatasetsCards); - } - }, [selectedTheme, locale, defaultDatasetsCards]); - - const handleSelectTheme = (elm) => { - router.push("#theme", undefined, { locale: router.locale }) - if(selectedTheme.includes(elm)) { - setSelectedTheme(selectedTheme.filter(res => res !== elm)) - } else { - triggerGAEvent("theme_home", elm) - triggerGAEvent("theme", elm) - setSelectedTheme([elm, ...selectedTheme]) - } - } - - return ( - - - - - - ) -} +import { + VStack, + Center, + Box, + Image, + Tooltip, + Skeleton, + SkeletonText, + Text, +} from "@chakra-ui/react"; +import React, { useState, useEffect } from "react"; +import axios from "axios"; +import { useTranslation } from "next-i18next"; +import { useRouter } from "next/router"; +import { capitalize } from "lodash"; +import { useMediaQuery } from "@chakra-ui/react"; +import { useCheckMobile } from "../../hooks/useCheckMobile.hook"; +import { triggerGAEvent } from "../../utils"; + +import Carousel from "../atoms/Carousel"; +import DatasetThemeCatalogCard from "../organisms/DatasetThemeCatalogCard"; +import RemoveIcon from "../../public/img/icons/removeIcon"; +import styles from "../../styles/themeCatalog.module.css"; + +function Themes({ + loading, + responsive, + onSelectTheme, + selectedTheme = [], + listThemes, + locale, +}) { + const [screenQuery, setScreenQuery] = useState(0); + + useEffect(() => { + if (responsive.mobileQuery) return setScreenQuery(4); + if (responsive.baseQuery) return setScreenQuery(6); + if (responsive.mediumQuery) return setScreenQuery(9); + if (responsive.lgQuery) return setScreenQuery(10); + + return setScreenQuery(10); + }, [responsive]); + + const found = (value) => { + return selectedTheme.find((res) => res === value); + }; + + return ( +
+ + {loading + ? new Array(screenQuery) + .fill(0) + .map((elm, i) => ( + + )) + : listThemes + ? Object.values(listThemes).map((elm) => ( +
onSelectTheme(elm.node.slug)} + cursor="pointer" + width={responsive.mobileQuery ? "65px" : "100px"} + minWidth={responsive.mobileQuery ? "65px" : "100px"} + height={responsive.mobileQuery ? "65px" : "100px"} + minHeight={responsive.mobileQuery ? "65px" : "100px"} + borderRadius={responsive.mobileQuery ? "12px" : "16px"} + backgroundColor={found(elm.node.slug) ? "#2B8C4D" : "FFF"} + boxShadow="0px 1px 8px 1px rgba(64, 60, 67, 0.16)" + _hover={{ + transform: "scale(1.1)", + backgroundColor: "#2B8C4D", + }} + transition="all 0.5s" + margin="10px 0" + > + + { + + +
+ )) + : new Array(screenQuery) + .fill(0) + .map((elm, i) => ( + + ))} +
+
+ ); +} + +const SkeletonWaitCard = () => { + return ( + + + + + + + + + + + + + + + + ); +}; + +function CardThemes({ responsive, datasetsCards = [], loading, locale }) { + const { t } = useTranslation("common"); + const [screenQuery, setScreenQuery] = useState(0); + + useEffect(() => { + if (responsive.mobileQuery) return setScreenQuery(1); + if (responsive.baseQuery) return setScreenQuery(2); + if (responsive.mediumQuery) return setScreenQuery(3); + + return setScreenQuery(4); + }, [responsive]); + + return ( + + {!loading && datasetsCards?.length === 0 && ( +
+ + {t("noDatasetsFound", { returnObjects: true })[0]} + {useCheckMobile() ? null :
} + {t("noDatasetsFound", { returnObjects: true })[1]} +
+
+ )} +
+ + {loading + ? new Array(screenQuery) + .fill(0) + .map((elm, i) => ) + : datasetsCards.length === 0 + ? new Array(screenQuery) + .fill(0) + .map((elm, i) => ) + : datasetsCards.map((elm, i) => ( + + ))} + +
+
+ ); +} + +export default function ThemeCatalog({ data, locale }) { + const router = useRouter(); + const [listThemes, setListThemes] = useState([]); + const [defaultDatasetsCards, setDefaultDatasetCards] = useState([]); + const [fetchThemesTimeout, setFetchThemesTimeout] = useState(null); + + const [datasetsCards, setDatasetsCards] = useState([]); + const [selectedTheme, setSelectedTheme] = useState([]); + const [loading, setLoading] = useState(true); + const [loadingTheme, setLoadingTheme] = useState(true); + + const mobileCheck = useCheckMobile(); + const [mobileQuery, setMobileQuery] = useState(false); + const [baseQuery] = useMediaQuery("(max-width: 938px)"); + const [mediumQuery] = useMediaQuery("(max-width: 1250px)"); + const [lgQuery] = useMediaQuery("(max-width: 1366px)"); + + useEffect(() => { + setMobileQuery(mobileCheck); + setListThemes(data.themes); + setDefaultDatasetCards(data.defaultDataset); + setLoading(false); + setLoadingTheme(false); + }, [data]); + + useEffect(() => { + if (selectedTheme.length > 0) { + if (fetchThemesTimeout) clearTimeout(fetchThemesTimeout); + setLoading(true); + + const fetchFunc = setTimeout(async () => { + try { + const response = await axios.get("/api/themes/getDatasetsByThemes", { + params: { themes: selectedTheme.join(","), locale }, + }); + setDatasetsCards(response.data); + setLoading(false); + } catch (error) { + console.error("Error fetching datasets by themes:", error); + setLoading(false); + } + }, 500); + + setFetchThemesTimeout(fetchFunc); + } else { + setDatasetsCards(defaultDatasetsCards); + } + }, [selectedTheme, locale, defaultDatasetsCards]); + + const handleSelectTheme = (elm) => { + router.push("#theme", undefined, { locale: router.locale }); + if (selectedTheme.includes(elm)) { + setSelectedTheme(selectedTheme.filter((res) => res !== elm)); + } else { + triggerGAEvent("theme_home", elm); + triggerGAEvent("theme", elm); + setSelectedTheme([elm, ...selectedTheme]); + } + }; + + return ( + + + + + + ); +} diff --git a/next/components/molecules/uiUserPage.js b/next/components/molecules/uiUserPage.js index 6c978c4dd..b6acbc121 100644 --- a/next/components/molecules/uiUserPage.js +++ b/next/components/molecules/uiUserPage.js @@ -15,13 +15,13 @@ import { FormErrorMessage, Spinner, ListItem, - ListIcon + ListIcon, } from "@chakra-ui/react"; import Exclamation from "../../public/img/icons/exclamationIcon"; import CheckIcon from "../../public/img/icons/checkIcon"; import CircleIcon from "../../public/img/icons/circleIcon"; -export function LabelTextForm ({ text, ...props }) { +export function LabelTextForm({ text, ...props }) { return ( {text} - ) + > + {text} + + ); } -export function TitleTextForm ({ children, ...props }) { +export function TitleTextForm({ children, ...props }) { return ( {children} - ) + > + {children} + + ); } -export function SkStack ({ isLoaded, children, ...props }) { +export function SkStack({ isLoaded, children, ...props }) { return ( {children} - ) + ); } -export function ExtraInfoTextForm ({children, ...props}) { +export function ExtraInfoTextForm({ children, ...props }) { return ( {children} - ) + > + {children} + + ); } -export function ModalGeneral ({ +export function ModalGeneral({ children, isOpen, onClose, isCentered = true, propsModal, propsModalContent, - classNameBody + classNameBody, }) { return ( - + - - {children[0]} - + {children[0]} {children[1]} - + {children[2]} - ) + ); } export function InputForm({ @@ -149,14 +153,14 @@ export function InputForm({ border="2px solid transparent !important" color="#464A51" _hover={{ - border:"2px solid transparent !important", - backgroundColor:"#DEDFE0", + border: "2px solid transparent !important", + backgroundColor: "#DEDFE0", }} _focus={{ - border:"2px solid #0068C5 !important", + border: "2px solid #0068C5 !important", backgroundColor: "#FFF", }} - _invalid={{backgroundColor:"#F6E3E3"}} + _invalid={{ backgroundColor: "#F6E3E3" }} paddingRight={icon !== null && "52px !important"} backgroundColor="#EEEEEE" height="40px" @@ -166,11 +170,11 @@ export function InputForm({ fontFamily="Roboto" fontWeight="400" borderRadius="8px" - _placeholder={{color: "#464A51", opacity: 1}} + _placeholder={{ color: "#464A51", opacity: 1 }} {...props} /> - {icon && + {icon && ( - } + )} - ) + ); } export function ErrorMessage({ children }) { @@ -197,16 +201,13 @@ export function ErrorMessage({ children }) { gap="8px" alignItems="flex-start" > - {children} + + {children} - ) + ); } -export function Button ({ children, onClick, isLoading, ...props }) { +export function Button({ children, onClick, isLoading, ...props }) { return ( - {isLoading ? - - : - children - } + {isLoading ? : children} - ) + ); } export function ListChecked({ children, checked = false, err = false }) { return ( - - {checked ? : } + + {checked ? ( + + ) : ( + + )} {children} - ) -} \ No newline at end of file + ); +} diff --git a/next/components/organisms/BePartner.js b/next/components/organisms/BePartner.js index 3343d41ef..eeefead06 100644 --- a/next/components/organisms/BePartner.js +++ b/next/components/organisms/BePartner.js @@ -5,9 +5,9 @@ import { Text, Center, Image, - Avatar + Avatar, } from "@chakra-ui/react"; -import { useTranslation } from 'next-i18next'; +import { useTranslation } from "next-i18next"; import TitleText from "../atoms/Text/TitleText"; import LabelText from "../atoms/Text/LabelText"; import BodyText from "../atoms/Text/BodyText"; @@ -47,25 +47,14 @@ function Testimonial({ children, name, position, src }) { - + {name} - + {position} - + ); @@ -97,7 +86,7 @@ function PartnerBox({ src, ...props }) { } export function BePartner() { - const { t } = useTranslation('common'); + const { t } = useTranslation("common"); return ( @@ -115,7 +104,7 @@ export function BePartner() { textAlign="center" color="#71757A" > - {t('partners.partnershipsWith')} + {t("partners.partnershipsWith")} - - - - - - - - + + + + + + + +
- - {t('partners.testimonials.fernando.quote')} - + + {t("partners.testimonials.fernando.quote")} + - - {t('partners.testimonials.marina.quote')} - + + {t("partners.testimonials.marina.quote")} + - - {t('partners.testimonials.amanda.quote')} - + + {t("partners.testimonials.amanda.quote")} +
diff --git a/next/components/organisms/Blog/Home.js b/next/components/organisms/Blog/Home.js index 7b20e9605..4f29c0a77 100644 --- a/next/components/organisms/Blog/Home.js +++ b/next/components/organisms/Blog/Home.js @@ -10,7 +10,7 @@ import { Divider, } from "@chakra-ui/react"; import { useEffect, useState } from "react"; -import { useTranslation } from 'next-i18next'; +import { useTranslation } from "next-i18next"; import { categories } from "../../../pages/api/blog/categories"; import Display from "../../atoms/Text/Display"; import TitleText from "../../atoms/Text/TitleText"; @@ -35,10 +35,7 @@ export function DatePost({ date, slug }) { } return ( - + {dateToLocatePt(date)} ); @@ -66,12 +63,8 @@ function LatestBlogCard({ slug, frontmatter }) { width="100%" maxWidth={{ base: "100%", md: "100%", lg: "648px" }} > - - + + - + - - {title} - + {title} - - {description} - + {description} - - {authors ? ( - - {authors[0].name} - - ) : null} + + {authors ? {authors[0].name} : null} @@ -127,38 +103,24 @@ function LatestBlogCard({ slug, frontmatter }) { function MiniBlogCard({ slug, frontmatter }) { const { title, description, date, authors } = frontmatter; return ( - + - - {title} + {title} - - {description} - + {description} - - {authors ? ( - - {authors[0].name} - - ) : null} + + {authors ? {authors[0].name} : null} @@ -166,31 +128,31 @@ function MiniBlogCard({ slug, frontmatter }) { } function BlogHeader({ category }) { - const { t } = useTranslation('blog') + const { t } = useTranslation("blog"); return ( - + - - {t('filter')} + + {t("filter")} {[ - { name: t('all'), shortName: "all", href: "/blog" }, + { name: t("all"), shortName: "all", href: "/blog" }, ...Object.entries(categories).map((category) => { const [shortName, name] = category; return { @@ -207,7 +169,7 @@ function BlogHeader({ category }) { pointerEvents={shortName === category ? "none" : "default"} background={shortName === category ? "#2B8C4D" : "#EEEEEE"} _hover={{ - opacity: 0.8 + opacity: 0.8, }} > { - const { frontmatter } = elm - const categories = frontmatter.categories || [] + array.forEach((elm) => { + const { frontmatter } = elm; + const categories = frontmatter.categories || []; - if(categories.length > 0 ) { - categories.forEach(category => { + if (categories.length > 0) { + categories.forEach((category) => { if (!result[category]) { - result[category] = [] + result[category] = []; } - result[category].push({ ...elm }) - }) + result[category].push({ ...elm }); + }); } else { if (!result["no categories"]) { - result["no categories"] = [] + result["no categories"] = []; } - result["no categories"].push({ ...elm }) + result["no categories"].push({ ...elm }); } - }) + }); - return result + return result; } useEffect(() => { - setData(groupByCategories(posts)) - }, [posts]) + setData(groupByCategories(posts)); + }, [posts]); return ( - {category === "all" ? - data && Object.entries(data).map(([key, value], index) => { + {category === "all" ? ( + data && + Object.entries(data).map(([key, value], index) => { return ( - {value.length > 7 && + {value.length > 7 && ( {t("seeAll")} @@ -321,10 +284,13 @@ export function BlogGrid({ posts, category }) { width="16px" /> - } + )} - + {value.slice(0, 7).map((post, index) => { if (index === 0) { return ( @@ -332,8 +298,8 @@ export function BlogGrid({ posts, category }) { as="article" key={index} gridColumn={{ md: "span 2", xl: "span 3" }} - borderBottom={{base: "1px solid #DEDFE0", md: "none"}} - paddingBottom={{base: "24px", md: "none"}} + borderBottom={{ base: "1px solid #DEDFE0", md: "none" }} + paddingBottom={{ base: "24px", md: "none" }} > @@ -354,18 +320,18 @@ export function BlogGrid({ posts, category }) { })} - ) + ); }) - : + ) : ( - + {categories?.[category] || category} - + {posts.map((post, index) => { if (index === 0) { return ( @@ -373,8 +339,8 @@ export function BlogGrid({ posts, category }) { as="article" key={index} gridColumn={{ md: "span 2", xl: "span 3" }} - borderBottom={{base: "1px solid #DEDFE0", md: "none"}} - paddingBottom={{base: "24px", md: "none"}} + borderBottom={{ base: "1px solid #DEDFE0", md: "none" }} + paddingBottom={{ base: "24px", md: "none" }} > @@ -395,7 +361,7 @@ export function BlogGrid({ posts, category }) { })} - } + )} ); -} \ No newline at end of file +} diff --git a/next/components/organisms/Blog/Slug.js b/next/components/organisms/Blog/Slug.js index a8eb1a89b..e7fe09aed 100644 --- a/next/components/organisms/Blog/Slug.js +++ b/next/components/organisms/Blog/Slug.js @@ -20,7 +20,7 @@ import { Divider, Link as ChakraLink, } from "@chakra-ui/react"; -import { useTranslation } from 'next-i18next'; +import { useTranslation } from "next-i18next"; import { useRouter } from "next/router"; import { useEffect, useState } from "react"; import hljs from "highlight.js/lib/core"; @@ -28,10 +28,7 @@ import Link from "../../atoms/Link"; import Display from "../../atoms/Text/Display"; import LabelText from "../../atoms/Text/LabelText"; import BodyText from "../../atoms/Text/BodyText"; -import { - DatePost, - dateToLocatePt -} from "./Home"; +import { DatePost, dateToLocatePt } from "./Home"; import { CopyIcon } from "../../../public/img/icons/copyIcon"; import FacebookIcon from "../../../public/img/icons/facebookIcon"; @@ -150,7 +147,7 @@ function NativeShare({ url, title, description }) { { if (nagivatorAvailable) { navigator @@ -197,7 +194,7 @@ export function ShareButtons({ frontmatter }) { @@ -205,7 +202,7 @@ export function ShareButtons({ frontmatter }) { @@ -213,13 +210,13 @@ export function ShareButtons({ frontmatter }) { - + ); } @@ -263,13 +260,10 @@ function FigCaption(props) { export function Toc({ headings }) { return ( - + Tabela de conteúdo - + {headings.map(({ id, title, level }) => ( @@ -279,7 +273,7 @@ export function Toc({ headings }) { display="block" _hover={{ textDecoration: "none", - opacity: 0.8 + opacity: 0.8, }} fontWeight="500" fontSize="14px" @@ -298,65 +292,49 @@ export function Toc({ headings }) { } export function Header({ frontmatter, slug }) { - const { t } = useTranslation('blog') + const { t } = useTranslation("blog"); return ( - - {frontmatter.title} - - + {frontmatter.title} + {frontmatter.description} {frontmatter.authors && ( - {frontmatter.authors.map((elm) => elm.name).join(', ')} + {frontmatter.authors.map((elm) => elm.name).join(", ")} )} - {frontmatter?.date && + {frontmatter?.date && ( - {frontmatter.date?.created && + {frontmatter.date?.created && ( <> - {frontmatter.date?.updated && - + {frontmatter.date?.updated && ( + {`${t("edited")} ${dateToLocatePt(frontmatter.date.updated)}`} - } + )} - } + )} - } + )} - - - {t("share")} - + + {t("share")} - + @@ -380,14 +358,14 @@ export const mdxComponents = { /> ), a: (props) => ( - + ), hr: (props) => ( ), - p: (props) => ( - - ), + p: (props) => , // Inline code code: (props) => ( , ul: (props) => , li: (props) => ( - + ), table: (props) => ( @@ -487,13 +458,9 @@ export const mdxComponents = { > “ - + {figcaption ? ( - + ) : null} ); diff --git a/next/components/organisms/DatasetResource.js b/next/components/organisms/DatasetResource.js index 84b148c74..51ebae9eb 100644 --- a/next/components/organisms/DatasetResource.js +++ b/next/components/organisms/DatasetResource.js @@ -10,7 +10,7 @@ import { MenuList, MenuItem, MenuDivider, - useBreakpointValue + useBreakpointValue, } from "@chakra-ui/react"; import { useRef, useEffect, useState } from "react"; import { useRouter } from "next/router"; @@ -25,85 +25,116 @@ import InformationRequestPage from "./InformationRequestPage"; import ChevronIcon from "../../public/img/icons/chevronIcon"; -export default function DatasetResource({ - dataset, - isBDSudo -}) { - const { t } = useTranslation('dataset'); - const router = useRouter() - const { query, locale } = router - const [tables, setTables] = useState([]) - const [rawDataSources, setRawDataSources] = useState([]) - const [informationRequests, setInformationRequests] = useState([]) - const displayScreen = useBreakpointValue({ base: "mobile", lg: "desktop" }) +export default function DatasetResource({ dataset, isBDSudo }) { + const { t } = useTranslation("dataset"); + const router = useRouter(); + const { query, locale } = router; + const [tables, setTables] = useState([]); + const [rawDataSources, setRawDataSources] = useState([]); + const [informationRequests, setInformationRequests] = useState([]); + const displayScreen = useBreakpointValue({ base: "mobile", lg: "desktop" }); const pushQuery = (key, value) => { - router.replace({ - pathname: `/dataset/${query.dataset}`, - query: { [key]: value } - }, - undefined, { shallow: true } - ) - } + router.replace( + { + pathname: `/dataset/${query.dataset}`, + query: { [key]: value }, + }, + undefined, + { shallow: true }, + ); + }; function sortElements(a, b) { if (a.order < b.order) { - return -1 + return -1; } if (a.order > b.order) { - return 1 + return 1; } - return 0 + return 0; } useEffect(() => { - let dataset_tables - let raw_data_sources - let information_request - - if(isBDSudo) { - dataset_tables = dataset?.tables?.edges?.map((elm) => elm.node)?.sort(sortElements) || []; - raw_data_sources = dataset?.rawDataSources?.edges?.map((elm) => elm.node)?.sort(sortElements) || []; - information_request = dataset?.informationRequests?.edges?.map((elm) => elm.node)?.sort(sortElements) || []; + let dataset_tables; + let raw_data_sources; + let information_request; + + if (isBDSudo) { + dataset_tables = + dataset?.tables?.edges?.map((elm) => elm.node)?.sort(sortElements) || + []; + raw_data_sources = + dataset?.rawDataSources?.edges + ?.map((elm) => elm.node) + ?.sort(sortElements) || []; + information_request = + dataset?.informationRequests?.edges + ?.map((elm) => elm.node) + ?.sort(sortElements) || []; } else { - dataset_tables = dataset?.tables?.edges - ?.map((elm) => elm.node) + dataset_tables = + dataset?.tables?.edges + ?.map((elm) => elm.node) ?.filter( (elm) => !["under_review", "excluded"].includes(elm?.status?.slug) && - !["dicionario", "dictionary"].includes(elm?.slug) + !["dicionario", "dictionary"].includes(elm?.slug), ) - ?.sort(sortElements) || []; + ?.sort(sortElements) || []; - raw_data_sources = dataset?.rawDataSources?.edges - ?.map((elm) => elm.node) - ?.filter((elm) => !["under_review", "excluded"].includes(elm?.status?.slug)) - ?.sort(sortElements) || []; + raw_data_sources = + dataset?.rawDataSources?.edges + ?.map((elm) => elm.node) + ?.filter( + (elm) => !["under_review", "excluded"].includes(elm?.status?.slug), + ) + ?.sort(sortElements) || []; - information_request = dataset?.informationRequests?.edges - ?.map((elm) => elm.node) - ?.filter((elm) => !["under_review", "excluded"].includes(elm?.status?.slug)) - ?.sort(sortElements) || []; + information_request = + dataset?.informationRequests?.edges + ?.map((elm) => elm.node) + ?.filter( + (elm) => !["under_review", "excluded"].includes(elm?.status?.slug), + ) + ?.sort(sortElements) || []; } setTables(dataset_tables); setRawDataSources(raw_data_sources); setInformationRequests(information_request); - const queryParams = new URLSearchParams(window.location.search) + const queryParams = new URLSearchParams(window.location.search); - if(queryParams.toString().length === 0) { - if(dataset_tables.length > 0) return pushQuery("table", dataset_tables[0]?._id) - if(raw_data_sources.length > 0) return pushQuery("raw_data_source", raw_data_sources[0]?._id) - if(information_request.length > 0) return pushQuery("information_request", information_request[0]?._id) + if (queryParams.toString().length === 0) { + if (dataset_tables.length > 0) + return pushQuery("table", dataset_tables[0]?._id); + if (raw_data_sources.length > 0) + return pushQuery("raw_data_source", raw_data_sources[0]?._id); + if (information_request.length > 0) + return pushQuery("information_request", information_request[0]?._id); } - }, [dataset, isBDSudo === true]) - - function SwitchResource ({route}) { - if (route.hasOwnProperty("table")) return - if (route.hasOwnProperty("raw_data_source")) return - if (route.hasOwnProperty("information_request")) return - return null + }, [dataset, isBDSudo === true]); + + function SwitchResource({ route }) { + if (route.hasOwnProperty("table")) + return ; + if (route.hasOwnProperty("raw_data_source")) + return ( + + ); + if (route.hasOwnProperty("information_request")) + return ( + + ); + return null; } function ContentFilter({ @@ -111,24 +142,24 @@ export default function DatasetResource({ choices, onChange, value, - hasDivider = true + hasDivider = true, }) { - const [isOverflow, setIsOverflow] = useState({}) - const textRefs = useRef({}) + const [isOverflow, setIsOverflow] = useState({}); + const textRefs = useRef({}); - if(choices.length === 0) return null + if (choices.length === 0) return null; useEffect(() => { choices.forEach((elm, i) => { - const textElement = textRefs.current[i] + const textElement = textRefs.current[i]; if (textElement) { setIsOverflow((prev) => ({ ...prev, [i]: textElement.scrollWidth > textElement.clientWidth, - })) + })); } - }) - }, [choices]) + }); + }, [choices]); return ( @@ -138,11 +169,7 @@ export default function DatasetResource({ borderColor="#DEDFE0" /> - + {fieldName} @@ -154,14 +181,16 @@ export default function DatasetResource({ cursor="pointer" pointerEvents={elm._id === value ? "none" : "default"} > - - ) + ); } - function SelectResource ({ selectedResource }) { - const { t } = useTranslation('dataset'); + function SelectResource({ selectedResource }) { + const { t } = useTranslation("dataset"); const [widthScreen, setWidthScreen] = useState(0); - const [value, setValue] = useState("") - const {table, raw_data_source, information_request} = selectedResource; + const [value, setValue] = useState(""); + const { table, raw_data_source, information_request } = selectedResource; const findResourceName = (source, id) => { - const resource = source.find(item => item._id === id); - return resource ? resource[`name${capitalize(locale)}`] || resource.name : ""; + const resource = source.find((item) => item._id === id); + return resource + ? resource[`name${capitalize(locale)}`] || resource.name + : ""; }; useEffect(() => { setValue( - table ? findResourceName(tables, table) : - raw_data_source ? findResourceName(rawDataSources, raw_data_source) : - information_request ? findResourceName(informationRequests, information_request) : "" + table + ? findResourceName(tables, table) + : raw_data_source + ? findResourceName(rawDataSources, raw_data_source) + : information_request + ? findResourceName(informationRequests, information_request) + : "", ); const updateWidthScreen = () => { - setWidthScreen(window.innerWidth - 48) - } + setWidthScreen(window.innerWidth - 48); + }; - updateWidthScreen() + updateWidthScreen(); - window.addEventListener('resize', updateWidthScreen) + window.addEventListener("resize", updateWidthScreen); return () => { - window.removeEventListener('resize', updateWidthScreen) - } + window.removeEventListener("resize", updateWidthScreen); + }; }, [table, raw_data_source, information_request]); return ( - - {t('selectResource')} + + {t("selectResource")} {value} - + @@ -278,7 +305,7 @@ export default function DatasetResource({ zIndex={100} boxShadow="0 1.6px 16px 0 rgba(100, 96, 103, 0.16)" > - {tables.length > 0 && + {tables.length > 0 && ( - {tables.map((elm, i) => {return ( - pushQuery("table", elm._id)} - > - {elm.name || elm.number} - - )})} - - } - - {rawDataSources.length > 0 && - <> - - - {rawDataSources.map((elm, i) => {return ( + {tables.map((elm, i) => { + return ( pushQuery("raw_data_source", elm._id)} + onClick={() => pushQuery("table", elm._id)} > {elm.name || elm.number} - )})} + ); + })} + + )} + + {rawDataSources.length > 0 && ( + <> + + + {rawDataSources.map((elm, i) => { + return ( + pushQuery("raw_data_source", elm._id)} + > + {elm.name || elm.number} + + ); + })} - } + )} - {informationRequests.length > 0 && + {informationRequests.length > 0 && ( <> - + - {informationRequests.map((elm, i) => {return ( - pushQuery("information_request", elm._id)} - > - {elm.name || elm.number} - - )})} + {informationRequests.map((elm, i) => { + return ( + pushQuery("information_request", elm._id)} + > + {elm.name || elm.number} + + ); + })} - } + )} - ) + ); } return ( @@ -407,50 +440,52 @@ export default function DatasetResource({ spacing={0} height="100%" > - {displayScreen === "desktop" ? + {displayScreen === "desktop" ? ( { - pushQuery("table", id) + pushQuery("table", id); }} hasDivider={false} /> { - pushQuery("raw_data_source", id) + pushQuery("raw_data_source", id); }} hasDivider={tables.length > 0 ? true : false} /> { - pushQuery("information_request", id) + pushQuery("information_request", id); }} - hasDivider={tables.length > 0 || rawDataSources.length > 0 ? true : false} + hasDivider={ + tables.length > 0 || rawDataSources.length > 0 ? true : false + } /> - : - - } + ) : ( + + )} - + - ) -} \ No newline at end of file + ); +} diff --git a/next/components/organisms/DatasetSearchCard.js b/next/components/organisms/DatasetSearchCard.js index 8a4fd28bb..9b48ec0dc 100644 --- a/next/components/organisms/DatasetSearchCard.js +++ b/next/components/organisms/DatasetSearchCard.js @@ -1,15 +1,8 @@ -import { - HStack, - Image, - Stack, - VStack, - Text, - Box -} from "@chakra-ui/react"; -import { useTranslation } from 'next-i18next'; +import { HStack, Image, Stack, VStack, Text, Box } from "@chakra-ui/react"; +import { useTranslation } from "next-i18next"; import { capitalize } from "lodash"; import { useCheckMobile } from "../../hooks/useCheckMobile.hook"; -import Link from '../atoms/Link'; +import Link from "../atoms/Link"; import TitleText from "../atoms/Text/TitleText"; import BodyText from "../atoms/Text/BodyText"; @@ -27,13 +20,13 @@ export default function Dataset({ rawDataSources, informationRequests, contains, - locale + locale, }) { - const { t } = useTranslation('dataset'); + const { t } = useTranslation("dataset"); const Tables = () => { - let tablesNumber = tables.number - if(tables.number === undefined) tablesNumber = 0 + let tablesNumber = tables.number; + if (tables.number === undefined) tablesNumber = 0; return ( - - + + {tablesNumber}{" "} - {tablesNumber === 1 ? t('datasetCard.table') : t('datasetCard.tables')} + {tablesNumber === 1 + ? t("datasetCard.table") + : t("datasetCard.tables")} - ) - } + ); + }; const RawDataSources = () => { - let rawDataSourcesNumber = rawDataSources.number - if(rawDataSources.number === undefined) rawDataSourcesNumber = 0 + let rawDataSourcesNumber = rawDataSources.number; + if (rawDataSources.number === undefined) rawDataSourcesNumber = 0; return ( 0 ? `/dataset/${id}?raw_data_source=${rawDataSources.id}` : "#"} + href={ + rawDataSourcesNumber > 0 + ? `/dataset/${id}?raw_data_source=${rawDataSources.id}` + : "#" + } > - - + + {rawDataSourcesNumber}{" "} - {rawDataSourcesNumber === 1 ? t('datasetCard.rawDataSource') : t('datasetCard.rawDataSources')} + {rawDataSourcesNumber === 1 + ? t("datasetCard.rawDataSource") + : t("datasetCard.rawDataSources")} - ) - } + ); + }; const InformationRequest = () => { - let informationRequestsNumber = informationRequests.number - if(informationRequests.number === undefined) informationRequestsNumber = 0 + let informationRequestsNumber = informationRequests.number; + if (informationRequests.number === undefined) informationRequestsNumber = 0; return ( 0 ? `/dataset/${id}?information_request=${informationRequests.id}` : "#"} + href={ + informationRequestsNumber > 0 + ? `/dataset/${id}?information_request=${informationRequests.id}` + : "#" + } > - + {informationRequestsNumber}{" "} - {informationRequestsNumber === 1 ? t('datasetCard.informationRequest') : t('datasetCard.informationRequests')} + {informationRequestsNumber === 1 + ? t("datasetCard.informationRequest") + : t("datasetCard.informationRequests")} - ) - } + ); + }; return ( - + {organizations[0]?.[`name${capitalize(locale)}`] @@ -184,17 +177,14 @@ export default function Dataset({ alignItems="flex-start" pb={{ base: 2, lg: 0 }} > - + {name} @@ -208,88 +198,58 @@ export default function Dataset({ marginBottom="4px !important" alignItems="flex-start" > - - - {t('organization')}: + + + {t("organization")}: - + - {organizations[0]?.[`name${capitalize(locale)}`] || organizations[0]?.name} + {organizations[0]?.[`name${capitalize(locale)}`] || + organizations[0]?.name} - - - {t('temporalCoverage')}: + + + {t("temporalCoverage")}: - - {temporalCoverageText ? temporalCoverageText : t('notProvided')} + + {temporalCoverageText + ? temporalCoverageText + : t("notProvided")} - {locale !== 'pt' ? - - - {t('spatialCoverage')}: + {locale !== "pt" ? ( + + + {t("spatialCoverage")}: - - {spatialCoverage ? spatialCoverage : t('notProvided')} + + {spatialCoverage ? spatialCoverage : t("notProvided")} - : + ) : ( <> - } + )} - - - {t('resources')}: + + + {t("resources")}: - - {contains.free && t('openData')} {contains.free && contains.pro && t('datasetCard.and')} {contains.pro && t('closedData')} - {!contains.free && !contains.pro && t('none')} + + {contains.free && t("openData")}{" "} + {contains.free && contains.pro && t("datasetCard.and")}{" "} + {contains.pro && t("closedData")} + {!contains.free && !contains.pro && t("none")} @@ -301,11 +261,13 @@ export default function Dataset({ spacing={informationRequests?.number > 0 ? 0 : 10} width="100%" maxWidth="440px" - justifyContent={informationRequests?.number > 0 ? "space-between" : "flex-start"} + justifyContent={ + informationRequests?.number > 0 ? "space-between" : "flex-start" + } > - - - {informationRequests?.number > 0 && } + + + {informationRequests?.number > 0 && } diff --git a/next/components/organisms/DatasetThemeCatalogCard.js b/next/components/organisms/DatasetThemeCatalogCard.js index 0c76ef0c1..c439af047 100644 --- a/next/components/organisms/DatasetThemeCatalogCard.js +++ b/next/components/organisms/DatasetThemeCatalogCard.js @@ -1,12 +1,5 @@ -import { - HStack, - VStack, - Center, - Text, - Tooltip, - Stack -} from "@chakra-ui/react"; -import { useTranslation } from 'next-i18next'; +import { HStack, VStack, Center, Text, Tooltip, Stack } from "@chakra-ui/react"; +import { useTranslation } from "next-i18next"; import { capitalize } from "lodash"; import Card from "../molecules/Card"; import { CategoryIcon } from "../atoms/CategoryIcon"; @@ -24,53 +17,55 @@ export default function DatasetCard({ link, locale, }) { - const { t } = useTranslation('dataset'); + const { t } = useTranslation("dataset"); return ( ( - -
( + - - - -
-
- )), - ]} + + + + + + )), + ] + } spacing={0} > @@ -91,29 +86,31 @@ export default function DatasetCard({ textOverflow="ellipsis" color="#71757A" > - {organizations?.[0]?.[`name${capitalize(locale)}`] || organizations?.[0]?.name || organizations?.[0]?.slug} + {organizations?.[0]?.[`name${capitalize(locale)}`] || + organizations?.[0]?.name || + organizations?.[0]?.slug} - - {tags.length !== 0 && tags.slice(0,3).map((t, i) => ( - - ))} + + {tags.length !== 0 && + tags + .slice(0, 3) + .map((t, i) => ( + + ))} - { - tables?.number === 0 ? - t('datasetCard.noRawDataSources') - : - tables?.number === 1 ? - t('datasetCard.oneTable') - : - t('datasetCard.multipleTables', { count: tables?.number || 0 }) + color={ + tables?.number === undefined || tables?.number === 0 + ? "#C4C4C4" + : "#2B8C4D" } + _hover={{ color: "#22703E" }} + > + {tables?.number === 0 + ? t("datasetCard.noRawDataSources") + : tables?.number === 1 + ? t("datasetCard.oneTable") + : t("datasetCard.multipleTables", { + count: tables?.number || 0, + })} @@ -172,30 +171,37 @@ export default function DatasetCard({ pointerEvents={rawDataSources?.number > 0 ? "default" : "none"} > 0 ? `${link}?raw_data_source=${rawDataSources?.id}` : ""} + href={ + rawDataSources?.number > 0 + ? `${link}?raw_data_source=${rawDataSources?.id}` + : "" + } target="_blank" display="flex" fontWeight="500" fontSize="12px" lineHeight="18px" letterSpacing="0.1px" - color={rawDataSources?.number === undefined || rawDataSources?.number === 0 ? "#C4C4C4" : "#2B8C4D"} - _hover={{color: "#22703E"}} - > - { - rawDataSources.number === 0 ? - t('datasetCard.noRawDataSources') - : - rawDataSources.number === 1 ? - t('datasetCard.oneRawDataSource') - : - t('datasetCard.multipleRawDataSources', { count: rawDataSources.number }) + color={ + rawDataSources?.number === undefined || + rawDataSources?.number === 0 + ? "#C4C4C4" + : "#2B8C4D" } + _hover={{ color: "#22703E" }} + > + {rawDataSources.number === 0 + ? t("datasetCard.noRawDataSources") + : rawDataSources.number === 1 + ? t("datasetCard.oneRawDataSource") + : t("datasetCard.multipleRawDataSources", { + count: rawDataSources.number, + })}
- ) + ); } diff --git a/next/components/organisms/DatasetUserGuide.js b/next/components/organisms/DatasetUserGuide.js index cdcca6447..c68b154cd 100644 --- a/next/components/organisms/DatasetUserGuide.js +++ b/next/components/organisms/DatasetUserGuide.js @@ -18,7 +18,7 @@ import { } from "@chakra-ui/react"; import { useEffect, useRef, useState } from "react"; import { MDXRemote } from "next-mdx-remote"; -import { useTranslation } from 'next-i18next'; +import { useTranslation } from "next-i18next"; import Button from "../atoms/Button"; import TitleText from "../atoms/Text/TitleText"; import LabelText from "../atoms/Text/LabelText"; @@ -27,7 +27,7 @@ import Link from "../atoms/Link"; import InfoIcon from "../../public/img/icons/infoIcon"; function Toc({ headings }) { - const { t } = useTranslation('dataset'); + const { t } = useTranslation("dataset"); const [isOverflow, setIsOverflow] = useState({}); const textRefs = useRef({}); const [activeId, setActiveId] = useState(null); @@ -43,14 +43,14 @@ function Toc({ headings }) { }; headings.forEach((elm, i) => { - const textElement = textRefs.current[i] + const textElement = textRefs.current[i]; if (textElement) { setIsOverflow((prev) => ({ ...prev, [i]: textElement.scrollWidth > textElement.clientWidth, - })) + })); } - }) + }); const observerOptions = { root: null, @@ -58,11 +58,14 @@ function Toc({ headings }) { threshold: 0.5, }; - const observer = new IntersectionObserver(observerCallback, observerOptions); + const observer = new IntersectionObserver( + observerCallback, + observerOptions, + ); observerRef.current = observer; const headingElements = document.querySelectorAll( - headings.map(({ id }) => `#${id}`).join(", ") + headings.map(({ id }) => `#${id}`).join(", "), ); headingElements.forEach((element) => observer.observe(element)); @@ -72,15 +75,11 @@ function Toc({ headings }) { }; }, [headings]); - if(headings.length === 0) return null + if (headings.length === 0) return null; return ( - + {t("tableContents")} @@ -92,7 +91,7 @@ function Toc({ headings }) { cursor="pointer" pointerEvents={id === activeId ? "none" : "default"} > - , - h2: (props) => , - h3: (props) => , - h4: (props) => , - h5: (props) => , - h6: (props) => , + h2: (props) => ( + + ), + h3: (props) => ( + + ), + h4: (props) => ( + + ), + h5: (props) => ( + + ), + h6: (props) => ( + + ), blockquote: (props) => ( - - + + ), a: (props) => ( - + ), hr: (props) => (
- + {figcaption ? ( - + ) : null}
); @@ -335,28 +328,27 @@ export const mdxComponents = { }; export default function DatasetUserGuide({ data, locale = "pt", slug }) { - const { t } = useTranslation('dataset'); - const [mdxSource] = useState(data?.mdxSource || null) - const [hasGuide] = useState(!!data?.mdxSource?.frontmatter?.title) + const { t } = useTranslation("dataset"); + const [mdxSource] = useState(data?.mdxSource || null); + const [hasGuide] = useState(!!data?.mdxSource?.frontmatter?.title); const repository = () => { - const baseUrl = process.env.NEXT_PUBLIC_BASE_URL_FRONTEND - if (baseUrl === "http://localhost:3000" || baseUrl === "https://development.basedosdados.org") return "development" - if (baseUrl === "https://staging.basedosdados.org") return "staging" - if (baseUrl === "https://basedosdados.org") return "main" - return null - } + const baseUrl = process.env.NEXT_PUBLIC_BASE_URL_FRONTEND; + if ( + baseUrl === "http://localhost:3000" || + baseUrl === "https://development.basedosdados.org" + ) + return "development"; + if (baseUrl === "https://staging.basedosdados.org") return "staging"; + if (baseUrl === "https://basedosdados.org") return "main"; + return null; + }; return ( - - {data?.headings.length > 0 && + + {data?.headings.length > 0 && ( - } + )} {mdxSource && } - + - {hasGuide ? t("gotAnyQuestionsGuide") : t("notHaveUserGuide")} - {t("contributeToTheUsageGuide")} + + {hasGuide ? t("gotAnyQuestionsGuide") : t("notHaveUserGuide")} + + + {t("contributeToTheUsageGuide")} + - {t('informationRequest.description')} + {t("informationRequest.description")} @@ -205,23 +195,28 @@ export default function InformationRequestPage({ id, isBDSudo }) { isLoaded={!isLoading} > - {resource?.[`observations${capitalize(locale)}`] || resource?.observations || t('informationRequest.notProvided')} + {resource?.[`observations${capitalize(locale)}`] || + resource?.observations || + t("informationRequest.notProvided")} - + - {t('informationRequest.additionalInformation')} + {t("informationRequest.additionalInformation")} - ) + ); } diff --git a/next/components/organisms/PaymentSystem.js b/next/components/organisms/PaymentSystem.js index ee0c1dd61..f51b0f568 100644 --- a/next/components/organisms/PaymentSystem.js +++ b/next/components/organisms/PaymentSystem.js @@ -1,11 +1,6 @@ -import { - Stack, - VStack, - Skeleton, - Spinner, -} from "@chakra-ui/react" -import { useState, useEffect } from 'react'; -import { loadStripe } from '@stripe/stripe-js'; +import { Stack, VStack, Skeleton, Spinner } from "@chakra-ui/react"; +import { useState, useEffect } from "react"; +import { loadStripe } from "@stripe/stripe-js"; import { Elements, PaymentElement, @@ -14,56 +9,48 @@ import { } from "@stripe/react-stripe-js"; import Button from "../atoms/Button"; import styles from "../../styles/paymentSystem.module.css"; -import { useTranslation } from 'next-i18next'; +import { useTranslation } from "next-i18next"; -const stripePromise = loadStripe(process.env.NEXT_PUBLIC_KEY_STRIPE) +const stripePromise = loadStripe(process.env.NEXT_PUBLIC_KEY_STRIPE); -const PaymentForm = ({ onSucess, onErro, clientSecret}) => { - const { t } = useTranslation('user'); - const [isLoading, setIsLoading] = useState(false) - const stripe = useStripe() - const elements = useElements() +const PaymentForm = ({ onSucess, onErro, clientSecret }) => { + const { t } = useTranslation("user"); + const [isLoading, setIsLoading] = useState(false); + const stripe = useStripe(); + const elements = useElements(); const handlerSubmit = async (e) => { - setIsLoading(true) - e.preventDefault() + setIsLoading(true); + e.preventDefault(); - const isSetupIntent = clientSecret.startsWith('seti_'); + const isSetupIntent = clientSecret.startsWith("seti_"); if (isSetupIntent) { await elements.submit(); const data = await stripe.confirmSetup({ elements, clientSecret: clientSecret, - redirect: 'if_required', + redirect: "if_required", }); - + if (data?.error?.code === "card_declined") return onErro(); if (data?.setupIntent?.status === "succeeded") return onSucess(); - } else { const data = await stripe.confirmPayment({ elements, - redirect: 'if_required', - }) - - if(data?.error?.code === "card_declined") return onErro() - if(data?.paymentIntent?.status === "succeeded") return onSucess() + redirect: "if_required", + }); + + if (data?.error?.code === "card_declined") return onErro(); + if (data?.paymentIntent?.status === "succeeded") return onSucess(); } - setIsLoading(false) - } + setIsLoading(false); + }; return ( - -
- + + + - ) -} + ); +}; export default function PaymentSystem({ userData, @@ -86,14 +73,14 @@ export default function PaymentSystem({ coupon, onSucess, onErro, - isLoading + isLoading, }) { - const [clientSecret, setClientSecret] = useState("") + const [clientSecret, setClientSecret] = useState(""); const appearance = { theme: "stripe", variables: { - fontFamily: 'Roboto, sans-serif', + fontFamily: "Roboto, sans-serif", fontSizeBase: "16px", fontSizeSm: "16px", borderRadius: "14px", @@ -107,18 +94,18 @@ export default function PaymentSystem({ ".Input": { borderRadius: "8px", border: "2px solid #EEEEEE", - backgroundColor: "#EEEEEE" + backgroundColor: "#EEEEEE", }, ".Input:hover": { - backgroundColor:"#DEDFE0", - borderColor: "#DEDFE0" + backgroundColor: "#DEDFE0", + borderColor: "#DEDFE0", }, ".Input:focus": { backgroundColor: "#FFFFFF", - border:"2px solid #0068C5", + border: "2px solid #0068C5", borderColor: "#0068C5", boxShadow: "none", - outline: "none" + outline: "none", }, ".Input:focus:hover": { backgroundColor: "#FFFFFF", @@ -127,79 +114,137 @@ export default function PaymentSystem({ ".Tab": { border: "2px solid #ececec", backgroundColor: "#FFF", - boxShadow: "none" + boxShadow: "none", }, ".Tab:focus": { - boxShadow: "none" + boxShadow: "none", }, ".Tab--selected": { - boxShadow: "none" + boxShadow: "none", }, ".Tab--selected:focus": { - boxShadow: "none" - } - } - } + boxShadow: "none", + }, + }, + }; const options = { clientSecret, appearance, - fonts: [{ cssSrc: 'https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap' }], - } + fonts: [ + { + cssSrc: + "https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap", + }, + ], + }; const customerCreatPost = async (id, coupon) => { - const clientSecret = await fetch(`/api/stripe/createSubscription?p=${btoa(id)}&c=${btoa(coupon)}`, {method: "GET"}) - .then(res => res.json()) + const clientSecret = await fetch( + `/api/stripe/createSubscription?p=${btoa(id)}&c=${btoa(coupon)}`, + { method: "GET" }, + ).then((res) => res.json()); if (clientSecret) { - setClientSecret(clientSecret) - return isLoading(false) + setClientSecret(clientSecret); + return isLoading(false); } - } + }; useEffect(() => { - setClientSecret("") - isLoading(true) - customerCreatPost(plan, coupon) - }, [plan, coupon]) + setClientSecret(""); + isLoading(true); + customerCreatPost(plan, coupon); + }, [plan, coupon]); const SkeletonBox = ({ type, ...props }) => { - if(type === "text") return - if(type === "box") return - if(type === "smallBox") return - if(type === "bnt") return - } - - if(!clientSecret) return ( - - - - - - - - - + if (type === "text") + return ( + + ); + if (type === "box") + return ( + + ); + if (type === "smallBox") + return ( + + ); + if (type === "bnt") + return ( + + ); + }; + + if (!clientSecret) + return ( + + + + + + + + + + - - - + + - - - - - - - - + + + + + + + + + - - - - ) + + + ); return ( @@ -210,5 +255,5 @@ export default function PaymentSystem({ onErro={onErro} /> - ) + ); } diff --git a/next/components/organisms/RawDataSourcesPage.js b/next/components/organisms/RawDataSourcesPage.js index 80cee33c0..aec379612 100644 --- a/next/components/organisms/RawDataSourcesPage.js +++ b/next/components/organisms/RawDataSourcesPage.js @@ -4,11 +4,11 @@ import { Skeleton, SkeletonText, Tooltip, - Divider + Divider, } from "@chakra-ui/react"; import { useState, useEffect } from "react"; -import { useTranslation } from 'next-i18next'; -import { useRouter } from 'next/router'; +import { useTranslation } from "next-i18next"; +import { useRouter } from "next/router"; import { capitalize } from "lodash"; import Button from "../atoms/Button"; @@ -20,79 +20,84 @@ import ObservationLevel from "../atoms/ObservationLevelTable"; import { AlertDiscalimerBox } from "../molecules/DisclaimerBox"; import FourOFour from "../templates/404"; -import RedirectIcon from "../../public/img/icons/redirectIcon" +import RedirectIcon from "../../public/img/icons/redirectIcon"; import InfoIcon from "../../public/img/icons/infoIcon"; export default function RawDataSourcesPage({ id, isBDSudo }) { - const { t } = useTranslation('dataset'); + const { t } = useTranslation("dataset"); const router = useRouter(); const { locale } = router; - const [isLoading, setIsLoading] = useState(true) - const [resource, setResource] = useState({}) - const [isError, setIsError] = useState(false) + const [isLoading, setIsLoading] = useState(true); + const [resource, setResource] = useState({}); + const [isError, setIsError] = useState(false); useEffect(() => { const fetchRawDataSources = async () => { - setIsLoading(true) + setIsLoading(true); try { const url = `/api/rawDataSources/getRawDataSource?id=${id}&locale=${locale}`; - const response = await fetch(url, { method: "GET" }) - const result = await response.json() + const response = await fetch(url, { method: "GET" }); + const result = await response.json(); if (result.success) { - const statusName = result?.resource?.status?.slug || "" - if(statusName === "under_review" || statusName === "excluded" && isBDSudo === false) { - setIsError(true) + const statusName = result?.resource?.status?.slug || ""; + if ( + statusName === "under_review" || + (statusName === "excluded" && isBDSudo === false) + ) { + setIsError(true); } else { - setResource(result.resource) - setIsError(false) + setResource(result.resource); + setIsError(false); } } else { - console.error(result.error) - setIsError(true) + console.error(result.error); + setIsError(true); } } catch (error) { - console.error("Fetch error: ", error) - setIsError(true) + console.error("Fetch error: ", error); + setIsError(true); } finally { - setIsLoading(false) + setIsLoading(false); } - } + }; - fetchRawDataSources() - }, [id, locale]) + fetchRawDataSources(); + }, [id, locale]); const ObjectValues = (value) => { - if(value === undefined || Object.keys(value).length === 0) return t('rawDataSource.notProvided') + if (value === undefined || Object.keys(value).length === 0) + return t("rawDataSource.notProvided"); - const array = [] + const array = []; Object.values(value).map((elm) => { - const translatedName = elm[`name${capitalize(locale)}`] || elm.name - array.push(translatedName) - }) + const translatedName = elm[`name${capitalize(locale)}`] || elm.name; + array.push(translatedName); + }); - if(array.length === 0) return t('rawDataSource.notProvided') - return array.join(", ").toString() - } + if (array.length === 0) return t("rawDataSource.notProvided"); + return array.join(", ").toString(); + }; const TrueOrFalse = (value) => { switch (value) { case true: - return t('rawDataSource.yes') + return t("rawDataSource.yes"); break; case false: - return t('rawDataSource.no') + return t("rawDataSource.no"); break; default: - return t('rawDataSource.notProvided') + return t("rawDataSource.notProvided"); break; } - } + }; const UpdateFrequency = () => { const value = resource?.updates?.[0]; - if (!value || Object.keys(value).length === 0) return t('rawDataSource.notProvided'); + if (!value || Object.keys(value).length === 0) + return t("rawDataSource.notProvided"); const localizedName = value.entity[`name${capitalize(locale)}`]; const defaultName = value.entity.name; @@ -104,8 +109,8 @@ export default function RawDataSourcesPage({ id, isBDSudo }) { return `${localizedName || defaultName}`; } - return t('rawDataSource.notProvided'); - } + return t("rawDataSource.notProvided"); + }; const TooltipText = ({ text, info, ...props }) => { return ( @@ -145,8 +150,8 @@ export default function RawDataSourcesPage({ id, isBDSudo }) { - ) - } + ); + }; const StackSkeleton = ({ children, ...props }) => { return ( @@ -161,8 +166,8 @@ export default function RawDataSourcesPage({ id, isBDSudo }) { > {children} - ) - } + ); + }; const AddInfoTextBase = ({ title, text, ...props }) => { return ( @@ -180,21 +185,20 @@ export default function RawDataSourcesPage({ id, isBDSudo }) { {...props} > {title} - {text || t('rawDataSource.notProvided')} + + {text || t("rawDataSource.notProvided")} + - ) - } + ); + }; - if(isError) return + if (isError) return ; return ( - {t('rawDataSource.rawDataDisclaimer')} + {t("rawDataSource.rawDataDisclaimer")} @@ -237,21 +241,18 @@ export default function RawDataSourcesPage({ id, isBDSudo }) { backgroundColor={resource?.url ? "#2B8C4D" : "#ACAEB1"} cursor={resource?.url ? "pointer" : "default"} _hover={{ - backgroundColor: resource?.url ? "#22703E" : "#ACAEB1" + backgroundColor: resource?.url ? "#22703E" : "#ACAEB1", }} > - {t('rawDataSource.accessOriginalSource')} - + {t("rawDataSource.accessOriginalSource")} + - {t('rawDataSource.description')} + {t("rawDataSource.description")} @@ -268,49 +269,51 @@ export default function RawDataSourcesPage({ id, isBDSudo }) { isLoaded={!isLoading} > - {resource?.[`description${capitalize(locale)}`] || resource?.description || t('rawDataSource.notProvided')} + {resource?.[`description${capitalize(locale)}`] || + resource?.description || + t("rawDataSource.notProvided")} - + - {t('rawDataSource.additionalInfo')} + {t("rawDataSource.additionalInfo")} @@ -323,33 +326,31 @@ export default function RawDataSourcesPage({ id, isBDSudo }) { width="100%" isLoaded={!isLoading} > - {resource?.observationLevels && Object.keys(resource?.observationLevels).length > 0 ? - - : - - {t('rawDataSource.notProvided')} + {resource?.observationLevels && + Object.keys(resource?.observationLevels).length > 0 ? ( + + ) : ( + + {t("rawDataSource.notProvided")} - } - + )} +
- ) + ); } diff --git a/next/components/organisms/TablePage.js b/next/components/organisms/TablePage.js index 1858bf55a..883808c6e 100644 --- a/next/components/organisms/TablePage.js +++ b/next/components/organisms/TablePage.js @@ -8,9 +8,9 @@ import { Tooltip, } from "@chakra-ui/react"; import { useState, useEffect } from "react"; -import { useTranslation } from 'next-i18next'; -import { useRouter } from 'next/router'; -import { capitalize } from 'lodash'; +import { useTranslation } from "next-i18next"; +import { useRouter } from "next/router"; +import { capitalize } from "lodash"; import { formatBytes } from "../../utils"; import Link from "../atoms/Link"; import ReadMore from "../atoms/ReadMore"; @@ -31,42 +31,48 @@ import DownloadIcon from "../../public/img/icons/downloadIcon"; import RedirectIcon from "../../public/img/icons/redirectIcon"; export default function TablePage({ id, isBDSudo }) { - const { t } = useTranslation('dataset', 'prices'); + const { t } = useTranslation("dataset", "prices"); const router = useRouter(); const { locale } = router; - const [isLoading, setIsLoading] = useState(true) - const [resource, setResource] = useState({}) - const [isError, setIsError] = useState(false) + const [isLoading, setIsLoading] = useState(true); + const [resource, setResource] = useState({}); + const [isError, setIsError] = useState(false); useEffect(() => { const fetchData = async () => { try { - const response = await fetch(`/api/tables/getTable?id=${id}&locale=${locale}`, { method: "GET" }) - const result = await response.json() + const response = await fetch( + `/api/tables/getTable?id=${id}&locale=${locale}`, + { method: "GET" }, + ); + const result = await response.json(); if (result.success) { - const statusName = result?.resource?.status?.slug || "" - if(statusName === "under_review" || statusName === "excluded" && isBDSudo === false) { + const statusName = result?.resource?.status?.slug || ""; + if ( + statusName === "under_review" || + (statusName === "excluded" && isBDSudo === false) + ) { setIsError(true); } else { setResource(result.resource); setIsError(false); } } else { - console.error(result.error) - setIsError(true) + console.error(result.error); + setIsError(true); } } catch (error) { - console.error("Fetch error: ", error) - setIsError(true) + console.error("Fetch error: ", error); + setIsError(true); } finally { - setIsLoading(false) + setIsLoading(false); } - } + }; setIsLoading(true); fetchData(); - }, [id, locale]) + }, [id, locale]); const TooltipText = ({ text, info, ...props }) => { return ( @@ -107,55 +113,67 @@ export default function TablePage({ id, isBDSudo }) { - ) - } + ); + }; const keyIcons = (ref) => { - let href = "" - let alt = "" + let href = ""; + let alt = ""; - if(ref.github_user) { - const github = ref.github_user.replace(/(https:)\/\/(github.com)\//gim, "") - href = `https://github.com/${github}` - alt = "github basedosdados" + if (ref.github_user) { + const github = ref.github_user.replace( + /(https:)\/\/(github.com)\//gim, + "", + ); + href = `https://github.com/${github}`; + alt = "github basedosdados"; } - if(ref.twitter_user) { - const twitter = ref.twitter_user.replace(/(https:)\/\/(twitter.com)\//gim, "") - href = `https://x.com/${twitter}` - alt = "twitter basedosdados" + if (ref.twitter_user) { + const twitter = ref.twitter_user.replace( + /(https:)\/\/(twitter.com)\//gim, + "", + ); + href = `https://x.com/${twitter}`; + alt = "twitter basedosdados"; } - if(ref.email) { - href = `mailto:${ref.email}` - alt= "email do contribuidor" + if (ref.email) { + href = `mailto:${ref.email}`; + alt = "email do contribuidor"; } - if(ref.website) { - const website = ref.website.replace(/(https?:)\/\//gim, "") - href = `https://${website}` - alt = "website pessoal" + if (ref.website) { + const website = ref.website.replace(/(https?:)\/\//gim, ""); + href = `https://${website}`; + alt = "website pessoal"; } return { alt: alt, cursor: "pointer", - width:"20px", - height:"20px", + width: "20px", + height: "20px", fill: "#0068C5", _hover: { - fill: "#0057A4" + fill: "#0057A4", }, - onClick: () => {router.push(href)} - } - } + onClick: () => { + router.push(href); + }, + }; + }; const PublishedOrDataCleanedBy = ({ resource }) => { - if (!resource || typeof resource !== 'object' || Object.keys(resource).length === 0) { + if ( + !resource || + typeof resource !== "object" || + Object.keys(resource).length === 0 + ) { return ( - {t('table.notProvided')} + {t("table.notProvided")} ); } @@ -171,15 +189,22 @@ export default function TablePage({ id, isBDSudo }) { marginRight="4px !important" color="#464A51" > - {person?.firstName && person?.lastName + {person?.firstName && person?.lastName ? `${person.firstName} ${person.lastName}` - : t('table.notProvided') - } + : t("table.notProvided")} - {person?.email && } - {person?.github && } - {person?.website && } - {person?.twitter && } + {person?.email && ( + + )} + {person?.github && ( + + )} + {person?.website && ( + + )} + {person?.twitter && ( + + )} ))} @@ -199,79 +224,77 @@ export default function TablePage({ id, isBDSudo }) { > {children} - ) - } + ); + }; const formatDate = (value) => { const date = new Date(value); - const formattedDate = date.getFullYear()+"-"+String(date.getMonth() + 1).padStart(2, "0")+"-"+String(date.getDate()).padStart(2, "0") - return formattedDate - } + const formattedDate = + date.getFullYear() + + "-" + + String(date.getMonth() + 1).padStart(2, "0") + + "-" + + String(date.getDate()).padStart(2, "0"); + return formattedDate; + }; const getUpdateFormat = (value, yearFrequency = false, frequency) => { - let formats - {yearFrequency ? - formats = { - "second":`${t('table.updateEvery')} ${frequency} ${t('table.seconds')}`, - "minute":`${t('table.updateEvery')} ${frequency} ${t('table.minutes')}`, - "hour":`${t('table.updateEvery')} ${frequency} ${t('table.hours')}`, - "day":`${t('table.updateEvery')} ${frequency} ${t('table.days')}`, - "week":`${t('table.updateEvery')} ${frequency} ${t('table.weeks')}`, - "month":`${t('table.updateEvery')} ${frequency} ${t('table.months')}`, - "bimester":`${t('table.updateEvery')} ${frequency} ${t('table.bimonths')}`, - "quarter":`${t('table.updateEvery')} ${frequency} ${t('table.quarters')}`, - "semester":`${t('table.updateEvery')} ${frequency} ${t('table.semesters')}`, - "year":`${t('table.updateEvery')} ${frequency} ${t('table.years')}`, - } - : - formats = { - "second":t('table.updatePerSecond'), - "minute":t('table.updatePerMinute'), - "hour":t('table.updatePerHour'), - "day":t('table.dailyUpdate'), - "week":t('table.weeklyUpdate'), - "month":t('table.monthlyUpdate'), - "bimester":t('table.bimonthlyUpdate'), - "quarter":t('table.quarterlyUpdate'), - "semester":t('table.semiannualUpdate'), - "year":t('table.annualUpdate'), - } + let formats; + { + yearFrequency + ? (formats = { + second: `${t("table.updateEvery")} ${frequency} ${t("table.seconds")}`, + minute: `${t("table.updateEvery")} ${frequency} ${t("table.minutes")}`, + hour: `${t("table.updateEvery")} ${frequency} ${t("table.hours")}`, + day: `${t("table.updateEvery")} ${frequency} ${t("table.days")}`, + week: `${t("table.updateEvery")} ${frequency} ${t("table.weeks")}`, + month: `${t("table.updateEvery")} ${frequency} ${t("table.months")}`, + bimester: `${t("table.updateEvery")} ${frequency} ${t("table.bimonths")}`, + quarter: `${t("table.updateEvery")} ${frequency} ${t("table.quarters")}`, + semester: `${t("table.updateEvery")} ${frequency} ${t("table.semesters")}`, + year: `${t("table.updateEvery")} ${frequency} ${t("table.years")}`, + }) + : (formats = { + second: t("table.updatePerSecond"), + minute: t("table.updatePerMinute"), + hour: t("table.updatePerHour"), + day: t("table.dailyUpdate"), + week: t("table.weeklyUpdate"), + month: t("table.monthlyUpdate"), + bimester: t("table.bimonthlyUpdate"), + quarter: t("table.quarterlyUpdate"), + semester: t("table.semiannualUpdate"), + year: t("table.annualUpdate"), + }); } - return formats[value] ? formats[value] : t('table.updateNotDefined') - } + return formats[value] ? formats[value] : t("table.updateNotDefined"); + }; + + if (isError) return ; - if (isError) return ; - return ( - + {resource?.[`name${capitalize(locale)}`] || resource?.name} - {resource?.uncompressedFileSize && - + {resource?.uncompressedFileSize && ( + {`(${formatBytes(resource.uncompressedFileSize)})`} - } + )} - {resource?.[`description${capitalize(locale)}`] || resource?.description || t('table.notProvided')} + {resource?.[`description${capitalize(locale)}`] || + resource?.description || + t("table.notProvided")} - {t('table.temporalCoverage')} + {t("table.temporalCoverage")} @@ -303,54 +328,53 @@ export default function TablePage({ id, isBDSudo }) { width="100%" height={!isLoading ? "fit-content" : "65px"} > - + - {locale !== 'pt' ? - + {locale !== "pt" ? ( + - {t('table.spatialCoverage')} + {t("table.spatialCoverage")} - + {resource?.[`spatialCoverageName${capitalize(locale)}`] - ? Object.values(resource[`spatialCoverageName${capitalize(locale)}`]) + ? Object.values( + resource[`spatialCoverageName${capitalize(locale)}`], + ) .sort((a, b) => a.localeCompare(b, locale)) - .join(', ') - : t('table.notProvided')} + .join(", ") + : t("table.notProvided")} - : + ) : ( <> - } + )} - - {t('table.dataAccess')} - + {t("table.dataAccess")} - + - {t('table.dataUpdateFrequency')} + {t("table.dataUpdateFrequency")} @@ -366,8 +390,8 @@ export default function TablePage({ id, isBDSudo }) { > - {resource?.updates?.[0]?.latest ? - `${formatDate(resource.updates[0].latest)}` - : - t('table.notProvided') - }: {t('table.lastUpdateBD')} - {resource?.updates?.[0]?.frequency && + {resource?.updates?.[0]?.latest + ? `${formatDate(resource.updates[0].latest)}` + : t("table.notProvided")} + : {t("table.lastUpdateBD")} + {resource?.updates?.[0]?.frequency && ( - {resource?.updates?.[0]?.frequency === 1 ? - getUpdateFormat(resource.updates[0].entity.slug) - : - getUpdateFormat(resource.updates[0].entity.slug, true, resource?.updates?.[0]?.frequency) - } + {resource?.updates?.[0]?.frequency === 1 + ? getUpdateFormat(resource.updates[0].entity.slug) + : getUpdateFormat( + resource.updates[0].entity.slug, + true, + resource?.updates?.[0]?.frequency, + )} - } - {!resource?.updates?.[0]?.frequency && + )} + {!resource?.updates?.[0]?.frequency && ( - {t('table.noUpdateScheduled')} + {t("table.noUpdateScheduled")} - } + )} - {resource?.rawDataSource?.[0]?.updates?.[0]?.latest ? - `${formatDate(resource.rawDataSource[0].updates[0].latest)}` - : - t('table.notProvided') - }: {t('table.lastUpdateRawDataSource')} - {resource?.rawDataSource?.[0]?.updates?.[0]?.frequency ? + {resource?.rawDataSource?.[0]?.updates?.[0]?.latest + ? `${formatDate(resource.rawDataSource[0].updates[0].latest)}` + : t("table.notProvided")} + : {t("table.lastUpdateRawDataSource")} + {resource?.rawDataSource?.[0]?.updates?.[0]?.frequency ? ( - {resource?.rawDataSource?.[0]?.updates?.[0]?.frequency === 1 ? - getUpdateFormat(resource?.rawDataSource?.[0]?.updates?.[0]?.entity?.slug) - : - getUpdateFormat(resource?.rawDataSource?.[0]?.updates?.[0]?.entity?.slug, true, resource?.rawDataSource?.[0]?.updates?.[0]?.frequency) - } + {resource?.rawDataSource?.[0]?.updates?.[0]?.frequency === 1 + ? getUpdateFormat( + resource?.rawDataSource?.[0]?.updates?.[0]?.entity?.slug, + ) + : getUpdateFormat( + resource?.rawDataSource?.[0]?.updates?.[0]?.entity?.slug, + true, + resource?.rawDataSource?.[0]?.updates?.[0]?.frequency, + )} - : - !resource?.rawDataSource?.[0]?.updates?.[0] || !resource?.updates?.[0]?.frequency ? + ) : !resource?.rawDataSource?.[0]?.updates?.[0] || + !resource?.updates?.[0]?.frequency ? ( - {t('table.noUpdateScheduled')} + {t("table.noUpdateScheduled")} - : + ) : ( <> - } + )} - {resource?.rawDataSource?.[0]?.polls?.[0]?.latest ? - `${formatDate(resource.rawDataSource[0].polls[0].latest)}` - : - t('table.notProvided') - }: {t('table.lastCheckRawDataSource')} + {resource?.rawDataSource?.[0]?.polls?.[0]?.latest + ? `${formatDate(resource.rawDataSource[0].polls[0].latest)}` + : t("table.notProvided")} + : {t("table.lastCheckRawDataSource")} - - {t('table.bigQueryID')} - + {t("table.bigQueryID")} - {!resource?.cloudTables ? - t('table.notProvided') - : - resource?.cloudTables?.[0]?.gcpProjectId+"."+resource?.cloudTables?.[0]?.gcpDatasetId+"."+resource?.cloudTables?.[0]?.gcpTableId - } + {!resource?.cloudTables + ? t("table.notProvided") + : resource?.cloudTables?.[0]?.gcpProjectId + + "." + + resource?.cloudTables?.[0]?.gcpDatasetId + + "." + + resource?.cloudTables?.[0]?.gcpTableId} - - - {resource?.partitions ? resource.partitions : t('table.notProvided')} + + {resource?.partitions + ? resource.partitions + : t("table.notProvided")} @@ -550,17 +575,15 @@ export default function TablePage({ id, isBDSudo }) { width="100%" isLoaded={!isLoading} > - {resource?.observationLevels && Object.keys(resource?.observationLevels).length > 0 ? - - : - - {t('table.notProvided')} + {resource?.observationLevels && + Object.keys(resource?.observationLevels).length > 0 ? ( + + ) : ( + + {t("table.notProvided")} - } - + )} + @@ -571,14 +594,11 @@ export default function TablePage({ id, isBDSudo }) { /> - - {resource?.auxiliaryFilesUrl ? + + {resource?.auxiliaryFilesUrl ? ( - {t('table.downloadFiles')} - + {t("table.downloadFiles")} + - : - t('table.notProvided') - } - + ) : ( + t("table.notProvided") + )} + @@ -613,47 +630,42 @@ export default function TablePage({ id, isBDSudo }) { - - {resource?.rawDataSource?.[0]?._id ? - Object.values(resource?.rawDataSource).map((elm, i) => { - return ( - - {elm?.[`name${capitalize(locale)}`] || elm?.name} - - ) - }) - : - t('table.notProvided') - } + + {resource?.rawDataSource?.[0]?._id + ? Object.values(resource?.rawDataSource).map((elm, i) => { + return ( + + {elm?.[`name${capitalize(locale)}`] || elm?.name} + + ); + }) + : t("table.notProvided")} - + - + - {t('table.additionalInformation')} + {t("table.additionalInformation")} @@ -661,7 +673,7 @@ export default function TablePage({ id, isBDSudo }) { startColor="#F0F0F0" endColor="#F3F3F3" borderRadius="6px" - width={resource?.publishedByInfo ? "100%" :"200px"} + width={resource?.publishedByInfo ? "100%" : "200px"} minHeight="40px" spacing="4px" skeletonHeight="16px" @@ -669,9 +681,9 @@ export default function TablePage({ id, isBDSudo }) { marginBottom="24px !important" isLoaded={!isLoading} > - {t('table.publishedBy')} + {t("table.publishedBy")} @@ -687,9 +699,9 @@ export default function TablePage({ id, isBDSudo }) { marginBottom="24px !important" isLoaded={!isLoading} > - {t('table.dataCleanedBy')} + {t("table.dataCleanedBy")} @@ -705,12 +717,11 @@ export default function TablePage({ id, isBDSudo }) { marginBottom="24px !important" isLoaded={!isLoading} > - {t('table.version')} - {resource?.version || t('table.notProvided')} + {t("table.version")} + + {resource?.version || t("table.notProvided")} + - ) + ); } diff --git a/next/components/organisms/componentsUserPage/Accesses.js b/next/components/organisms/componentsUserPage/Accesses.js index 871af1452..526fcbee2 100644 --- a/next/components/organisms/componentsUserPage/Accesses.js +++ b/next/components/organisms/componentsUserPage/Accesses.js @@ -8,7 +8,7 @@ import { Tooltip, useDisclosure, ModalCloseButton, - FormControl + FormControl, } from "@chakra-ui/react"; import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -21,159 +21,170 @@ import { ErrorMessage, ExtraInfoTextForm, LabelTextForm, - Button + Button, } from "../../molecules/uiUserPage"; import TrashIcon from "../../../public/img/icons/trashIcon"; -export default function Accesses ({ userInfo }) { - const { t } = useTranslation('user'); - const [data, setData] = useState(null) - const AddMemberModal = useDisclosure() - const RemoveMemberModal = useDisclosure() - const RemoveAllMembersModal = useDisclosure() - const [valueEmail, setValueEmail] = useState("") - const [errors, setErrors] = useState({}) - const [isLoading, setIsLoading] = useState(true) - const [isLoadingAddMember, setIsLoadingAddMember] = useState(false) - const [owner, setOwner] = useState(null) - const [subscriptionMembers, setSubscriptionMembers] = useState([]) - const [isMaxMembersReached, setIsMaxMembersReached] = useState(false) - - const reg = new RegExp("(?<=:).*") - const [ id ] = reg.exec(userInfo?.id) - const maxSlots = parseInt(userInfo.proSubscriptionSlots, 10) - 1 +export default function Accesses({ userInfo }) { + const { t } = useTranslation("user"); + const [data, setData] = useState(null); + const AddMemberModal = useDisclosure(); + const RemoveMemberModal = useDisclosure(); + const RemoveAllMembersModal = useDisclosure(); + const [valueEmail, setValueEmail] = useState(""); + const [errors, setErrors] = useState({}); + const [isLoading, setIsLoading] = useState(true); + const [isLoadingAddMember, setIsLoadingAddMember] = useState(false); + const [owner, setOwner] = useState(null); + const [subscriptionMembers, setSubscriptionMembers] = useState([]); + const [isMaxMembersReached, setIsMaxMembersReached] = useState(false); + + const reg = new RegExp("(?<=:).*"); + const [id] = reg.exec(userInfo?.id); + const maxSlots = parseInt(userInfo.proSubscriptionSlots, 10) - 1; async function getMembers() { - const res = await fetch(`/api/user/getMembers?p=${btoa(id)}`, {method: "GET"}) - .then(res => res.json()) - setIsLoading(false) - return setData(res) + const res = await fetch(`/api/user/getMembers?p=${btoa(id)}`, { + method: "GET", + }).then((res) => res.json()); + setIsLoading(false); + return setData(res); } useEffect(() => { - getMembers() - }, [userInfo]) + getMembers(); + }, [userInfo]); useEffect(() => { - if (!data) return - - const subData = userInfo?.proSubscriptionRole === "owner" - ? data?.internalSubscription?.edges?.[0]?.node - : data?.subscriptionSet?.edges?.[0]?.node - - setOwner(subData?.admin) - setSubscriptionMembers(subData?.subscribers?.edges) - setIsMaxMembersReached(subData?.subscribers?.edges?.length >= maxSlots) - setIsLoading(false) - }, [data]) + if (!data) return; + + const subData = + userInfo?.proSubscriptionRole === "owner" + ? data?.internalSubscription?.edges?.[0]?.node + : data?.subscriptionSet?.edges?.[0]?.node; + + setOwner(subData?.admin); + setSubscriptionMembers(subData?.subscribers?.edges); + setIsMaxMembersReached(subData?.subscribers?.edges?.length >= maxSlots); + setIsLoading(false); + }, [data]); const handleAddMember = async () => { - setErrors({}) - const valueEmailTrim = valueEmail.trim() + setErrors({}); + const valueEmailTrim = valueEmail.trim(); if (isMaxMembersReached) { - setErrors({ email: t('username.maxMembersReached') }); + setErrors({ email: t("username.maxMembersReached") }); return; } if (!valueEmailTrim || !/^\S+@\S+$/.test(valueEmailTrim)) { - setErrors({ email: t('username.pleaseEnterValidEmail') }); + setErrors({ email: t("username.pleaseEnterValidEmail") }); return; } - setIsLoadingAddMember(true) + setIsLoadingAddMember(true); try { - const response = await fetch(`/api/user/getIdUser?p=${btoa(valueEmailTrim)}`) - const idUser = await response.json() + const response = await fetch( + `/api/user/getIdUser?p=${btoa(valueEmailTrim)}`, + ); + const idUser = await response.json(); if (idUser.error === "err, user not found") { - setErrors({ email: t('username.userNotFound') }) - return + setErrors({ email: t("username.userNotFound") }); + return; } - const [idUserMember] = reg.exec(idUser?.id) || [] + const [idUserMember] = reg.exec(idUser?.id) || []; if (!idUserMember) { - setErrors({ email: t('username.userNotFound') }) - return + setErrors({ email: t("username.userNotFound") }); + return; } - const res = await fetch(`/api/user/addMemberInSubscription?p=${btoa(idUserMember)}&r=${btoa(id)}`) - const result = await res.json() + const res = await fetch( + `/api/user/addMemberInSubscription?p=${btoa(idUserMember)}&r=${btoa(id)}`, + ); + const result = await res.json(); if (result.success) { - setIsLoading(true) - AddMemberModal.onClose() - setValueEmail("") - setErrors({}) - getMembers() + setIsLoading(true); + AddMemberModal.onClose(); + setValueEmail(""); + setErrors({}); + getMembers(); } else { setErrors({ - email: result?.error?.[0] === "Conta possui inscrição ativa" ? t('username.userAlreadyHasSubscription') - : - result?.error?.[0] || t('username.userNotFound') - }) + email: + result?.error?.[0] === "Conta possui inscrição ativa" + ? t("username.userAlreadyHasSubscription") + : result?.error?.[0] || t("username.userNotFound"), + }); } } catch (error) { - setErrors({ email: t('username.unexpectedError') }) + setErrors({ email: t("username.unexpectedError") }); } finally { - setIsLoadingAddMember(false) + setIsLoadingAddMember(false); } - } + }; const handleRemoveMember = async () => { - setIsLoading(true) - setErrors({}) + setIsLoading(true); + setErrors({}); try { - const response = await fetch(`/api/user/getIdUser?p=${btoa(valueEmail)}`) - const idUser = await response.json() - const [ idUserMember ] = reg.exec(idUser?.id) + const response = await fetch(`/api/user/getIdUser?p=${btoa(valueEmail)}`); + const idUser = await response.json(); + const [idUserMember] = reg.exec(idUser?.id); if (!idUserMember) throw new Error("User not found"); - const res = await fetch(`/api/user/removeMemberInSubscription?p=${btoa(idUserMember)}&r=${btoa(id)}`) - const result = await res.json() + const res = await fetch( + `/api/user/removeMemberInSubscription?p=${btoa(idUserMember)}&r=${btoa(id)}`, + ); + const result = await res.json(); if (result.success) { - getMembers() + getMembers(); } else { - setIsLoading(false) + setIsLoading(false); } } catch (error) { - setErrors({ email: t("username.unexpectedError") }) - setIsLoading(false) + setErrors({ email: t("username.unexpectedError") }); + setIsLoading(false); } finally { - setValueEmail("") + setValueEmail(""); } - } + }; const handleRemoveAllMembers = async () => { - setIsLoading(true) - setErrors({}) + setIsLoading(true); + setErrors({}); try { - const res = await fetch(`/api/user/removeAllMembersInSubscription?p=${btoa(id)}`) - const result = await res.json() + const res = await fetch( + `/api/user/removeAllMembersInSubscription?p=${btoa(id)}`, + ); + const result = await res.json(); if (result.success) { - getMembers() + getMembers(); } else { - setIsLoading(false) + setIsLoading(false); } } catch (error) { - console.error(t("username.unexpectedError")) - setIsLoading(false) + console.error(t("username.unexpectedError")); + setIsLoading(false); } - } + }; const MembersComponent = ({ data, isOwner }) => { return ( <> @@ -194,13 +205,13 @@ export default function Accesses ({ userInfo }) { borderRadius="50%" overflow="hidden" > - @@ -210,17 +221,17 @@ export default function Accesses ({ userInfo }) { justifyContent="center" overflow="hidden" > - {data?.firstName} {data?.lastName || ""} + + {data?.firstName} {data?.lastName || ""} + {data?.email} + > + {data?.email} + @@ -229,19 +240,19 @@ export default function Accesses ({ userInfo }) { display="flex" alignItems="center" width="100%" - padding={{base: "24px 16px", lg: "24px"}} + padding={{ base: "24px 16px", lg: "24px" }} borderBottom="1px solid #EEEEEE" > - {isOwner ? t('username.administrator') : t('username.member')} + {isOwner ? t("username.administrator") : t("username.member")} - {!isOwner && userInfo?.proSubscriptionRole === "owner" && + {!isOwner && userInfo?.proSubscriptionRole === "owner" && ( { - RemoveMemberModal.onOpen() - setValueEmail(data?.email) + RemoveMemberModal.onOpen(); + setValueEmail(data?.email); }} /> - } + )} - ) - } + ); + }; return ( - + { - setValueEmail("") - setErrors({}) - AddMemberModal.onClose() + setValueEmail(""); + setErrors({}); + AddMemberModal.onClose(); }} propsModalContent={{ width: "100%", maxWidth: "600px", - margin: "24px" + margin: "24px", }} > - - {t("username.addUser")} - + {t("username.addUser")} - {t('username.addUserInfo')} + {t("username.addUserInfo")} - + setValueEmail(e.target.value)} /> - - {errors.email} - + {errors.email} @@ -338,13 +353,13 @@ export default function Accesses ({ userInfo }) { { - RemoveMemberModal.onClose() - setValueEmail("") + RemoveMemberModal.onClose(); + setValueEmail(""); }} propsModalContent={{ width: "100%", maxWidth: "500px", - margin: "24px" + margin: "24px", }} > @@ -355,46 +370,46 @@ export default function Accesses ({ userInfo }) { fontSize="14px" top="28px" right="26px" - _hover={{backgroundColor: "transparent", opacity: 0.7}} + _hover={{ backgroundColor: "transparent", opacity: 0.7 }} /> - - {!isMaxMembersReached ? - - : - 0 ? "flex" : "none"} + width={{ base: "100%", lg: "auto" }} + border="1px solid #BF3434" + color="#BF3434" + backgroundColor="#fff" + _hover={{ + color: "#992A2A", + borderColor: "#992A2A", + }} + onClick={() => RemoveAllMembersModal.onOpen()} > - + + {!isMaxMembersReached ? ( + + ) : ( + - {t('username.addUser')} - - - } - + + {t("username.addUser")} + + + )} + - - - {t('username.user')} - - - {t('username.access')} - - - {owner && } - {subscriptionMembers.map((member, index) => ( - - ))} - - - } + + + + {t("username.user")} + + + + + {t("username.access")} + + + + {owner && } + {subscriptionMembers.map((member, index) => ( + + ))} + + + )} - ) -} \ No newline at end of file + ); +} diff --git a/next/components/organisms/componentsUserPage/Account.js b/next/components/organisms/componentsUserPage/Account.js index ab8eafb44..dc6cda161 100644 --- a/next/components/organisms/componentsUserPage/Account.js +++ b/next/components/organisms/componentsUserPage/Account.js @@ -6,7 +6,7 @@ import { ModalCloseButton, } from "@chakra-ui/react"; import { useState } from "react"; -import cookies from 'js-cookie'; +import cookies from "js-cookie"; import { useTranslation } from "react-i18next"; import { useRouter } from "next/router"; import Link from "../../atoms/Link"; @@ -19,155 +19,173 @@ import { ModalGeneral, Button, InputForm, - ErrorMessage + ErrorMessage, } from "../../molecules/uiUserPage"; export default function Account({ userInfo }) { - const { t } = useTranslation('user'); + const { t } = useTranslation("user"); const router = useRouter(); - const usernameModal = useDisclosure() - const eraseModalAccount = useDisclosure() - const sucessEraseModalAccount = useDisclosure() - const errorEraseModalAccount = useDisclosure() - const [isLoading, setIsLoading] = useState(false) - const [hasCancelSubscription, setHasCancelSubscription] = useState(false) - const [hasMembers, setHasMembers] = useState(false) + const usernameModal = useDisclosure(); + const eraseModalAccount = useDisclosure(); + const sucessEraseModalAccount = useDisclosure(); + const errorEraseModalAccount = useDisclosure(); + const [isLoading, setIsLoading] = useState(false); + const [hasCancelSubscription, setHasCancelSubscription] = useState(false); + const [hasMembers, setHasMembers] = useState(false); - const [formData, setFormData] = useState({username: ""}) - const [errors, setErrors] = useState({}) + const [formData, setFormData] = useState({ username: "" }); + const [errors, setErrors] = useState({}); const handleInputChange = (e) => { setFormData((prevState) => ({ ...prevState, [e.target.name]: e.target.value, - })) - } + })); + }; async function submitUpdate() { - setErrors({}) - if(formData.username === "") return setErrors({username: t('username.invalidUsername')}) - if(formData.username.includes(" ")) return setErrors({username: t('username.noSpacesInUsername')}) - setIsLoading(true) - - const reg = new RegExp("(?<=:).*") - const [ id ] = reg.exec(userInfo?.id) - const form = {id: id, username: formData.username} - - const result = await fetch(`/api/user/updateUser?p=${btoa(id)}&q=${btoa(form.username)}`, {method: "GET"}) - .then(res => res.json()) - - if(result?.errors?.length === 0) { - const userData = await fetch(`/api/user/getUser?p=${btoa(id)}`, {method: "GET"}) - .then(res => res.json()) - cookies.set('userBD', JSON.stringify(userData)) - window.open(`/user/${formData.username}?account`, "_self") + setErrors({}); + if (formData.username === "") + return setErrors({ username: t("username.invalidUsername") }); + if (formData.username.includes(" ")) + return setErrors({ username: t("username.noSpacesInUsername") }); + setIsLoading(true); + + const reg = new RegExp("(?<=:).*"); + const [id] = reg.exec(userInfo?.id); + const form = { id: id, username: formData.username }; + + const result = await fetch( + `/api/user/updateUser?p=${btoa(id)}&q=${btoa(form.username)}`, + { method: "GET" }, + ).then((res) => res.json()); + + if (result?.errors?.length === 0) { + const userData = await fetch(`/api/user/getUser?p=${btoa(id)}`, { + method: "GET", + }).then((res) => res.json()); + cookies.set("userBD", JSON.stringify(userData)); + window.open(`/user/${formData.username}?account`, "_self"); } - if(result?.errors?.length > 0) { - setErrors({username: t('username.usernameAlreadyExists')}) - setIsLoading(false) + if (result?.errors?.length > 0) { + setErrors({ username: t("username.usernameAlreadyExists") }); + setIsLoading(false); } } async function eraseAccount() { try { - setIsLoading(true) - setHasCancelSubscription(false) - setHasMembers(false) + setIsLoading(true); + setHasCancelSubscription(false); + setHasMembers(false); - const reg = new RegExp("(?<=:).*") - const [ id ] = reg.exec(userInfo.id) + const reg = new RegExp("(?<=:).*"); + const [id] = reg.exec(userInfo.id); - const canDeleteAccount = await validateAccountDeletion(id) + const canDeleteAccount = await validateAccountDeletion(id); if (canDeleteAccount) { - await deleteUserAccount(id) + await deleteUserAccount(id); } else { - eraseModalAccount.onClose() - errorEraseModalAccount.onOpen() + eraseModalAccount.onClose(); + errorEraseModalAccount.onOpen(); } } catch (error) { - console.error(error) + console.error(error); } finally { - setIsLoading(false) - eraseModalAccount.onClose() + setIsLoading(false); + eraseModalAccount.onClose(); } } async function validateAccountDeletion(id) { if (!userInfo?.isSubscriber || userInfo?.proSubscriptionRole === "member") { - return true + return true; } - let hasMembersInSubscription = false - const hasActiveSubscription = userInfo?.internalSubscription?.edges?.[0]?.node?.canceledAt === null + let hasMembersInSubscription = false; + const hasActiveSubscription = + userInfo?.internalSubscription?.edges?.[0]?.node?.canceledAt === null; if (hasActiveSubscription) { - setHasCancelSubscription(true) + setHasCancelSubscription(true); } if (userInfo?.proSubscription === "bd_pro_empresas") { - const res = await fetch(`/api/user/getMembers?p=${btoa(id)}`, {method: "GET"}) - const membersData = await res.json() - - if (membersData?.internalSubscription?.edges?.[0]?.node?.subscribers?.edges?.length > 0) { - setHasMembers(true) - hasMembersInSubscription = true + const res = await fetch(`/api/user/getMembers?p=${btoa(id)}`, { + method: "GET", + }); + const membersData = await res.json(); + + if ( + membersData?.internalSubscription?.edges?.[0]?.node?.subscribers?.edges + ?.length > 0 + ) { + setHasMembers(true); + hasMembersInSubscription = true; } } - return !hasActiveSubscription && !hasMembersInSubscription + return !hasActiveSubscription && !hasMembersInSubscription; } async function deleteUserAccount(id) { - const result = await fetch(`/api/user/deleteAccount?p=${btoa(id)}`, {method: "GET"}) - .then(res => res.json()) + const result = await fetch(`/api/user/deleteAccount?p=${btoa(id)}`, { + method: "GET", + }).then((res) => res.json()); - if(result?.ok === true) { - sucessEraseModalAccount.onOpen() + if (result?.ok === true) { + sucessEraseModalAccount.onOpen(); } else { - errorEraseModalAccount.onOpen() + errorEraseModalAccount.onOpen(); } } function handleCloseSucessEraseAccount() { - setIsLoading(true) - cookies.remove('userBD', { path: '/' }) - cookies.remove('token', { path: '/' }) - sucessEraseModalAccount.onClose() - return window.open("/", "_self") + setIsLoading(true); + cookies.remove("userBD", { path: "/" }); + cookies.remove("token", { path: "/" }); + sucessEraseModalAccount.onClose(); + return window.open("/", "_self"); } return ( - + - {t('username.changeUsername')} + {t("username.changeUsername")} - + - - {errors.username} - + {errors.username} - {t('username.confirmAccountDeletion')} + + {t("username.confirmAccountDeletion")} + eraseModalAccount.onClose() } + _hover={{ backgroundColor: "transparent", opacity: 0.7 }} + onClick={() => eraseModalAccount.onClose()} /> - {t('username.accountDeletionWarning')} + {t("username.accountDeletionWarning")} @@ -240,27 +260,25 @@ export default function Account({ userInfo }) { - {t('username.deleteAccountSuccessTitle')} + {t("username.deleteAccountSuccessTitle")} - {t('username.deleteAccountSuccessText')} + {t("username.deleteAccountSuccessText")} - + @@ -278,30 +296,31 @@ export default function Account({ userInfo }) { - {t('username.errorEraseAccountTitle')} + {t("username.errorEraseAccountTitle")} {hasCancelSubscription && ( - {t('username.errorEraseAccountText')} + + {t("username.errorEraseAccountText")} + )} {hasMembers && ( - {t('username.errorEraseAccountMembers')} + + {t("username.errorEraseAccountMembers")} + )} - + - {t('username.username')} + {t("username.username")} {userInfo.username} + > + {t("username.changeUsername")} + - {t('username.exportAccountData')} + {t("username.exportAccountData")} - {t('username.dataStorageInfo', { returnObjects: true })[0]} + {t("username.dataStorageInfo", { returnObjects: true })[0]} - {t('username.dataStorageInfo', { returnObjects: true })[1]} + {t("username.dataStorageInfo", { returnObjects: true })[1]} - {t('username.dataStorageInfo', { returnObjects: true })[2]} + {t("username.dataStorageInfo", { returnObjects: true })[2]} - {t('username.dataStorageInfo', { returnObjects: true })[3]} + {t("username.dataStorageInfo", { returnObjects: true })[3]} - {t('username.dataStorageInfo', { returnObjects: true })[4]} + {t("username.dataStorageInfo", { returnObjects: true })[4]} + onClick={() => router.push("/contact")} + > + {t("username.contactUs")} + - {t('username.deleteAccount')} - {t('username.accountAccessWarning')} + + {t("username.deleteAccount")} + + + {t("username.accountAccessWarning")} + + > + {t("username.deleteMyAccount")} + - ) + ); } diff --git a/next/components/organisms/componentsUserPage/BigQuery.js b/next/components/organisms/componentsUserPage/BigQuery.js index 6e4e18dc4..cbb3daf57 100644 --- a/next/components/organisms/componentsUserPage/BigQuery.js +++ b/next/components/organisms/componentsUserPage/BigQuery.js @@ -1,11 +1,6 @@ -import { - Stack, - Box, - Text, - FormControl, -} from "@chakra-ui/react"; +import { Stack, Box, Text, FormControl } from "@chakra-ui/react"; import { useState } from "react"; -import cookies from 'js-cookie'; +import cookies from "js-cookie"; import { useTranslation } from "react-i18next"; import { triggerGAEvent } from "../../../utils"; @@ -14,107 +9,120 @@ import { ExtraInfoTextForm, Button, InputForm, - ErrorMessage + ErrorMessage, } from "../../molecules/uiUserPage"; - -export default function BigQuery ({ userInfo }) { - const { t } = useTranslation('user'); - const [emailGcp, setEmailGcp] = useState(userInfo?.gcpEmail || userInfo?.email) - const [errors, setErrors] = useState({}) - const [isLoading, setIsLoading] = useState(false) +export default function BigQuery({ userInfo }) { + const { t } = useTranslation("user"); + const [emailGcp, setEmailGcp] = useState( + userInfo?.gcpEmail || userInfo?.email, + ); + const [errors, setErrors] = useState({}); + const [isLoading, setIsLoading] = useState(false); async function handleUpdateEmailGcp() { - if(emailGcp === userInfo?.gcpEmail) { - setErrors({emailGcp: t('username.errEmailGcp')}) - return + if (emailGcp === userInfo?.gcpEmail) { + setErrors({ emailGcp: t("username.errEmailGcp") }); + return; } - setErrors({}) - setIsLoading(true) + setErrors({}); + setIsLoading(true); function isValidEmail(email) { - const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ - return emailRegex.test(email) + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + return emailRegex.test(email); } - if(!isValidEmail(emailGcp)) { - setErrors({emailGcp: t('username.errEmailGcp')}) + if (!isValidEmail(emailGcp)) { + setErrors({ emailGcp: t("username.errEmailGcp") }); } else { - const reg = new RegExp("(?<=:).*") - const [ id ] = reg.exec(userInfo.id) - - let user - let attempts = 0 - const maxAttempts = 10 - const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)) - - const response = await fetch(`/api/user/changeUserGcpEmail?p=${btoa(emailGcp)}`) - .then(res => res.json()) - - if(response.ok) { - if(emailGcp !== userInfo?.email) { - if(emailGcp !== userInfo?.gcpEmail) { - triggerGAEvent("troca_do_email_gcp",`section_bigquery`) + const reg = new RegExp("(?<=:).*"); + const [id] = reg.exec(userInfo.id); + + let user; + let attempts = 0; + const maxAttempts = 10; + const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); + + const response = await fetch( + `/api/user/changeUserGcpEmail?p=${btoa(emailGcp)}`, + ).then((res) => res.json()); + + if (response.ok) { + if (emailGcp !== userInfo?.email) { + if (emailGcp !== userInfo?.gcpEmail) { + triggerGAEvent("troca_do_email_gcp", `section_bigquery`); } } while (!user?.gcpEmail && attempts < maxAttempts) { - user = await fetch(`/api/user/getUser?p=${btoa(id)}`, { method: "GET" }) - .then((res) => res.json()) - + user = await fetch(`/api/user/getUser?p=${btoa(id)}`, { + method: "GET", + }).then((res) => res.json()); + if (user?.gcpEmail) { - cookies.set("userBD", JSON.stringify(user)) - break + cookies.set("userBD", JSON.stringify(user)); + break; } - - attempts++ - await delay(10000) + + attempts++; + await delay(10000); } - window.location.reload() + window.location.reload(); } else { - setErrors({emailGcp: t('username.errEmailGcp')}) - setIsLoading(false) + setErrors({ emailGcp: t("username.errEmailGcp") }); + setIsLoading(false); } } } return ( - + - {t('username.bigquerySectionTitle')} + {t("username.bigquerySectionTitle")} - - {t('username.bigquerySectionSubtitle', { returnObjects: true })[0]} - - {t('username.bigquerySectionSubtitle', { returnObjects: true })[1]} - - {t('username.bigquerySectionSubtitle', { returnObjects: true })[2]} + + {t("username.bigquerySectionSubtitle", { returnObjects: true })[0]} + + {t("username.bigquerySectionSubtitle", { returnObjects: true })[1]} + + {t("username.bigquerySectionSubtitle", { returnObjects: true })[2]} - + setEmailGcp(e.target.value)} - placeholder={t('username.bigquerySectionInputPlaceholder')} + placeholder={t("username.bigquerySectionInputPlaceholder")} /> - - {errors.emailGcp} - + {errors.emailGcp} - ) + ); } diff --git a/next/components/organisms/componentsUserPage/DataAPI.js b/next/components/organisms/componentsUserPage/DataAPI.js index 4744e4280..63d5174ea 100644 --- a/next/components/organisms/componentsUserPage/DataAPI.js +++ b/next/components/organisms/componentsUserPage/DataAPI.js @@ -7,7 +7,7 @@ import { Tooltip, useClipboard, Link, - Button + Button, } from "@chakra-ui/react"; import { useState, useEffect } from "react"; import { useTranslation } from "react-i18next"; @@ -18,13 +18,13 @@ import { CopySolidIcon } from "../../../public/img/icons/copyIcon"; import CheckIcon from "../../../public/img/icons/checkIcon"; export default function DataAPI({ userInfo }) { - const { t } = useTranslation('user'); + const { t } = useTranslation("user"); const [apiKeys, setApiKeys] = useState([]); const [copiedIndex, setCopiedIndex] = useState(null); useEffect(() => { if (userInfo?.keys?.edges) { - setApiKeys(userInfo.keys.edges.map(edge => edge.node)); + setApiKeys(userInfo.keys.edges.map((edge) => edge.node)); } }, [userInfo]); @@ -40,32 +40,32 @@ export default function DataAPI({ userInfo }) { const formatDate = (dateString) => { const date = new Date(dateString); - return date.toISOString().split('T')[0]; + return date.toISOString().split("T")[0]; }; return ( - - - {t('dataAPI.earlyRelease')} 🚧 - - - {t('dataAPI.earlyReleaseDescription')} - - + + + {t("dataAPI.earlyRelease")} 🚧 + + + {t("dataAPI.earlyReleaseDescription")} + + - {t('dataAPI.keys')} + {t("dataAPI.keys")} - {t('dataAPI.description')} + {t("dataAPI.description")} @@ -82,7 +82,7 @@ export default function DataAPI({ userInfo }) { - {t('dataAPI.prefix')}: {key.prefix} + {t("dataAPI.prefix")}: {key.prefix} {key.name && ( <> @@ -90,7 +90,7 @@ export default function DataAPI({ userInfo }) { | - {t('dataAPI.name')}: {key.name} + {t("dataAPI.name")}: {key.name} )} @@ -111,7 +111,7 @@ export default function DataAPI({ userInfo }) { borderRadius="4px" px={2} > - {key.isActive ? t('dataAPI.active') : t('dataAPI.inactive')} + {key.isActive ? t("dataAPI.active") : t("dataAPI.inactive")} {key.isActive && ( )} @@ -135,15 +135,15 @@ export default function DataAPI({ userInfo }) { - {t('dataAPI.balance')} + {t("dataAPI.balance")} - {key.balance || 0} {t('dataAPI.reais')} + {key.balance || 0} {t("dataAPI.reais")} - {t('dataAPI.created')} + {t("dataAPI.created")} {formatDate(key.createdAt)} @@ -151,10 +151,12 @@ export default function DataAPI({ userInfo }) { - {t('dataAPI.expires')} + {t("dataAPI.expires")} - {key.expiresAt ? formatDate(key.expiresAt) : t('dataAPI.never')} + {key.expiresAt + ? formatDate(key.expiresAt) + : t("dataAPI.never")} @@ -165,7 +167,7 @@ export default function DataAPI({ userInfo }) { - {t('dataAPI.needMoreKeys')} {' '} + {t("dataAPI.needMoreKeys")}{" "} - {t('dataAPI.contactUs')} - - {' '}{t('dataAPI.weWillHelpYou')} + {t("dataAPI.contactUs")} + {" "} + {t("dataAPI.weWillHelpYou")} ); -} \ No newline at end of file +} diff --git a/next/components/organisms/componentsUserPage/NewPassword.js b/next/components/organisms/componentsUserPage/NewPassword.js index 75a33c07d..f0eb964b2 100644 --- a/next/components/organisms/componentsUserPage/NewPassword.js +++ b/next/components/organisms/componentsUserPage/NewPassword.js @@ -18,7 +18,7 @@ import { InputForm, ErrorMessage, Button, - ListChecked + ListChecked, } from "../../molecules/uiUserPage"; import Exclamation from "../../../public/img/icons/exclamationIcon"; @@ -26,96 +26,104 @@ import { SuccessIcon } from "../../../public/img/icons/successIcon"; import { EyeIcon, EyeOffIcon } from "../../../public/img/icons/eyeIcon"; export default function NewPassword({ userInfo }) { - const { t } = useTranslation('user'); - const newPasswordModal = useDisclosure() + const { t } = useTranslation("user"); + const newPasswordModal = useDisclosure(); const [formData, setFormData] = useState({ password: "", newPassword: "", - confirmPassword: "" - }) - const [errors, setErrors] = useState({}) - const [isLoading, setIsLoading] = useState(false) + confirmPassword: "", + }); + const [errors, setErrors] = useState({}); + const [isLoading, setIsLoading] = useState(false); - const [showPassword, setShowPassword] = useState(true) - const [showNewPassword, setShowNewPassword] = useState(true) - const [showConfirmPassword, setShowConfirmPassword] = useState(true) + const [showPassword, setShowPassword] = useState(true); + const [showNewPassword, setShowNewPassword] = useState(true); + const [showConfirmPassword, setShowConfirmPassword] = useState(true); const handleInputChange = (e, field) => { setFormData((prevState) => ({ ...prevState, [field]: e.target.value, - })) - } + })); + }; async function handleSubmit(event) { - event.preventDefault() - setIsLoading(true) - let regexPassword = {} - let validationErrors = {} + event.preventDefault(); + setIsLoading(true); + let regexPassword = {}; + let validationErrors = {}; - if(formData.password !== "" && formData.password === formData.newPassword) { - validationErrors.newPassword = t('username.newPasswordDifferent') + if ( + formData.password !== "" && + formData.password === formData.newPassword + ) { + validationErrors.newPassword = t("username.newPasswordDifferent"); } - if(!/^.{8,}$/.test(formData.newPassword)) { - regexPassword = {...regexPassword, amount: true} + if (!/^.{8,}$/.test(formData.newPassword)) { + regexPassword = { ...regexPassword, amount: true }; } - if(!/[A-Z]/.test(formData.newPassword)) { - regexPassword = {...regexPassword, upperCase: true} + if (!/[A-Z]/.test(formData.newPassword)) { + regexPassword = { ...regexPassword, upperCase: true }; } - if(!/[a-z]/.test(formData.newPassword)) { - regexPassword = {...regexPassword, lowerCase: true} + if (!/[a-z]/.test(formData.newPassword)) { + regexPassword = { ...regexPassword, lowerCase: true }; } - if(!/(?=.*?[0-9])/.test(formData.newPassword)) { - regexPassword = {...regexPassword, number: true} + if (!/(?=.*?[0-9])/.test(formData.newPassword)) { + regexPassword = { ...regexPassword, number: true }; } - if(!/[!@#?!%&*]/.test(formData.newPassword)) { - regexPassword = {...regexPassword, special: true} + if (!/[!@#?!%&*]/.test(formData.newPassword)) { + regexPassword = { ...regexPassword, special: true }; } if (!formData.confirmPassword) { - validationErrors.confirmPassword = t('username.confirmPasswordRequired') + validationErrors.confirmPassword = t("username.confirmPasswordRequired"); } - if(/\s/.test(formData.confirmPassword)) { - validationErrors.newPassword = t('username.noSpacesInPassword') - validationErrors.confirmPassword = t('username.noSpacesInPassword') + if (/\s/.test(formData.confirmPassword)) { + validationErrors.newPassword = t("username.noSpacesInPassword"); + validationErrors.confirmPassword = t("username.noSpacesInPassword"); } - if(formData.confirmPassword !== formData.newPassword) { - validationErrors.confirmPassword = t('username.passwordMismatch') + if (formData.confirmPassword !== formData.newPassword) { + validationErrors.confirmPassword = t("username.passwordMismatch"); } - if(Object.keys(regexPassword).length > 0) validationErrors.regexPassword = regexPassword + if (Object.keys(regexPassword).length > 0) + validationErrors.regexPassword = regexPassword; - if(formData.password === "") { - validationErrors.password = t('username.errEnterPassword') + if (formData.password === "") { + validationErrors.password = t("username.errEnterPassword"); } - if(formData.password !== "") { - const result = await fetch(`/api/user/getToken?a=${btoa(userInfo.email)}&q=${btoa(formData.password)}&s=${"true"}`, {method: "GET"}) - .then(res => res.json()) - if(result.error) { - validationErrors.password = t('username.incorrectPassword') + if (formData.password !== "") { + const result = await fetch( + `/api/user/getToken?a=${btoa(userInfo.email)}&q=${btoa(formData.password)}&s=${"true"}`, + { method: "GET" }, + ).then((res) => res.json()); + if (result.error) { + validationErrors.password = t("username.incorrectPassword"); } } - setErrors(validationErrors) + setErrors(validationErrors); if (Object.keys(validationErrors).length > 0) { - setIsLoading(false) + setIsLoading(false); } else { - const reg = new RegExp("(?<=:).*") - const [ id ] = reg.exec(userInfo?.id) - - const result = await fetch(`/api/user/updatePassword?b=${btoa(id)}&p=${btoa(formData.newPassword)}`, {method: "GET"}) - .then(res => res.json()) + const reg = new RegExp("(?<=:).*"); + const [id] = reg.exec(userInfo?.id); + + const result = await fetch( + `/api/user/updatePassword?b=${btoa(id)}&p=${btoa(formData.newPassword)}`, + { method: "GET" }, + ).then((res) => res.json()); - if(result?.success === true) { + if (result?.success === true) { setFormData({ password: "", newPassword: "", - confirmPassword: "" - }) - newPasswordModal.onOpen() + confirmPassword: "", + }); + newPasswordModal.onOpen(); } } - setIsLoading(false) + setIsLoading(false); } return ( @@ -139,30 +147,28 @@ export default function NewPassword({ userInfo }) { fontSize="14px" top="34px" right="26px" - _hover={{backgroundColor: "transparent", opacity: 0.7}} + _hover={{ backgroundColor: "transparent", opacity: 0.7 }} /> - - - {t('username.passwordChangedSuccessfully')} + + + {t("username.passwordChangedSuccessfully")} -
- + handleInputChange(e, "password")} - placeholder={t('username.enterCurrentPassword')} + placeholder={t("username.enterCurrentPassword")} inputElementStyle={{ cursor: "pointer", - onClick: () => setShowPassword(!showPassword) + onClick: () => setShowPassword(!showPassword), }} - icon={showPassword ? - - : - + icon={ + showPassword ? ( + + ) : ( + + ) } /> {errors.password} @@ -197,15 +205,19 @@ export default function NewPassword({ userInfo }) { fontWeight="400" color="#0068C5" _hover={{ - color:"#0057A4", + color: "#0057A4", }} href="/user/password-recovery" - >{t('username.forgotPassword')} + > + {t("username.forgotPassword")} - - + + handleInputChange(e, "newPassword")} - placeholder={t('username.createNewPassword')} + placeholder={t("username.createNewPassword")} inputElementStyle={{ cursor: "pointer", - onClick: () => setShowNewPassword(!showNewPassword) + onClick: () => setShowNewPassword(!showNewPassword), }} - icon={showNewPassword ? - - : - + icon={ + showNewPassword ? ( + + ) : ( + + ) } /> 0 ? "#BF3434" : "#71757A" : "#71757A" } + color={ + errors?.regexPassword + ? Object.keys(errors?.regexPassword).length > 0 + ? "#BF3434" + : "#71757A" + : "#71757A" + } display="flex" flexDirection="row" gap="8px" alignItems="flex-start" > 0 ? "flex" : "none" : "none"} + display={ + errors?.regexPassword + ? Object.keys(errors?.regexPassword).length > 0 + ? "flex" + : "none" + : "none" + } width="18px" height="18px" fill="#BF3434" - /> {t('username.passwordRequirements')} + />{" "} + {t("username.passwordRequirements")} - = 8} err={errors?.regexPassword?.amount} > - {t('username.minCharacters')} + {t("username.minCharacters")} - {t('username.uppercaseLetter')} + {t("username.uppercaseLetter")} - {t('username.lowercaseLetter')} + {t("username.lowercaseLetter")} - {t('username.digit')} + {t("username.digit")} - {t('username.specialCharacter')} + {t("username.specialCharacter")} - {errors.newPassword && + {errors.newPassword && ( {errors.newPassword} - } + )} - + handleInputChange(e, "confirmPassword")} - placeholder={t('username.enterPasswordAgain')} + placeholder={t("username.enterPasswordAgain")} inputElementStyle={{ cursor: "pointer", - onClick: () => setShowConfirmPassword(!showConfirmPassword) + onClick: () => setShowConfirmPassword(!showConfirmPassword), }} - icon={showConfirmPassword ? - - : - + icon={ + showConfirmPassword ? ( + + ) : ( + + ) } /> {errors.confirmPassword} @@ -338,9 +367,9 @@ export default function NewPassword({ userInfo }) { isLoading={isLoading} onClick={() => {}} > - {t('username.updatePassword')} + {t("username.updatePassword")}
- ) -} \ No newline at end of file + ); +} diff --git a/next/components/organisms/componentsUserPage/PlansAndPayment.js b/next/components/organisms/componentsUserPage/PlansAndPayment.js index 0eeb17a5f..2e68561dd 100644 --- a/next/components/organisms/componentsUserPage/PlansAndPayment.js +++ b/next/components/organisms/componentsUserPage/PlansAndPayment.js @@ -8,11 +8,11 @@ import { ModalCloseButton, Badge, Grid, - GridItem + GridItem, } from "@chakra-ui/react"; import { useState, useEffect } from "react"; import { useRouter } from "next/router"; -import cookies from 'js-cookie'; +import cookies from "js-cookie"; import { useTranslation } from "react-i18next"; import { isMobileMod } from "../../../hooks/useCheckMobile.hook"; import { ControlledInputSimple } from "../../atoms/ControlledInput"; @@ -28,7 +28,7 @@ import { triggerGAEvent } from "../../../utils"; import { ExtraInfoTextForm, ModalGeneral, - Button + Button, } from "../../molecules/uiUserPage"; import Exclamation from "../../../public/img/icons/exclamationIcon"; @@ -39,202 +39,238 @@ import { SuccessIcon } from "../../../public/img/icons/successIcon"; import ErrIcon from "../../../public/img/icons/errIcon"; import stylesPS from "../../../styles/paymentSystem.module.css"; -export default function PlansAndPayment ({ userData }) { - const { t } = useTranslation('user'); - const router = useRouter() - const { query } = router - const [plan, setPlan] = useState("") - const [checkoutInfos, setCheckoutInfos] = useState({}) - const [valueCoupon, setValueCoupon] = useState("") - const [errCoupon, setErrCoupon] = useState(false) - const [couponInfos, setCouponInfos] = useState({}) - const [couponInputFocus, setCouponInputFocus] = useState(false) - const [coupon, setCoupon] = useState("") - const [hasOpenEmailModal, setHasOpenEmailModal] = useState(false) - const [emailGCP, setEmailGCP] = useState(userData?.gcpEmail || userData?.email) - const [emailGCPFocus, setEmailGCPFocus] = useState(false) - const [errEmailGCP, setErrEmailGCP] = useState(false) - const [isLoadingEmailChange, setIsLoadingEmailChange] = useState(false) - - const PaymentModal = useDisclosure() - const EmailModal = useDisclosure() - const SucessPaymentModal = useDisclosure() - const ErroPaymentModal = useDisclosure() - const PlansModal = useDisclosure() - const CancelModalPlan = useDisclosure() - const AlertChangePlanModal = useDisclosure() - - const [isLoading, setIsLoading] = useState(false) - const [isLoadingH, setIsLoadingH] = useState(false) - const [isLoadingCanSub, setIsLoadingCanSub] = useState(false) - const [isLoadingClientSecret, setIsLoadingClientSecret] = useState(true) - const [hasSubscribed, setHasSubscribed] = useState(true) - const [plans, setPlans] = useState(null) - const [toggleAnual, setToggleAnual] = useState(true) +export default function PlansAndPayment({ userData }) { + const { t } = useTranslation("user"); + const router = useRouter(); + const { query } = router; + const [plan, setPlan] = useState(""); + const [checkoutInfos, setCheckoutInfos] = useState({}); + const [valueCoupon, setValueCoupon] = useState(""); + const [errCoupon, setErrCoupon] = useState(false); + const [couponInfos, setCouponInfos] = useState({}); + const [couponInputFocus, setCouponInputFocus] = useState(false); + const [coupon, setCoupon] = useState(""); + const [hasOpenEmailModal, setHasOpenEmailModal] = useState(false); + const [emailGCP, setEmailGCP] = useState( + userData?.gcpEmail || userData?.email, + ); + const [emailGCPFocus, setEmailGCPFocus] = useState(false); + const [errEmailGCP, setErrEmailGCP] = useState(false); + const [isLoadingEmailChange, setIsLoadingEmailChange] = useState(false); + + const PaymentModal = useDisclosure(); + const EmailModal = useDisclosure(); + const SucessPaymentModal = useDisclosure(); + const ErroPaymentModal = useDisclosure(); + const PlansModal = useDisclosure(); + const CancelModalPlan = useDisclosure(); + const AlertChangePlanModal = useDisclosure(); + + const [isLoading, setIsLoading] = useState(false); + const [isLoadingH, setIsLoadingH] = useState(false); + const [isLoadingCanSub, setIsLoadingCanSub] = useState(false); + const [isLoadingClientSecret, setIsLoadingClientSecret] = useState(true); + const [hasSubscribed, setHasSubscribed] = useState(true); + const [plans, setPlans] = useState(null); + const [toggleAnual, setToggleAnual] = useState(true); const subscriptionInfo = () => { - if(userData?.internalSubscription?.edges?.[0]?.node) return userData?.internalSubscription?.edges?.[0]?.node - if(userData?.subscriptionSet?.edges?.[0]?.node) return userData?.subscriptionSet?.edges?.[0]?.node - } + if (userData?.internalSubscription?.edges?.[0]?.node) + return userData?.internalSubscription?.edges?.[0]?.node; + if (userData?.subscriptionSet?.edges?.[0]?.node) + return userData?.subscriptionSet?.edges?.[0]?.node; + }; async function alreadySubscribed(id) { - const result = await fetch(`/api/user/getAlreadySubscribed?p=${btoa(id)}`) - .then(res => res.json()) - setHasSubscribed(result) + const result = await fetch( + `/api/user/getAlreadySubscribed?p=${btoa(id)}`, + ).then((res) => res.json()); + setHasSubscribed(result); } useEffect(() => { - const reg = new RegExp("(?<=:).*") - const [ id ] = reg.exec(userData.id) + const reg = new RegExp("(?<=:).*"); + const [id] = reg.exec(userData.id); - alreadySubscribed(id) - }, [userData?.id]) + alreadySubscribed(id); + }, [userData?.id]); useEffect(() => { async function fecthPlans() { try { - const result = await fetch(`/api/stripe/getPlans`, { method: "GET" }) - .then(res => res.json()) + const result = await fetch(`/api/stripe/getPlans`, { + method: "GET", + }).then((res) => res.json()); - if(result.success === true) { + if (result.success === true) { function filterData(productName, interval, isActive) { - let array = result.data - - return array.filter(item => - (productName ? item.node.productName === productName : true) && - (interval ? item.node.interval === interval : true) && - (isActive !== undefined ? item.node.isActive === isActive : true) - ) + let array = result.data; + + return array.filter( + (item) => + (productName ? item.node.productName === productName : true) && + (interval ? item.node.interval === interval : true) && + (isActive !== undefined + ? item.node.isActive === isActive + : true), + ); } const filteredPlans = { - bd_pro_month : filterData("BD Pro", "month", true)[0].node, - bd_pro_year : filterData("BD Pro", "year", true)[0].node, - bd_empresas_month : filterData("BD Empresas", "month", true)[0].node, - bd_empresas_year : filterData("BD Empresas", "year", true)[0].node - } + bd_pro_month: filterData("BD Pro", "month", true)[0].node, + bd_pro_year: filterData("BD Pro", "year", true)[0].node, + bd_empresas_month: filterData("BD Empresas", "month", true)[0].node, + bd_empresas_year: filterData("BD Empresas", "year", true)[0].node, + }; - setPlans(filteredPlans) + setPlans(filteredPlans); } } catch (error) { - console.error(error) + console.error(error); } } - fecthPlans() - }, []) + fecthPlans(); + }, []); useEffect(() => { - if(plans === null) return - if(plan === "") return - - const value = Object.values(plans).find(elm => elm._id === plan) - if(value?.interval === "month") setToggleAnual(false) - setCheckoutInfos(value) - if(!hasOpenEmailModal) { - EmailModal.onOpen() - setHasOpenEmailModal(true) + if (plans === null) return; + if (plan === "") return; + + const value = Object.values(plans).find((elm) => elm._id === plan); + if (value?.interval === "month") setToggleAnual(false); + setCheckoutInfos(value); + if (!hasOpenEmailModal) { + EmailModal.onOpen(); + setHasOpenEmailModal(true); } - }, [plan, plans]) + }, [plan, plans]); useEffect(() => { - if(query.i) { - if(userData?.isSubscriber) return AlertChangePlanModal.onOpen() - setPlan(query.i) + if (query.i) { + if (userData?.isSubscriber) return AlertChangePlanModal.onOpen(); + setPlan(query.i); } - }, [query]) + }, [query]); - const planActive = userData?.isSubscriber + const planActive = userData?.isSubscriber; const resources = { - "BD Gratis" : { - title: t('username.DBFree'), - buttons: [{ - text: t('username.comparePlans'), - onClick: () => { - PlansModal.onOpen() - setToggleAnual(true) - }} + "BD Gratis": { + title: t("username.DBFree"), + buttons: [ + { + text: t("username.comparePlans"), + onClick: () => { + PlansModal.onOpen(); + setToggleAnual(true); + }, + }, + ], + resources: [ + { name: t("username.processedTables") }, + { + name: t("username.integratedData"), + tooltip: t("username.integratedDataTooltip"), + }, + { name: t("username.updatedLowFrequencyData") }, + { name: t("username.cloudAccess") }, + { name: t("username.sqlPythonRAccess") }, + { name: t("username.biIntegration") }, + planActive + ? "" + : { + name: t("username.downloadLimit100MB"), + tooltip: t("username.downloadLimit100MBTooltip"), + }, ], - resources : [ - {name: t('username.processedTables')}, - {name: t('username.integratedData'), tooltip: t('username.integratedDataTooltip')}, - {name: t('username.updatedLowFrequencyData')}, - {name: t('username.cloudAccess')}, - {name: t('username.sqlPythonRAccess')}, - {name: t('username.biIntegration')}, - planActive ? "" : {name: t('username.downloadLimit100MB'), tooltip: t('username.downloadLimit100MBTooltip')}, - ] }, - "bd_pro" : { - title: t('username.DBPro'), - buttons : [{ - text: t('username.cancelPlan'), - onClick: () => CancelModalPlan.onOpen(), - props: { - borderColor: subscriptionInfo()?.canceledAt ? "#ACAEB1" : "#2B8C4D", - color: subscriptionInfo()?.canceledAt ? "#ACAEB1" : "#2B8C4D", - pointerEvents: subscriptionInfo()?.canceledAt ? "none" : "default", - backgroundColor: "#FFF", - border: "1px solid", - _hover: { - borderColor: "#22703E", - color: "#22703E", + bd_pro: { + title: t("username.DBPro"), + buttons: [ + { + text: t("username.cancelPlan"), + onClick: () => CancelModalPlan.onOpen(), + props: { + borderColor: subscriptionInfo()?.canceledAt ? "#ACAEB1" : "#2B8C4D", + color: subscriptionInfo()?.canceledAt ? "#ACAEB1" : "#2B8C4D", + pointerEvents: subscriptionInfo()?.canceledAt ? "none" : "default", backgroundColor: "#FFF", - } - } - }], - resources : [ - {name: t('username.dozensOfHighFrequencyDatasets')}, - {name: t('username.companyReferenceTable')}, - {name: t('username.downloadLimit1GB'), tooltip: t('username.downloadLimit1GBTooltip')}, - ] + border: "1px solid", + _hover: { + borderColor: "#22703E", + color: "#22703E", + backgroundColor: "#FFF", + }, + }, + }, + ], + resources: [ + { name: t("username.dozensOfHighFrequencyDatasets") }, + { name: t("username.companyReferenceTable") }, + { + name: t("username.downloadLimit1GB"), + tooltip: t("username.downloadLimit1GBTooltip"), + }, + ], }, - "bd_pro_empresas" : { - title: t('username.DBEnterprise'), - buttons : [{ - text: t('username.cancelPlan'), - onClick: () => CancelModalPlan.onOpen(), - props: { - borderColor: subscriptionInfo()?.canceledAt ? "#ACAEB1" : "#2B8C4D", - color: subscriptionInfo()?.canceledAt ? "#ACAEB1" : "#2B8C4D", - pointerEvents: subscriptionInfo()?.canceledAt ? "none" : "default", - backgroundColor: "#FFF", - border: "1px solid", - _hover: { - borderColor: "#22703E", - color: "#22703E", + bd_pro_empresas: { + title: t("username.DBEnterprise"), + buttons: [ + { + text: t("username.cancelPlan"), + onClick: () => CancelModalPlan.onOpen(), + props: { + borderColor: subscriptionInfo()?.canceledAt ? "#ACAEB1" : "#2B8C4D", + color: subscriptionInfo()?.canceledAt ? "#ACAEB1" : "#2B8C4D", + pointerEvents: subscriptionInfo()?.canceledAt ? "none" : "default", backgroundColor: "#FFF", - } - } - }], - resources : [ - {name: t('username.accessFor10Accounts')}, - {name: t('username.prioritySupport')} - ]} - } + border: "1px solid", + _hover: { + borderColor: "#22703E", + color: "#22703E", + backgroundColor: "#FFF", + }, + }, + }, + ], + resources: [ + { name: t("username.accessFor10Accounts") }, + { name: t("username.prioritySupport") }, + ], + }, + }; - const defaultResource = resources["BD Gratis"] - const planResource = resources[userData?.proSubscription] - const planCanceled = subscriptionInfo()?.canceledAt + const defaultResource = resources["BD Gratis"]; + const planResource = resources[userData?.proSubscription]; + const planCanceled = subscriptionInfo()?.canceledAt; - const controlResource = () => { - return planActive ? planResource : defaultResource - } + const controlResource = () => { + return planActive ? planResource : defaultResource; + }; const ListFeature = ({ elm, index, notIncludes = false }) => { return ( - {notIncludes ? - - : - - } - {elm.name} - {elm.tooltip && + {notIncludes ? ( + + ) : ( + + )} + + {elm.name} + + {elm.tooltip && ( - + - } + )} - ) - } + ); + }; const openModalSucess = () => { - PaymentModal.onClose() - SucessPaymentModal.onOpen() - } + PaymentModal.onClose(); + SucessPaymentModal.onOpen(); + }; const openModalErro = () => { - PaymentModal.onClose() - ErroPaymentModal.onOpen() - } + PaymentModal.onClose(); + ErroPaymentModal.onOpen(); + }; async function cancelSubscripetion() { - const reg = new RegExp("(?<=:).*") - const [ id ] = reg.exec(userData.id) - - const subscriptionActive = await fetch(`/api/stripe/getSubscriptionActive?p=${btoa(id)}`, {method: "GET"}) - .then(res => res.json()) - - const result = await fetch(`/api/stripe/removeSubscription?p=${btoa(subscriptionActive)}`, {method: "GET"}) - .then(res => res.json()) - - if(result?.success === false) { - setIsLoadingCanSub(false) - CancelModalPlan.onClose() + const reg = new RegExp("(?<=:).*"); + const [id] = reg.exec(userData.id); + + const subscriptionActive = await fetch( + `/api/stripe/getSubscriptionActive?p=${btoa(id)}`, + { method: "GET" }, + ).then((res) => res.json()); + + const result = await fetch( + `/api/stripe/removeSubscription?p=${btoa(subscriptionActive)}`, + { method: "GET" }, + ).then((res) => res.json()); + + if (result?.success === false) { + setIsLoadingCanSub(false); + CancelModalPlan.onClose(); } - const user = await fetch(`/api/user/getUser?p=${btoa(id)}`, {method: "GET"}) - .then(res => res.json()) - cookies.set('userBD', JSON.stringify(user)) - window.open(`/user/${userData.username}?plans_and_payment`, "_self") + const user = await fetch(`/api/user/getUser?p=${btoa(id)}`, { + method: "GET", + }).then((res) => res.json()); + cookies.set("userBD", JSON.stringify(user)); + window.open(`/user/${userData.username}?plans_and_payment`, "_self"); } async function closeModalSucess() { - const reg = new RegExp("(?<=:).*") - const [ id ] = reg.exec(userData.id) - - let user - let attempts = 0 - const maxAttempts = 10 - const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)) - - while (!user?.internalSubscription?.edges?.[0]?.node && attempts < maxAttempts) { - user = await fetch(`/api/user/getUser?p=${btoa(id)}`, { method: "GET" }) - .then((res) => res.json()) + const reg = new RegExp("(?<=:).*"); + const [id] = reg.exec(userData.id); + + let user; + let attempts = 0; + const maxAttempts = 10; + const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); + + while ( + !user?.internalSubscription?.edges?.[0]?.node && + attempts < maxAttempts + ) { + user = await fetch(`/api/user/getUser?p=${btoa(id)}`, { + method: "GET", + }).then((res) => res.json()); if (user?.internalSubscription?.edges?.[0]?.node) { - cookies.set("userBD", JSON.stringify(user)) - break + cookies.set("userBD", JSON.stringify(user)); + break; } - attempts++ - await delay(10000) + attempts++; + await delay(10000); } - if(isLoadingH === true) return window.open("/", "_self") - window.open(`/user/${userData.username}?plans_and_payment`, "_self") + if (isLoadingH === true) return window.open("/", "_self"); + window.open(`/user/${userData.username}?plans_and_payment`, "_self"); } - function formatTimeStamp (value) { - if(value === null || value === undefined) return t("username.noDate") - const date = new Date(value) - const options = { day: '2-digit', month: 'long', year: 'numeric' } - const formattedDate = date.toLocaleDateString('pt-BR', options) - return formattedDate + function formatTimeStamp(value) { + if (value === null || value === undefined) return t("username.noDate"); + const date = new Date(value); + const options = { day: "2-digit", month: "long", year: "numeric" }; + const formattedDate = date.toLocaleDateString("pt-BR", options); + return formattedDate; } - function formattedPlanInterval (value, variant = false) { - if(variant) { - if(value === "month") return t('username.month') - if(value === "year") return t('username.year') + function formattedPlanInterval(value, variant = false) { + if (variant) { + if (value === "month") return t("username.month"); + if (value === "year") return t("username.year"); } else { - if(value === "month") return t('username.monthly') - if(value === "year") return t('username.annually') + if (value === "month") return t("username.monthly"); + if (value === "year") return t("username.annually"); } } function changeIntervalPlanCheckout() { - let togglerValue = !toggleAnual ? "year" : "month" - const value = Object.values(plans).find(elm => elm.interval === togglerValue && elm.productSlug === checkoutInfos?.productSlug) - setCheckoutInfos(value) - setCoupon("") - setValueCoupon("") - setPlan(value._id) - setToggleAnual(!toggleAnual) + let togglerValue = !toggleAnual ? "year" : "month"; + const value = Object.values(plans).find( + (elm) => + elm.interval === togglerValue && + elm.productSlug === checkoutInfos?.productSlug, + ); + setCheckoutInfos(value); + setCoupon(""); + setValueCoupon(""); + setPlan(value._id); + setToggleAnual(!toggleAnual); } async function validateStripeCoupon() { - if(valueCoupon === "") return - setErrCoupon(false) + if (valueCoupon === "") return; + setErrCoupon(false); - const result = await fetch(`/api/stripe/validateStripeCoupon?p=${btoa(plan)}&c=${btoa(valueCoupon)}`, { method: "GET" }) - .then(res => res.json()) + const result = await fetch( + `/api/stripe/validateStripeCoupon?p=${btoa(plan)}&c=${btoa(valueCoupon)}`, + { method: "GET" }, + ).then((res) => res.json()); - if(result?.isValid === false || result?.errors || !result) { - setValueCoupon("") - setErrCoupon(true) + if (result?.isValid === false || result?.errors || !result) { + setValueCoupon(""); + setErrCoupon(true); } - if(result?.duration === "repeating" && toggleAnual === true) { - setValueCoupon("") - setErrCoupon(true) + if (result?.duration === "repeating" && toggleAnual === true) { + setValueCoupon(""); + setErrCoupon(true); } else { - setCouponInfos(result) - setCoupon(valueCoupon) + setCouponInfos(result); + setCoupon(valueCoupon); } } const CouponDisplay = () => { - let limitText + let limitText; - if(couponInfos?.duration === "once") limitText = toggleAnual ? t('username.validFor1Year') : t('username.validFor1Month') - if(couponInfos?.duration === "repeating") limitText = `${t('username.validFor')} ${couponInfos?.durationInMonths} ${couponInfos?.durationInMonths.length === 1 ? t('username.month') : t('username.months')})` + if (couponInfos?.duration === "once") + limitText = toggleAnual + ? t("username.validFor1Year") + : t("username.validFor1Month"); + if (couponInfos?.duration === "repeating") + limitText = `${t("username.validFor")} ${couponInfos?.durationInMonths} ${couponInfos?.durationInMonths.length === 1 ? t("username.month") : t("username.months")})`; return ( <> - {t('username.coupon')} {coupon.toUpperCase()} {limitText} + + {t("username.coupon")} {coupon.toUpperCase()} {limitText} + - - {couponInfos?.discountAmount?.toLocaleString('pt-BR', { style: 'currency', currency: 'BRL', minimumFractionDigits: 2 })}/{formattedPlanInterval(checkoutInfos?.interval, true)} + + -{" "} + {couponInfos?.discountAmount?.toLocaleString("pt-BR", { + style: "currency", + currency: "BRL", + minimumFractionDigits: 2, + })} + /{formattedPlanInterval(checkoutInfos?.interval, true)} + - ) - } + ); + }; const TotalToPayDisplay = () => { - let value - - if(couponInfos?.discountAmount) { - value = (checkoutInfos?.amount-couponInfos?.discountAmount).toLocaleString('pt-BR', { style: 'currency', currency: 'BRL', minimumFractionDigits: 2 }) + let value; + + if (couponInfos?.discountAmount) { + value = ( + checkoutInfos?.amount - couponInfos?.discountAmount + ).toLocaleString("pt-BR", { + style: "currency", + currency: "BRL", + minimumFractionDigits: 2, + }); } else { - value = checkoutInfos?.amount?.toLocaleString('pt-BR', { style: 'currency', currency: 'BRL', minimumFractionDigits: 2 }) + value = checkoutInfos?.amount?.toLocaleString("pt-BR", { + style: "currency", + currency: "BRL", + minimumFractionDigits: 2, + }); } return ( <> - {t('username.totalToPay')} + + {t("username.totalToPay")} + - {value}/{formattedPlanInterval(checkoutInfos?.interval, true)} + + {value}/{formattedPlanInterval(checkoutInfos?.interval, true)} + - ) - } + ); + }; async function handlerEmailGcp() { - setErrEmailGCP(false) - setIsLoadingEmailChange(true) + setErrEmailGCP(false); + setIsLoadingEmailChange(true); function isValidEmail(email) { - const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ - return emailRegex.test(email) + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + return emailRegex.test(email); } - if(!isValidEmail(emailGCP)) return setErrEmailGCP(true) + if (!isValidEmail(emailGCP)) return setErrEmailGCP(true); - const response = await fetch(`/api/user/changeUserGcpEmail?p=${btoa(emailGCP)}`) - .then(res => res.json()) + const response = await fetch( + `/api/user/changeUserGcpEmail?p=${btoa(emailGCP)}`, + ).then((res) => res.json()); - if(response.ok) { - if(emailGCP !== userData?.email) { - if(emailGCP !== userData?.gcpEmail) { - triggerGAEvent("troca_do_email_gcp",`checkout_de_pagamento`) + if (response.ok) { + if (emailGCP !== userData?.email) { + if (emailGCP !== userData?.gcpEmail) { + triggerGAEvent("troca_do_email_gcp", `checkout_de_pagamento`); } } - setIsLoadingEmailChange(false) - EmailModal.onClose() - PaymentModal.onOpen() + setIsLoadingEmailChange(false); + EmailModal.onClose(); + PaymentModal.onOpen(); } else { - setErrEmailGCP(true) + setErrEmailGCP(true); } } useEffect(() => { - if(valueCoupon === "") { - setCoupon("") - setCouponInfos("") + if (valueCoupon === "") { + setCoupon(""); + setCouponInfos(""); } - }, [valueCoupon]) + }, [valueCoupon]); useEffect(() => { - if(isLoading === true || isLoadingH === true) closeModalSucess() - if(isLoadingCanSub === true) cancelSubscripetion() - }, [isLoading, isLoadingH, isLoadingCanSub]) + if (isLoading === true || isLoadingH === true) closeModalSucess(); + if (isLoadingCanSub === true) cancelSubscripetion(); + }, [isLoading, isLoadingH, isLoadingCanSub]); return ( - + {/* stripe */} { - setToggleAnual(true) - setValueCoupon("") - if(query.i) return window.open(`/user/${userData.username}?plans_and_payment`, "_self") - PaymentModal.onClose() + setToggleAnual(true); + setValueCoupon(""); + if (query.i) + return window.open( + `/user/${userData.username}?plans_and_payment`, + "_self", + ); + PaymentModal.onClose(); }} propsModalContent={{ width: "100%", - maxWidth:"1008px", - margin: "24px" + maxWidth: "1008px", + margin: "24px", }} isCentered={isMobileMod() ? false : true} > - - {t('username.step2of2')} + + {t("username.step2of2")} - - {t('username.payment')} - + {t("username.payment")} - - - - - {checkoutInfos?.productName} - + + + + {checkoutInfos?.productName} { - PaymentModal.onClose() - setToggleAnual(true) - setCoupon("") - setValueCoupon("") - PlansModal.onOpen() + PaymentModal.onClose(); + setToggleAnual(true); + setCoupon(""); + setValueCoupon(""); + PlansModal.onOpen(); }} - >{t('username.changePlan')} + > + {t("username.changePlan")} + - {toggleAnual ? - changeIntervalPlanCheckout()} - /> - : - changeIntervalPlanCheckout()} - /> - } - - {t('username.annualDiscount')} - + {toggleAnual ? ( + changeIntervalPlanCheckout()} + /> + ) : ( + changeIntervalPlanCheckout()} + /> + )} + {t("username.annualDiscount")} - {t('username.save20')} + {t("username.save20")} - - - {t('username.discountCoupon')} - + + {t("username.discountCoupon")} @@ -586,7 +659,7 @@ export default function PlansAndPayment ({ userData }) { inputFocus={couponInputFocus} changeInputFocus={setCouponInputFocus} width="100%" - placeholder={t('username.enterCoupon')} + placeholder={t("username.enterCoupon")} inputElementStyle={{ display: "none", }} @@ -594,22 +667,22 @@ export default function PlansAndPayment ({ userData }) { paddingLeft: "16px !important", paddingRight: "40px !important", borderRadius: "8px", - height: "44px" + height: "44px", }} /> - {valueCoupon && + {valueCoupon && ( setValueCoupon("")} /> - } + )} - {errCoupon && + {errCoupon && ( - {t('username.enterValidCoupon')} + {" "} + {t("username.enterValidCoupon")} - } + )} - {t('username.trialPeriod')} + {t("username.trialPeriod")} @@ -669,25 +739,46 @@ export default function PlansAndPayment ({ userData }) { color="#464A51" > - {t('username.subtotal')} + {t("username.subtotal")} - {checkoutInfos?.amount?.toLocaleString('pt-BR', { style: 'currency', currency: 'BRL', minimumFractionDigits: 2 })}/{formattedPlanInterval(checkoutInfos?.interval, true)} + + {checkoutInfos?.amount?.toLocaleString("pt-BR", { + style: "currency", + currency: "BRL", + minimumFractionDigits: 2, + })} + /{formattedPlanInterval(checkoutInfos?.interval, true)} + - {couponInfos?.isValid && - - } + {couponInfos?.isValid && } - {(couponInfos?.duration === "once" || couponInfos?.duration === "repeating") && + {(couponInfos?.duration === "once" || + couponInfos?.duration === "repeating") && ( - {t('username.couponDuration', { returnObjects: true })[0]}{couponInfos?.duration === "once" && 2} {couponInfos?.duration === "repeating" && couponInfos?.durationInMonths + 1}º {formattedPlanInterval(checkoutInfos?.interval, true)} {!hasSubscribed && "e 7º dia"}{t('username.couponDuration', { returnObjects: true })[1]}{checkoutInfos?.amount?.toLocaleString('pt-BR', { style: 'currency', currency: 'BRL', minimumFractionDigits: 2 })}/{formattedPlanInterval(checkoutInfos?.interval, true)}. + {t("username.couponDuration", { returnObjects: true })[0]} + {couponInfos?.duration === "once" && 2}{" "} + {couponInfos?.duration === "repeating" && + couponInfos?.durationInMonths + 1} + º {formattedPlanInterval(checkoutInfos?.interval, true)}{" "} + {!hasSubscribed && "e 7º dia"} + {t("username.couponDuration", { returnObjects: true })[1]} + {checkoutInfos?.amount?.toLocaleString("pt-BR", { + style: "currency", + currency: "BRL", + minimumFractionDigits: 2, + })} + /{formattedPlanInterval(checkoutInfos?.interval, true)}. - } + )} - + - - {t('username.paymentDetails')} - + {t("username.paymentDetails")} setIsLoadingClientSecret(e)} /> - - @@ -741,54 +833,47 @@ export default function PlansAndPayment ({ userData }) { { - setEmailGCP(userData?.gcpEmail || userData?.email) - setErrEmailGCP(false) - EmailModal.onClose() + setEmailGCP(userData?.gcpEmail || userData?.email); + setErrEmailGCP(false); + EmailModal.onClose(); }} propsModalContent={{ width: "100%", - maxWidth:"1008px", + maxWidth: "1008px", margin: "24px", }} isCentered={isMobileMod() ? false : true} > - - {t('username.step1of2')} + + {t("username.step1of2")} - - - {t('username.BQEmail')} - + + {t("username.BQEmail")} - - {t('username.BQEmailDescription1')} - {t('username.BQEmailDescription2')} - {t('username.BQEmailDescription3')} + + {t("username.BQEmailDescription1")} + + {t("username.BQEmailDescription2")} + + {t("username.BQEmailDescription3")} - {t('username.BQEmail')} + {t("username.BQEmail")} - {errEmailGCP && + {errEmailGCP && ( - {t('username.pleaseEnterValidEmail')} + {" "} + {t("username.pleaseEnterValidEmail")} - } + )} @@ -871,17 +953,17 @@ export default function PlansAndPayment ({ userData }) { isOpen={SucessPaymentModal.isOpen} propsModalContent={{ width: "100%", - maxWidth: "656px" + maxWidth: "656px", }} onClose={() => setIsLoading(true)} > - + @@ -896,24 +978,29 @@ export default function PlansAndPayment ({ userData }) { marginBottom="24px" spacing={0} > - - - {t('username.congratulations')} - + + {t("username.congratulations")} - {t('username.BQEmailDescription4')} {emailGCP}. - {t('username.BQEmailDescription5')} - - {t('username.BQEmailDescription6')} {t('username.BQEmailDescription7')} + {t("username.BQEmailDescription4")}{" "} + + {emailGCP} + + .{t("username.BQEmailDescription5")} + {t("username.BQEmailDescription6")}{" "} + + {t("username.BQEmailDescription7")} + window.open(`/user/${userData?.username}?big_query`, "_self")} + width={{ base: "100%", lg: "50%" }} + onClick={() => + window.open(`/user/${userData?.username}?big_query`, "_self") + } isLoading={isLoading} > - {t('username.continueSettings')} + {t("username.continueSettings")} @@ -950,12 +1039,12 @@ export default function PlansAndPayment ({ userData }) { onClose={ErroPaymentModal.onClose} > - + @@ -970,43 +1059,37 @@ export default function PlansAndPayment ({ userData }) { marginBottom="24px" spacing={0} > - - {t('username.paymentFailed')} - - {t('username.paymentError')} + + {t("username.paymentFailed")} + + {t("username.paymentError")} {t('username.contactUs')} + > + {t("username.contactUs")} + . @@ -1016,38 +1099,31 @@ export default function PlansAndPayment ({ userData }) { isOpen={PlansModal.isOpen} onClose={PlansModal.onClose} propsModal={{ - scrollBehavior: {base: "outside", lg: "inside"} + scrollBehavior: { base: "outside", lg: "inside" }, }} propsModalContent={{ maxWidth: "fit-content", minWidth: "fit-content", maxHeight: "fit-content", - margin: {base: "0", lg: "24px"}, + margin: { base: "0", lg: "24px" }, padding: "32px 22px 26px 22px", - borderRadius: {base: "0", lg: "20px"}, + borderRadius: { base: "0", lg: "20px" }, }} isCentered={false} > - - {t('username.comparePlans')} + + {t("username.comparePlans")} - + - {t('username.annualDiscount')} + {t("username.annualDiscount")} - {t('username.save20')} + {t("username.save20")} {t('username.DBFreeSubtitle')}} + title={t("username.DBFree")} + subTitle={<>{t("username.DBFreeSubtitle")}} price={"0"} - textResource={t('username.resources')} + textResource={t("username.resources")} resources={[ - {name: t('username.processedTables')}, - {name: t('username.integratedData'), tooltip: t('username.integratedDataTooltip')}, - {name: t('username.cloudAccess')}, - {name: t('username.sqlPythonRAccess')}, - {name: t('username.biIntegration')}, - {name: t('username.downloadLimit100MB'), tooltip: t('username.downloadLimit100MBTooltip')}, + { name: t("username.processedTables") }, + { + name: t("username.integratedData"), + tooltip: t("username.integratedDataTooltip"), + }, + { name: t("username.cloudAccess") }, + { name: t("username.sqlPythonRAccess") }, + { name: t("username.biIntegration") }, + { + name: t("username.downloadLimit100MB"), + tooltip: t("username.downloadLimit100MBTooltip"), + }, ]} button={{ - text: t('username.exploreFeatures'), + text: t("username.exploreFeatures"), href: "/search", noHasModal: true, }} /> {t('username.DBProSubtitle')}} - price={plans?.[`bd_pro_${toggleAnual ? "year" : "month"}`].amount || 444} + title={t("username.DBPro")} + subTitle={<>{t("username.DBProSubtitle")}} + price={ + plans?.[`bd_pro_${toggleAnual ? "year" : "month"}`].amount || + 444 + } anualPlan={toggleAnual} - textResource={t('username.allDBFreeResources')} + textResource={t("username.allDBFreeResources")} resources={[ - {name: t('username.dozensOfHighFrequencyDatasets')}, - {name: t('username.companyReferenceTable')}, - {name: t('username.downloadLimit1GB'), tooltip: t('username.downloadLimit1GBTooltip')} + { name: t("username.dozensOfHighFrequencyDatasets") }, + { name: t("username.companyReferenceTable") }, + { + name: t("username.downloadLimit1GB"), + tooltip: t("username.downloadLimit1GBTooltip"), + }, ]} button={{ - text: `${userData?.proSubscription === "bd_pro" ? t('username.currentPlan') : hasSubscribed ? t('username.subscribe') : t('username.startFreeTrial')}`, - onClick: userData?.proSubscription === "bd_pro" ? () => {} : () => { - setPlan(plans?.[`bd_pro_${toggleAnual ? "year" : "month"}`]._id) - PlansModal.onClose() - EmailModal.onOpen() - }, - isCurrentPlan: userData?.proSubscription === "bd_pro" ? true : false, + text: `${userData?.proSubscription === "bd_pro" ? t("username.currentPlan") : hasSubscribed ? t("username.subscribe") : t("username.startFreeTrial")}`, + onClick: + userData?.proSubscription === "bd_pro" + ? () => {} + : () => { + setPlan( + plans?.[`bd_pro_${toggleAnual ? "year" : "month"}`] + ._id, + ); + PlansModal.onClose(); + EmailModal.onOpen(); + }, + isCurrentPlan: + userData?.proSubscription === "bd_pro" ? true : false, }} /> {t('username.DBEnterpriseSubtitle')}} - price={plans?.[`bd_empresas_${toggleAnual ? "year" : "month"}`].amount || 3360} + title={t("username.DBEnterprise")} + subTitle={<>{t("username.DBEnterpriseSubtitle")}} + price={ + plans?.[`bd_empresas_${toggleAnual ? "year" : "month"}`] + .amount || 3360 + } anualPlan={toggleAnual} - textResource={t('username.allDBProResources')} + textResource={t("username.allDBProResources")} resources={[ - {name: t('username.accessFor10Accounts')}, - {name: t('username.prioritySupport')} + { name: t("username.accessFor10Accounts") }, + { name: t("username.prioritySupport") }, ]} button={{ - text: `${userData?.proSubscription === "bd_pro_empresas" ? t('username.currentPlan') : hasSubscribed ? t('username.subscribe') : t('username.startFreeTrial')}`, - onClick: userData?.proSubscription === "bd_pro_empresas" ? () => {} : () => { - setPlan(plans?.[`bd_empresas_${toggleAnual ? "year" : "month"}`]._id) - PlansModal.onClose() - EmailModal.onOpen() - }, - isCurrentPlan: userData?.proSubscription === "bd_pro_empresas" ? true : false, + text: `${userData?.proSubscription === "bd_pro_empresas" ? t("username.currentPlan") : hasSubscribed ? t("username.subscribe") : t("username.startFreeTrial")}`, + onClick: + userData?.proSubscription === "bd_pro_empresas" + ? () => {} + : () => { + setPlan( + plans?.[ + `bd_empresas_${toggleAnual ? "year" : "month"}` + ]._id, + ); + PlansModal.onClose(); + EmailModal.onOpen(); + }, + isCurrentPlan: + userData?.proSubscription === "bd_pro_empresas" + ? true + : false, }} /> @@ -1168,41 +1276,41 @@ export default function PlansAndPayment ({ userData }) { - {t('username.planChange')} + {t("username.planChange")} - {t('username.changePlanInstructions')} + {t("username.changePlanInstructions")} @@ -1211,27 +1319,26 @@ export default function PlansAndPayment ({ userData }) { - - {t('username.confirmPlanCancellation')} + + + {t("username.confirmPlanCancellation")} + @@ -1265,27 +1372,32 @@ export default function PlansAndPayment ({ userData }) { - + - {planActive ? planCanceled ? t('username.canceled') : t('username.active') : t('username.active')} + {planActive + ? planCanceled + ? t("username.canceled") + : t("username.active") + : t("username.active")} - {controlResource().title} - + + {controlResource().title} + + {formattedPlanInterval(subscriptionInfo()?.planInterval)} - - {subscriptionInfo()?.canceledAt ? t('username.planAccessUntil') : t('username.nextAutoRenewal')} - {formatTimeStamp(subscriptionInfo()?.canceledAt ? subscriptionInfo()?.canceledAt : subscriptionInfo()?.nextBillingCycle)} + + {subscriptionInfo()?.canceledAt + ? t("username.planAccessUntil") + : t("username.nextAutoRenewal")} + + {formatTimeStamp( + subscriptionInfo()?.canceledAt + ? subscriptionInfo()?.canceledAt + : subscriptionInfo()?.nextBillingCycle, + )} - - {t('username.profilePicture')} - + {t("username.profilePicture")} - - - - - - - - { menuAvatar.onOpen() }} + + + + + + + + { + menuAvatar.onOpen(); + }} + > + - + + + + + + + + - - - - - - - + + + + hanlderRemovePicture()} > - - {t('username.updatePicture')} - - - - hanlderRemovePicture()} - >{t('username.removePicture')} - - - + {t("username.removePicture")} + + + + - ) -} \ No newline at end of file + ); +} diff --git a/next/components/organisms/componentsUserPage/index.js b/next/components/organisms/componentsUserPage/index.js index 4143efaef..23bc561b8 100644 --- a/next/components/organisms/componentsUserPage/index.js +++ b/next/components/organisms/componentsUserPage/index.js @@ -13,5 +13,5 @@ export { PlansAndPayment, BigQuery, Accesses, - DataAPI -} \ No newline at end of file + DataAPI, +}; diff --git a/next/components/templates/404.js b/next/components/templates/404.js index f2dec25ae..a0974ce4b 100644 --- a/next/components/templates/404.js +++ b/next/components/templates/404.js @@ -1,6 +1,4 @@ -import { - Center, -} from "@chakra-ui/react"; +import { Center } from "@chakra-ui/react"; import FourOFourImage from "../../public/img/fourOFour"; export default function FourOFour({ children, ...props }) { @@ -12,11 +10,8 @@ export default function FourOFour({ children, ...props }) { flexDirection="column" {...props} > - + {children} - ) -} \ No newline at end of file + ); +} diff --git a/next/components/templates/500.js b/next/components/templates/500.js index e0a596164..0b5948774 100644 --- a/next/components/templates/500.js +++ b/next/components/templates/500.js @@ -1,7 +1,4 @@ -import { - Center, - Text -} from "@chakra-ui/react"; +import { Center, Text } from "@chakra-ui/react"; import InternalErrorImage from "../../public/img/internalError"; export default function InternalError({ children, ...props }) { @@ -13,11 +10,8 @@ export default function InternalError({ children, ...props }) { flexDirection="column" {...props} > - + {children} - ) -} \ No newline at end of file + ); +} diff --git a/next/components/templates/main.js b/next/components/templates/main.js index e15907cb3..43edcba11 100644 --- a/next/components/templates/main.js +++ b/next/components/templates/main.js @@ -12,25 +12,19 @@ export function MainPageTemplate({ locale, ...style }) { - return ( - - - + + {children} -