Skip to content

Commit

Permalink
Merge pull request #736 from basedosdados/feat/profile-photo
Browse files Browse the repository at this point in the history
User config ajust
  • Loading branch information
AldemirLucas authored Jan 19, 2024
2 parents dbbf68a + cff5aef commit 122a527
Show file tree
Hide file tree
Showing 25 changed files with 939 additions and 98 deletions.
83 changes: 83 additions & 0 deletions next/components/molecules/Cookies.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import {
Box,
Text,
CloseButton,
HStack
} from "@chakra-ui/react";
import { useState, useEffect } from "react";
import cookies from "js-cookie";
import RoundedButton from "../atoms/RoundedButton";
import Link from "../atoms/Link";
import { useCheckMobile } from "../../hooks/useCheckMobile.hook";

export default function ConfirmCookies() {
const [isOpen, setIsOpen] = useState(false)

useEffect(() => {
const res = cookies.get("cookieAccepted")

if(res === undefined) setIsOpen(true)
}, [])

const handleClose = () => {
setIsOpen(false)
}

const handleConfirm = () => {
cookies.set("cookieAccepted", "true",{ expires: 366 })
setIsOpen(false)
}

if(!isOpen) return null

return (
<Box
bottom={0}
left={0}
position="fixed"
margin={useCheckMobile() ? "0 auto" :"0 0 40px 40px"}
zIndex={10000}
backgroundColor="#FFF"
maxWidth="400px"
boxShadow="0 1.6px 16px 0 rgba(100, 96, 103, 0.16)"
padding="16px"
borderRadius="30px"
>
<HStack spacing={0} marginBottom="16px" justifyContent="space-between">
<Text
width="fit-content"
fontFamily="Ubuntu"
fontSize="18px"
lineHeight="40px"
fontWeight="500"
color="#252A32"
>Nossos Cookies</Text>

<CloseButton
_hover={{backgroundColor: "transparent", color:"#42B0FF"}}
onClick={() => handleClose()}
/>
</HStack>

<Text
fontFamily="ubuntu"
marginBottom="8px"
color="#252A42"
>
Os cookies são essenciais para a funcionalidade completa de nossa plataforma. Ao continuar, você concorda com o uso desses cookies para garantir uma experiência de usuário eficaz. Veja mais sobre nossas <Link color="#42B0FF" href="/termos-e-privacidade" target="_blank">Política de Cookies</Link>
</Text>

<Box width="100%" display="flex" >
<RoundedButton
borderRadius="30px"
width={useCheckMobile() ? "100%" : "fit-content"}
_hover={{transform: "none", opacity: 0.8}}
onClick={() => handleConfirm()}
marginLeft="auto"
>
Concordo
</RoundedButton>
</Box>
</Box>
)
}
3 changes: 3 additions & 0 deletions next/components/molecules/Footer.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,9 @@ export default function Footer({ pages, ocult = false }) {
<FooterLink href="/perguntas-frequentes">
Perguntas frequentes
</FooterLink>
<FooterLink target="_self" href="/termos-e-privacidade">
Termos e Privacidade
</FooterLink>
<Link fontWeight="700" color="white" href="/#support">
Apoie o projeto
</Link>
Expand Down
200 changes: 200 additions & 0 deletions next/components/molecules/ImgCrop.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
import {
Stack,
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalBody,
ModalFooter,
ModalCloseButton
} from '@chakra-ui/react';
import { useState, useEffect, useRef } from 'react';
import ReactCrop from 'react-image-crop';
import cookies from 'js-cookie';
import { isMobileMod } from '../../hooks/useCheckMobile.hook';

import {
getUser,
updatePictureProfile
} from '../../pages/api/user'

import SectionTitle from '../atoms/SectionTitle';
import RoundedButton from '../atoms/RoundedButton';
import 'react-image-crop/dist/ReactCrop.css';
import styles from "../../styles/imgCrop.module.css";

export default function CropImage ({
isOpen,
onClose,
src,
id,
username,
email
}) {
const imgRef = useRef(null)
const [completedCrop, setCompletedCrop] = useState()
const [crop, setCrop] = useState()

useEffect(() => {
setCrop()
setCompletedCrop()
}, [!!isOpen])

async function handlerUpdatePicture() {
const image = imgRef.current

if (!image || !completedCrop) return null

const scaleX = image.naturalWidth / image.width;
const scaleY = image.naturalHeight / image.height;

const offscreen = new OffscreenCanvas(
completedCrop.width * scaleX,
completedCrop.height * scaleY,
)

const ctx = offscreen.getContext("2d")

if (!ctx) {
throw new Error("No 2d context")
}

ctx.drawImage(
image,
completedCrop.x * scaleX,
completedCrop.y * scaleY,
completedCrop.width * scaleX,
completedCrop.height * scaleY,
0,
0,
offscreen.width,
offscreen.height,
)

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 compressedDataUrl = tempCanvas.toDataURL("image/jpeg", quality)
const sizeKB = compressedDataUrl.length / 1024

if (sizeKB <= maxSizeKB) {
break;
}

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 getUser(email)
cookies.set('userBD', JSON.stringify(userData))
window.location.reload()
}
}

return (
<Modal
isOpen={isOpen}
onClose={onClose}
isCentered
margin="24px !important"
>
<ModalOverlay/>
<ModalContent
margin="24px"
minWidth={isMobileMod() ? "" : "536px"}
boxSizing="content-box"
padding="32px"
borderRadius="20px"
>
<ModalHeader padding="0">
<Stack>
<SectionTitle
lineHeight="40px"
>Corte sua nova foto de perfil</SectionTitle>
<ModalCloseButton
display={isMobileMod() ? "none" : "flex"}
fontSize="14px"
top="24px"
right="26px"
_hover={{backgroundColor: "transparent", color:"#42B0FF"}}
onClick={onClose}
/>
</Stack>
</ModalHeader>

<ModalBody padding="0">
<Stack
className={styles.containerImageCroped}
margin="24px 0"
overflow="hidden"
>
{!!src &&
<ReactCrop
crop={crop}
onChange={(c) => setCrop(c)}
onComplete={(c) => setCompletedCrop(c)}
aspect={1 / 1}
keepSelection={true}
circularCrop
>
<img ref={imgRef} src={src}/>
</ReactCrop>
}
</Stack>
</ModalBody>

<ModalFooter padding="0" width={isMobileMod() ? "100%" : "auto"}>
<Stack
flexDirection={isMobileMod() ? "column" : "row"}
spacing={0}
gap="24px"
width={isMobileMod() ? "100%" : "fit-content"}
>
<RoundedButton
borderRadius="30px"
backgroundColor="#FFF"
border="1px solid #42B0FF"
color="#42B0FF"
width={isMobileMod() ? "100%" : "fit-content"}
_hover={{transform: "none", opacity: 0.8}}
onClick={onClose}
>
Cancelar
</RoundedButton>
<RoundedButton
marginTop="16px"
borderRadius="30px"
_hover={{transform: "none", opacity: 0.8}}
onClick={() => handlerUpdatePicture()}
>
Salvar
</RoundedButton>
</Stack>
</ModalFooter>
</ModalContent>
</Modal>
)
}
2 changes: 2 additions & 0 deletions next/components/templates/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import UserContext from "../../context/user";
import SiteHead from "../atoms/SiteHead";
import Footer from "../molecules/Footer";
import Menu from "../molecules/Menu";
import Cookies from "../molecules/Cookies"

export function MainPageTemplate({
pages,
Expand All @@ -25,6 +26,7 @@ export function MainPageTemplate({
{children}
</Box>
<Footer pages={pages} ocult={cleanTemplate || userTemplate}/>
<Cookies/>
</Box>
</UserContext.Provider>
);
Expand Down
Loading

0 comments on commit 122a527

Please sign in to comment.