Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { useState, useEffect } from "react";
- import { supabase } from "../api/auth/supabaseClient";
- import Dropzone, { useDropzone } from "React-dropzone";
- import {
- Button,
- Flex,
- FormControl,
- FormLabel,
- Heading,
- Input,
- Stack,
- useColorModeValue,
- HStack,
- Avatar,
- AvatarBadge,
- IconButton,
- Center,
- Container,
- useBreakpointValue,
- Text,
- useDisclosure,
- Icon,
- Square,
- VStack
- } from '@chakra-ui/react';
- import { SmallCloseIcon } from "@chakra-ui/icons";
- import toast from "react-hot-toast";
- import { FiUploadCloud } from "react-icons/fi";
- export default function Account({ session }) {
- const {
- isOpen: isLoading,
- onOpen: startLoading,
- onClose: stopLoading
- } = useDisclosure();
- const [username, setUsername] = useState(null);
- const [avatar_url, setAvatarUrl] = useState(null);
- const [uploading, setUploading] = useState(false)
- useEffect(() => {
- getProfile()
- }, [session])
- function Comprimento(username) {
- if (username.length < 3) {
- toast.error("O nome de utilizador deve ter pelo menos 3 caracteres")
- }
- else {
- updateProfile()
- }
- }
- async function getProfile() {
- try {
- isLoading
- const user = supabase.auth.user();
- let { data, error, status } = await supabase
- .from("profiles")
- .select(`username, avatar_url`)
- .eq("id", user.id)
- .single();
- if (error && status !== 406) throw error;
- if (data) {
- setUsername(data.username);
- setAvatarUrl(data.avatar_url);
- if (data.avatar_url !== null) {
- downloadImage(data.avatar_url);
- }
- }
- } catch (error) {
- toast.error(error.message);
- }
- finally {
- stopLoading;
- }
- }
- async function updateProfile() {
- try {
- isLoading;
- const user = supabase.auth.user();
- const updates = {
- id: user.id,
- username,
- avatar_url,
- updated_at: new Date(),
- };
- let { error } = await supabase.from("profiles").upsert(updates, {
- returning: "minimal",
- });
- if (error) throw error;
- toast.success("Perfil atualizado com sucesso!");
- } catch (error) {
- toast.error("Nome de utilizador já existe!");
- } finally {
- stopLoading
- getProfile
- }
- }
- async function downloadImage(path) {
- try {
- const { data, error } = await supabase.storage.from('avatars').download(path)
- if (error) {
- throw error
- }
- const url = URL.createObjectURL(data)
- setAvatarUrl(url)
- } catch (error) {
- console.log('Erro ao baixar a imagem: ', error.message)
- }
- }
- async function uploadAvatar(event) {
- try {
- setUploading(true)
- if (!event.target.files || event.target.files.length === 0) {
- throw new Error('Tens de escolher um Avatar')
- }
- const file = event.target.files[0]
- const fileExt = file.name.split('.').pop()
- const fileName = `${Math.random()}.${fileExt}`
- const filePath = `${fileName}`
- let { error: uploadError } = await supabase.storage
- .from('avatars')
- .upload(filePath, file)
- if (uploadError) {
- throw uploadError
- }
- setAvatarUrl(fileName)
- } catch (error) {
- alert(error.message)
- }
- }
- return (
- <>
- <Container
- maxW="lg"
- py={{ base: "12", md: "24" }}
- px={{ base: "0", sm: "8" }}
- >
- <Stack spacing="8">
- <Stack spacing="6">
- <Stack spacing={{ base: "2", md: "3" }} textAlign="center">
- <Heading size={useBreakpointValue({ base: "xs", md: "sm" })}>
- Perfil
- </Heading>
- <HStack spacing="1" justify="center">
- <Text color="muted">
- Escolhe uma imagem de perfil e um nome de utilizador
- </Text>
- </HStack>
- </Stack>
- </Stack>
- <Stack
- spacing="10"
- py={{ base: "0", sm: "8" }}
- px={{ base: "4", sm: "10" }}
- bg={useBreakpointValue({ base: "transparent", sm: "bg-surface" })}
- boxShadow={{ base: "none", sm: useColorModeValue("md", "md-dark") }}
- borderRadius={{ base: "none", sm: "xl" }}
- >
- <FormControl id="userName" isRequired>
- <Stack direction={["column", "row"]} spacing={6}>
- <Center>
- <Avatar size="xl" src={avatar_url}>
- <AvatarBadge
- as={IconButton}
- size="sm"
- rounded="full"
- top="-10px"
- colorScheme="red"
- aria-label="remove Image"
- icon={<SmallCloseIcon />}
- >
- </AvatarBadge>
- </Avatar>
- </Center>
- <Center w="full">
- <VStack spacing="3">
- <VStack>
- <Square size="10" bg="bg-subtle" borderRadius="lg">
- <Icon as={FiUploadCloud} boxSize="5" _hover={{ textDecor: 'none' }} color="muted" />
- </Square>
- <VStack spacing="1">
- <HStack spacing="1" whiteSpace="nowrap">
- {/** <Button variant="link" colorScheme="blue" size="sm">Clique</Button> */}
- <Input type="file" variant="link" colorScheme="blue" size="sm" onChange={uploadAvatar}>
- </Input>
- <Text fontSize="sm" color="muted">
- ou arrasta e larga
- </Text>
- </HStack>
- <Text fontSize="xs" color="muted">
- PNG, JPG ou GIF até 2MB
- </Text>
- </VStack>
- </VStack>
- </VStack>
- </Center>
- </Stack>
- </FormControl>
- <FormControl id="userName">
- <FormLabel>Nome de Utilizador</FormLabel>
- <Input
- _placeholder={{ color: "gray.500" }}
- type="text"
- defaultValue={username}
- onChange={(e) => setUsername(e.target.value)}
- />
- </FormControl>
- <br />
- <Stack spacing={6} direction={["column", "row"]}>
- <Button
- isLoading={isLoading}
- onClick={() => { startLoading; Comprimento(username); }}
- variant="primary"
- w="full"
- >
- Guardar
- </Button>
- </Stack>
- </Stack>
- </Stack>
- </Container>
- </>
- );
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement