[CAL-811] Avatar icon not redirecting user back to the main page (#6586)

* Remove cursor-pointer, remove old Avatar* files

* Fixed styling for checkedSelect + some cleanup

Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
This commit is contained in:
GitStart-Cal.com 2023-01-21 17:26:49 +05:45 committed by GitHub
parent 0bb0883e64
commit 7ce83542e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 26 additions and 176 deletions

View File

@ -36,7 +36,7 @@ export const UserAvatars = ({
href?: string;
}[]
}
size="sm"
size={users.length <= 1 ? "lg" : "sm"}
truncateAfter={props.truncateAfter}
/>
);

View File

@ -1,51 +0,0 @@
import * as AvatarPrimitive from "@radix-ui/react-avatar";
import * as Tooltip from "@radix-ui/react-tooltip";
import { Maybe } from "@calcom/trpc/server";
import classNames from "@lib/classNames";
import { defaultAvatarSrc } from "@lib/profile";
export type AvatarProps = {
className?: string;
size?: number;
imageSrc?: Maybe<string>;
title?: string;
alt: string;
gravatarFallbackMd5?: string;
};
/**
* @deprecated Use AvatarSSR instead. Once, there is no usage of Avatar, AvatarSSR can be renamed.
*/
export default function Avatar(props: AvatarProps) {
const { imageSrc, gravatarFallbackMd5, size, alt, title } = props;
const className = classNames("rounded-full", props.className, size && `h-${size} w-${size}`);
const avatar = (
<AvatarPrimitive.Root>
<AvatarPrimitive.Image
src={imageSrc ?? undefined}
alt={alt}
className={classNames("rounded-full", `h-auto w-${size}`, props.className)}
/>
<AvatarPrimitive.Fallback delayMs={600}>
{gravatarFallbackMd5 && (
// eslint-disable-next-line @next/next/no-img-element
<img src={defaultAvatarSrc({ md5: gravatarFallbackMd5 })} alt={alt} className={className} />
)}
</AvatarPrimitive.Fallback>
</AvatarPrimitive.Root>
);
return title ? (
<Tooltip.Tooltip delayDuration={300}>
<Tooltip.TooltipTrigger className="cursor-default">{avatar}</Tooltip.TooltipTrigger>
<Tooltip.Content className="rounded-sm bg-black p-2 text-sm text-white">
<Tooltip.Arrow />
{title}
</Tooltip.Content>
</Tooltip.Tooltip>
) : (
<>{avatar}</>
);
}

View File

@ -1,47 +0,0 @@
import Link from "next/link";
import React from "react";
import classNames from "@lib/classNames";
import { AvatarSSR } from "@components/ui/AvatarSSR";
export type AvatarGroupProps = {
border?: string; // this needs to be the color of the parent container background, i.e.: border-white dark:border-gray-900
size: number;
truncateAfter?: number;
items: {
image: string;
title?: string;
alt?: string;
href?: string;
}[];
className?: string;
};
export const AvatarGroup = function AvatarGroup(props: AvatarGroupProps) {
return (
<ul className={classNames(props.className)}>
{props.items.slice(0, props.truncateAfter).map((item, idx) => {
if (item.image != null) {
const avatar = (
<AvatarSSR
className={props.border}
imageSrc={item.image}
title={item.title}
alt={item.alt || ""}
size={props.size}
/>
);
return (
<li key={idx} className="-ltr:mr-2 inline-block rtl:ml-2">
{item.href ? <Link href={item.href}>{avatar}</Link> : avatar}
</li>
);
}
})}
</ul>
);
};
export default AvatarGroup;

View File

@ -1,62 +0,0 @@
import { User } from "@prisma/client";
import * as Tooltip from "@radix-ui/react-tooltip";
import classNames from "@lib/classNames";
export type AvatarProps = (
| {
user: Pick<User, "name" | "username" | "avatar"> & { emailMd5?: string };
}
| {
user?: null;
imageSrc: string;
}
) & {
className?: string;
size?: number;
title?: string;
href?: string;
alt: string;
};
// defaultAvatarSrc from profile.tsx can't be used as it imports crypto
function defaultAvatarSrc(md5: string) {
return `https://www.gravatar.com/avatar/${md5}?s=160&d=mp&r=PG`;
}
// An SSR Supported version of Avatar component.
export function AvatarSSR(props: AvatarProps) {
const { size, title } = props;
let imgSrc = "";
let alt: string = props.alt;
if (props.user) {
const user = props.user;
const nameOrUsername = user.name || user.username || "";
alt = alt || nameOrUsername;
if (user.avatar) {
imgSrc = user.avatar;
} else if (user.emailMd5) {
imgSrc = defaultAvatarSrc(user.emailMd5);
}
} else {
imgSrc = props.imageSrc;
}
const className = classNames("rounded-full", props.className, size && `h-${size} w-${size}`);
const avatar = imgSrc ? <img alt={alt} className={className} src={imgSrc} /> : null;
return title ? (
<Tooltip.Tooltip delayDuration={300}>
<Tooltip.TooltipTrigger asChild>{avatar}</Tooltip.TooltipTrigger>
<Tooltip.Content className="rounded-sm bg-black p-2 text-sm text-white">
<Tooltip.Arrow />
{title}
</Tooltip.Content>
</Tooltip.Tooltip>
) : (
<>{avatar}</>
);
}

