chore: front-end-avatars (#12716)

* Update UserAvatar and remove org avatar

* Update Imports

* Fix imports to use calcom/ui

* type: fix imports

* fix: use testId on profile

* test: use image src instead of innerHTML

* fix: Allow alt on useravatar

* test: add testId to org profile

---------

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
This commit is contained in:
sean-brydon
2024-01-05 10:36:44 +00:00
committed by GitHub
co-authored by Peer Richelsen Alex van Andel
parent 0dddc2224a
commit 698d8ae4bd
16 changed files with 118 additions and 84 deletions
@@ -0,0 +1,37 @@
/* eslint-disable playwright/missing-playwright-await */
import { render } from "@testing-library/react";
import { AVATAR_FALLBACK } from "@calcom/lib/constants";
import { UserAvatar } from "./UserAvatar";
const mockUser = {
name: "John Doe",
username: "pro",
organizationId: null,
};
describe("tests for UserAvatar component", () => {
test("Should render the UsersAvatar Correctly", () => {
const { getByTestId } = render(<UserAvatar user={mockUser} data-testid="user-avatar-test" />);
const avatar = getByTestId("user-avatar-test");
expect(avatar).toBeInTheDocument();
});
test("It should render the organization logo if a organization is passed in", () => {
const { getByTestId } = render(
<UserAvatar
user={mockUser}
organization={{ id: -1, requestedSlug: "steve", slug: "steve", logoUrl: AVATAR_FALLBACK }}
data-testid="user-avatar-test"
/>
);
const avatar = getByTestId("user-avatar-test");
const organizationLogo = getByTestId("organization-logo");
expect(avatar).toBeInTheDocument();
expect(organizationLogo).toBeInTheDocument();
});
});
@@ -0,0 +1,54 @@
import { classNames } from "@calcom/lib";
import { getOrgAvatarUrl, getUserAvatarUrl } from "@calcom/lib/getAvatarUrl";
import type { User } from "@calcom/prisma/client";
import { Avatar } from "@calcom/ui";
type Organization = {
id: number;
slug: string | null;
requestedSlug: string | null;
logoUrl?: string;
};
type UserAvatarProps = Omit<React.ComponentProps<typeof Avatar>, "alt" | "imageSrc"> & {
user: Pick<User, "organizationId" | "name" | "username">;
/**
* Useful when allowing the user to upload their own avatar and showing the avatar before it's uploaded
*/
previewSrc?: string | null;
organization?: Organization | null;
alt?: string | null;
};
function OrganizationIndicator({
size,
organization,
user,
}: Pick<UserAvatarProps, "size" | "user"> & { organization: Organization }) {
const organizationUrl = organization.logoUrl ?? getOrgAvatarUrl(organization);
return (
<div className={classNames("absolute bottom-0 right-0 z-10", size === "lg" ? "h-6 w-6" : "h-10 w-10")}>
<img
data-testId="organization-logo"
src={organizationUrl}
alt={user.username || ""}
className="flex h-full items-center justify-center rounded-full"
/>
</div>
);
}
/**
* It is aware of the user's organization to correctly show the avatar from the correct URL
*/
export function UserAvatar(props: UserAvatarProps) {
const { user, previewSrc = getUserAvatarUrl(user), ...rest } = props;
const indicator = props.organization ? (
<OrganizationIndicator size={props.size} organization={props.organization} user={props.user} />
) : (
props.indicator
);
return <Avatar {...rest} alt={user.name || "Nameless User"} imageSrc={previewSrc} indicator={indicator} />;
}
+1
View File
@@ -1,4 +1,5 @@
export { Avatar } from "./Avatar";
export { UserAvatar } from "./UserAvatar";
export type { AvatarProps } from "./Avatar";
export { AvatarGroup } from "./AvatarGroup";
export type { AvatarGroupProps } from "./AvatarGroup";