use google user avatar as profile phone

This commit is contained in:
João Geonizeli
2022-07-22 12:53:57 -03:00
parent 20781746e6
commit 9db59c071f
18 changed files with 72 additions and 252 deletions

View File

@@ -454,6 +454,7 @@ export type UpdateQuestionPayload = {
export type User = {
__typename?: 'User';
avatarUrl?: Maybe<Scalars['String']>;
email: Scalars['String'];
id: Scalars['ID'];
name: Scalars['String'];

View File

@@ -614,6 +614,7 @@ type UpdateQuestionPayload {
}
type User {
avatarUrl: String
email: String!
id: ID!
name: String!

View File

@@ -1,63 +0,0 @@
import React, { FC, useState } from "react";
import axios from "axios";
import { Alert } from "../Alert";
import { Button } from "../Button";
import { PhotoCrop } from "./PhotoCrop";
import { useCurrentUser } from "../../contexts";
import { Modal } from "../Modal";
type Props = {
isOpen: boolean
setIsOpen: (value: boolean) => void;
};
export const AvatarEditor: FC<Props> = ({ isOpen, setIsOpen }) => {
const [croppedImage, setCroppedImage] = useState<any>()
const [alert, setAlert] = useState<boolean>()
const { refetch, authToken } = useCurrentUser()
const instance = axios.create({
});
instance.defaults.headers.common.Authorization = `Bearer ${authToken}`;
const onSubmit = () => {
instance
.post("/update_avatar", {
upload: croppedImage,
})
.then((res) => {
if (res.status === 200) {
setIsOpen(false)
refetch()
} else {
setAlert(true);
}
})
.catch(() => {
setAlert(true);
});
};
return (
<Modal
title="Alterar Imagem de Perfil"
isOpen={isOpen}
setIsOpen={setIsOpen}
buttons={
<>
<Button onClick={() => setIsOpen(false)}>
Cancelar
</Button>
<Button type="primary" onClick={() => onSubmit()}>
Salvar
</Button>
</>
}
>
{alert && <Alert>Algo deu errado, tente novamente mais tarde.</Alert>}
<PhotoCrop callback={setCroppedImage} />
</Modal>
);
};

View File

@@ -1,49 +0,0 @@
import React, { FC, useState } from "react";
import PhotoCropper from "react-avatar-edit";
type Props = {
callback: (value: any) => void
}
const borderStyle: React.CSSProperties = {
textAlign: 'center',
margin: 'auto',
borderStyle: 'dotted',
borderWidth: '0.3rem',
borderRadius: '0.3rem',
}
export const PhotoCrop: FC<Props> = ({ callback }) => {
const [result, setResult] = useState<any>();
const onCrop = (cropped: any) => {
setResult(cropped);
callback(result);
};
const onClose = () => {
setResult(null);
};
const onBeforeFileLoad = (elem: any) => {
if (elem.target.files[0].size > 1000000) {
elem.target.value = "";
alert("A imagem selecionada é grande de mais!")
}
};
const dimention = 300;
return (
<PhotoCropper
borderStyle={borderStyle}
label="Escolha uma imagem"
width={dimention}
height={dimention}
imageWidth={dimention}
imageHeight={dimention}
onCrop={(e) => onCrop(e)}
onClose={() => onClose()}
onBeforeFileLoad={onBeforeFileLoad}
/>
);
};

View File

@@ -1 +0,0 @@
export { AvatarEditor } from "./AvatarEditor";

View File

@@ -10,12 +10,19 @@ type Props = {
export const UserAvatar: FC<Props> = ({user, className}) => {
return (
<div className={`rounded-full border-2 border-primary-light shadow ${className || ''}`}>
<BoringAvatar
size={"100%"}
name={user.name}
variant="pixel"
colors={["#595F72", "#575D90", "#84A07C", "#C3D350", "#E6F14A"]}
/>
{user.avatarUrl ?
<img
className="rounded-full"
src={user.avatarUrl}
alt={`Avatar do usuário ${user.name}`}
/>
: <BoringAvatar
size={"100%"}
name={user.name}
variant="pixel"
colors={["#595F72", "#575D90", "#84A07C", "#C3D350", "#E6F14A"]}
/>
}
</div>
)
};

View File

@@ -4,7 +4,6 @@ export * from "./Button";
export * from "./Card";
export * from "./CardGrid";
export * from "./InputGroup";
export * from "./AvatarEditor";
export * from "./Navegator";
export * from "./UserAvatar";
export * from "./Dialog";

View File

@@ -1,23 +1,18 @@
import React, {
createContext, useContext, useState, FC
} from "react";
import { useQuery, gql } from "@apollo/client";
import { gql, useQuery } from "@apollo/client";
import React, { createContext, FC, useContext } from "react";
import { Query, UserRole } from "../__generated__/graphql-schema";
import { UnauthorizedAccess } from "../pages/session";
import { Loading } from "../pages/shared";
import { Query, UserRole } from "../__generated__/graphql-schema";
export type UserContext = {
user?: Query['currentUser']
refetch: () => void
isOnlyTeacher: boolean
}
user?: Query["currentUser"];
isOnlyTeacher: boolean;
};
const Context = createContext<UserContext>({
refetch: () => {
},
isOnlyTeacher: false,
})
});
export const useCurrentUser = (): UserContext => {
const context = useContext(Context);
@@ -30,41 +25,33 @@ export const useCurrentUser = (): UserContext => {
};
const CurrentUserQuery = gql`
query CurrentUserQuery {
currentUser {
id
name
email
roles
}
query CurrentUserQuery {
currentUser {
id
name
email
roles
avatarUrl
}
}
`;
type Props = {
children: any
}
children: any;
};
export const UserContext: FC<Props> = ({ children }) => {
const [user, setUser] = useState<Query['currentUser']>();
const isOnlyTeacher = !!(user?.roles.includes(UserRole.Teacher) && user?.roles.length === 1)
const { loading, data } = useQuery<Query>(CurrentUserQuery);
const user = data?.currentUser;
const isOnlyTeacher = !!(
user?.roles.includes(UserRole.Teacher) && user?.roles.length === 1
);
const { refetch: refetchUserQuery, loading } = useQuery<Query>(CurrentUserQuery, {
onCompleted: ({ currentUser }) => {
setUser(currentUser)
}
})
const refetch = async () => {
const { data: { currentUser } } = await refetchUserQuery()
setUser(currentUser)
}
if (loading) return <Loading />
if (!user) return <UnauthorizedAccess />
if (loading) return <Loading />;
if (!user?.roles.length) return <UnauthorizedAccess />;
return (
<Context.Provider value={{ user, refetch, isOnlyTeacher }}>
<Context.Provider value={{ user, isOnlyTeacher }}>
{children}
</Context.Provider>
);

View File

@@ -1,27 +1,21 @@
import React, { useState } from "react";
import React from "react";
import { CurrentUserAvatar, Navigator } from "../../components";
import { useCurrentUser } from "../../contexts";
import { AvatarEditor, Navigator, CurrentUserAvatar } from "../../components";
export const Profile = () => {
const [avatarEditorIsOpen, setAvatarEditorIsOpen] = useState(false);
const { user } = useCurrentUser();
return (
<>
<AvatarEditor
isOpen={avatarEditorIsOpen}
setIsOpen={setAvatarEditorIsOpen}
/>
<Navigator home />
<div className="bg-gray-100 w-full my-3">
<main>
<div className="flex items-center flex-col max-w-4xl m-auto">
<div className="bg-white shadow border border-gray-100 flex flex-col items-center rounded p-4 w-full mt-12 mb-4 relative">
<div
className="w-20 absolute cursor-pointer"
className="w-20 absolute"
style={{ top: "-3.10rem" }}
onClick={() => setAvatarEditorIsOpen(true)}
>
<CurrentUserAvatar />
</div>