fix avatar remove button (#12249)
This commit is contained in:
parent
f62c58532d
commit
a519941b81
|
@ -9,8 +9,8 @@ import { ErrorCode } from "@calcom/features/auth/lib/ErrorCode";
|
|||
import OrganizationMemberAvatar from "@calcom/features/ee/organizations/components/OrganizationMemberAvatar";
|
||||
import SectionBottomActions from "@calcom/features/settings/SectionBottomActions";
|
||||
import { getLayout } from "@calcom/features/settings/layouts/SettingsLayout";
|
||||
import checkIfItFallbackImage from "@calcom/lib/checkIfItFallbackImage";
|
||||
import { APP_NAME, FULL_NAME_LENGTH_MAX_LIMIT } from "@calcom/lib/constants";
|
||||
import { AVATAR_FALLBACK } from "@calcom/lib/constants";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { md } from "@calcom/lib/markdownIt";
|
||||
import turndown from "@calcom/lib/turndownService";
|
||||
|
@ -72,32 +72,24 @@ interface DeleteAccountValues {
|
|||
|
||||
type FormValues = {
|
||||
username: string;
|
||||
avatar: string | null;
|
||||
avatar: string;
|
||||
name: string;
|
||||
email: string;
|
||||
bio: string;
|
||||
};
|
||||
|
||||
const checkIfItFallbackImage = (fetchedImgSrc?: string) => {
|
||||
return !fetchedImgSrc || fetchedImgSrc.endsWith(AVATAR_FALLBACK);
|
||||
};
|
||||
|
||||
const ProfileView = () => {
|
||||
const { t } = useLocale();
|
||||
const utils = trpc.useContext();
|
||||
const { update } = useSession();
|
||||
|
||||
const [fetchedImgSrc, setFetchedImgSrc] = useState<string | undefined>(undefined);
|
||||
const [fetchedImgSrc, setFetchedImgSrc] = useState<string>("");
|
||||
|
||||
const { data: user, isLoading } = trpc.viewer.me.useQuery(undefined, {
|
||||
onSuccess: async (userData) => {
|
||||
try {
|
||||
if (!userData.organization) {
|
||||
const res = await fetch(userData.avatar);
|
||||
if (res.url) setFetchedImgSrc(res.url);
|
||||
} else {
|
||||
setFetchedImgSrc("");
|
||||
}
|
||||
const res = await fetch(userData.avatar);
|
||||
if (res.url) setFetchedImgSrc(res.url);
|
||||
} catch (err) {
|
||||
setFetchedImgSrc("");
|
||||
}
|
||||
|
@ -234,7 +226,7 @@ const ProfileView = () => {
|
|||
|
||||
const defaultValues = {
|
||||
username: user.username || "",
|
||||
avatar: user.avatar || "",
|
||||
avatar: fetchedImgSrc || "",
|
||||
name: user.name || "",
|
||||
email: user.email || "",
|
||||
bio: user.bio || "",
|
||||
|
@ -251,8 +243,6 @@ const ProfileView = () => {
|
|||
key={JSON.stringify(defaultValues)}
|
||||
defaultValues={defaultValues}
|
||||
isLoading={updateProfileMutation.isLoading}
|
||||
isFallbackImg={checkIfItFallbackImage(fetchedImgSrc)}
|
||||
userAvatar={user.avatar}
|
||||
user={user}
|
||||
userOrganization={user.organization}
|
||||
onSubmit={(values) => {
|
||||
|
@ -397,8 +387,6 @@ const ProfileForm = ({
|
|||
onSubmit,
|
||||
extraField,
|
||||
isLoading = false,
|
||||
isFallbackImg,
|
||||
userAvatar,
|
||||
user,
|
||||
userOrganization,
|
||||
}: {
|
||||
|
@ -406,8 +394,6 @@ const ProfileForm = ({
|
|||
onSubmit: (values: FormValues) => void;
|
||||
extraField?: React.ReactNode;
|
||||
isLoading: boolean;
|
||||
isFallbackImg: boolean;
|
||||
userAvatar: string;
|
||||
user: RouterOutputs["viewer"]["me"];
|
||||
userOrganization: RouterOutputs["viewer"]["me"]["organization"];
|
||||
}) => {
|
||||
|
@ -416,7 +402,7 @@ const ProfileForm = ({
|
|||
|
||||
const profileFormSchema = z.object({
|
||||
username: z.string(),
|
||||
avatar: z.string().nullable(),
|
||||
avatar: z.string(),
|
||||
name: z
|
||||
.string()
|
||||
.trim()
|
||||
|
@ -438,7 +424,6 @@ const ProfileForm = ({
|
|||
} = formMethods;
|
||||
|
||||
const isDisabled = isSubmitting || !isDirty;
|
||||
|
||||
return (
|
||||
<Form form={formMethods} handleSubmit={onSubmit}>
|
||||
<div className="border-subtle border-x px-4 pb-10 pt-8 sm:px-6">
|
||||
|
@ -447,7 +432,7 @@ const ProfileForm = ({
|
|||
control={formMethods.control}
|
||||
name="avatar"
|
||||
render={({ field: { value } }) => {
|
||||
const showRemoveAvatarButton = !isFallbackImg || (value && userAvatar !== value);
|
||||
const showRemoveAvatarButton = !checkIfItFallbackImage(value);
|
||||
const organization =
|
||||
userOrganization && userOrganization.id
|
||||
? {
|
||||
|
@ -474,7 +459,7 @@ const ProfileForm = ({
|
|||
handleAvatarChange={(newAvatar) => {
|
||||
formMethods.setValue("avatar", newAvatar, { shouldDirty: true });
|
||||
}}
|
||||
imageSrc={value || undefined}
|
||||
imageSrc={value}
|
||||
triggerButtonColor={showRemoveAvatarButton ? "secondary" : "primary"}
|
||||
/>
|
||||
|
||||
|
@ -482,7 +467,7 @@ const ProfileForm = ({
|
|||
<Button
|
||||
color="secondary"
|
||||
onClick={() => {
|
||||
formMethods.setValue("avatar", null, { shouldDirty: true });
|
||||
formMethods.setValue("avatar", "", { shouldDirty: true });
|
||||
}}>
|
||||
{t("remove")}
|
||||
</Button>
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
import { AVATAR_FALLBACK } from "./constants";
|
||||
|
||||
const checkIfItFallbackImage = (fetchedImgSrc: string) => {
|
||||
return !fetchedImgSrc || fetchedImgSrc.endsWith(AVATAR_FALLBACK);
|
||||
};
|
||||
export default checkIfItFallbackImage;
|
|
@ -36,7 +36,7 @@ export const updateProfileHandler = async ({ ctx, input }: UpdateProfileOptions)
|
|||
const userMetadata = handleUserMetadata({ ctx, input });
|
||||
const data: Prisma.UserUpdateInput = {
|
||||
...input,
|
||||
avatar: await getAvatarToSet(input.avatar),
|
||||
avatar: input.avatar ? await getAvatarToSet(input.avatar) : null,
|
||||
metadata: userMetadata,
|
||||
};
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ import type { FormEvent } from "react";
|
|||
import { useCallback, useEffect, useState } from "react";
|
||||
import Cropper from "react-easy-crop";
|
||||
|
||||
import checkIfItFallbackImage from "@calcom/lib/checkIfItFallbackImage";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
|
||||
import type { ButtonColor } from "../..";
|
||||
|
@ -120,20 +121,15 @@ export default function ImageUploader({
|
|||
buttonMsg,
|
||||
handleAvatarChange,
|
||||
triggerButtonColor,
|
||||
...props
|
||||
imageSrc,
|
||||
}: ImageUploaderProps) {
|
||||
const { t } = useLocale();
|
||||
const [imageSrc, setImageSrc] = useState<string | null>(null);
|
||||
const [croppedAreaPixels, setCroppedAreaPixels] = useState<Area | null>(null);
|
||||
|
||||
const [{ result }, setFile] = useFileReader({
|
||||
method: "readAsDataURL",
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (props.imageSrc) setImageSrc(props.imageSrc);
|
||||
}, [props.imageSrc]);
|
||||
|
||||
const onInputFile = (e: FileEvent<HTMLInputElement>) => {
|
||||
if (!e.target.files?.length) {
|
||||
return;
|
||||
|
@ -157,7 +153,6 @@ export default function ImageUploader({
|
|||
result as string /* result is always string when using readAsDataUrl */,
|
||||
croppedAreaPixels
|
||||
);
|
||||
setImageSrc(croppedImage);
|
||||
handleAvatarChange(croppedImage);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
|
@ -181,12 +176,11 @@ export default function ImageUploader({
|
|||
<div className="cropper mt-6 flex flex-col items-center justify-center p-8">
|
||||
{!result && (
|
||||
<div className="bg-muted flex h-20 max-h-20 w-20 items-center justify-start rounded-full">
|
||||
{!imageSrc && (
|
||||
{!imageSrc || checkIfItFallbackImage(imageSrc) ? (
|
||||
<p className="text-emphasis w-full text-center text-sm sm:text-xs">
|
||||
{t("no_target", { target })}
|
||||
</p>
|
||||
)}
|
||||
{imageSrc && (
|
||||
) : (
|
||||
// eslint-disable-next-line @next/next/no-img-element
|
||||
<img className="h-20 w-20 rounded-full" src={imageSrc} alt={target} />
|
||||
)}
|
||||
|
|
Loading…
Reference in New Issue
Block a user