View File

@ -2,9 +2,8 @@ import React from "react";
import { Props } from "react-select";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Icon } from "@calcom/ui";
import { Icon, Avatar } from "@calcom/ui";
import Avatar from "@components/ui/Avatar";
import Select from "@components/ui/form/Select";
type CheckedSelectOption = {
@ -43,7 +42,8 @@ export const CheckedSelect = ({
{value.map((option) => (
<div key={option.value} className="border p-2 font-medium">
<Avatar
className="inline h-6 w-6 rounded-full ltr:mr-2 rtl:ml-2"
className="inline ltr:mr-2 rtl:ml-2"
size="sm"
imageSrc={option.avatar}
alt={option.label}
/>

View File

@ -26,13 +26,11 @@ import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@calco
import prisma from "@calcom/prisma";
import { baseEventTypeSelect } from "@calcom/prisma/selects";
import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
import { Icon, HeadSeo, AvatarGroup } from "@calcom/ui";
import { Icon, HeadSeo, AvatarGroup, Avatar } from "@calcom/ui";
import { inferSSRProps } from "@lib/types/inferSSRProps";
import { EmbedProps } from "@lib/withEmbedSsr";
import { AvatarSSR } from "@components/ui/AvatarSSR";
import { ssrInit } from "@server/lib/ssr";
export default function User(props: inferSSRProps<typeof getServerSideProps> & EmbedProps) {
@ -132,7 +130,7 @@ export default function User(props: inferSSRProps<typeof getServerSideProps> & E
)}>
{isSingleUser && ( // When we deal with a single user, not dynamic group
<div className="mb-8 text-center">
<AvatarSSR user={user} className="mx-auto mb-4 h-24 w-24" alt={nameOrUsername} />
<Avatar imageSrc={user.avatar} size="xl" alt={nameOrUsername} />
<h1 className="font-cal mb-1 text-3xl text-gray-900 dark:text-white">
{nameOrUsername}
{user.verified && (

View File

@ -1,5 +1,6 @@
import * as AvatarPrimitive from "@radix-ui/react-avatar";
import * as Tooltip from "@radix-ui/react-tooltip";
import Link from "next/link";
import classNames from "@calcom/lib/classNames";
import { defaultAvatarSrc } from "@calcom/lib/defaultAvatarImage";
@ -9,10 +10,11 @@ import { Maybe } from "@trpc/server";
export type AvatarProps = {
className?: string;
size: "xs" | "sm" | "md" | "mdLg" | "lg";
size: "xs" | "sm" | "md" | "mdLg" | "lg" | "xl";
imageSrc?: Maybe<string>;
title?: string;
alt: string;
href?: string;
gravatarFallbackMd5?: string;
fallback?: React.ReactNode;
accepted?: boolean;
@ -25,20 +27,24 @@ const sizesPropsBySize = {
md: "w-8 h-8", // 32px
mdLg: "w-10 h-10", //40px
lg: "w-16 h-16", // 64px
xl: "w-24 h-24", // 96px
} as const;
export function Avatar(props: AvatarProps) {
const { imageSrc, gravatarFallbackMd5, size, alt, title } = props;
const sizeClassname = sizesPropsBySize[size];
const rootClass = classNames("rounded-full aspect-square ", sizeClassname);
const avatar = (
const { imageSrc, gravatarFallbackMd5, size, alt, title, href } = props;
const rootClass = classNames("aspect-square rounded-full", sizesPropsBySize[size]);
let avatar = (
<AvatarPrimitive.Root
className={classNames(
sizeClassname,
"dark:bg-darkgray-300 item-center relative inline-flex aspect-square justify-center overflow-hidden rounded-full"
"dark:bg-darkgray-300 item-center relative inline-flex aspect-square justify-center overflow-hidden rounded-full",
props.className
)}>
<>
<AvatarPrimitive.Image src={imageSrc ?? undefined} alt={alt} className={rootClass} />
<AvatarPrimitive.Image
src={imageSrc ?? undefined}
alt={alt}
className={classNames("aspect-square rounded-full", sizesPropsBySize[size])}
/>
<AvatarPrimitive.Fallback delayMs={600} asChild={props.asChild}>
<>
{props.fallback && !gravatarFallbackMd5 && props.fallback}
@ -62,6 +68,10 @@ export function Avatar(props: AvatarProps) {
</AvatarPrimitive.Root>
);
if (href) {
avatar = <Link href={href}>{avatar}</Link>;
}
return title ? (
<Tooltip.Provider>
<Tooltip.Tooltip delayDuration={300}>

View File

@ -8,6 +8,7 @@ export type AvatarGroupProps = {
image: string;
title?: string;
alt?: string;
href?: string;
}[];
className?: string;
accepted?: boolean;
@ -51,6 +52,7 @@ export const AvatarGroup = function AvatarGroup(props: AvatarGroupProps) {
alt={item.alt || ""}
accepted={props.accepted}
size={props.size}
href={item.href}
/>
</li>
);