Use avatar on login page (#1336)

This commit is contained in:
Luke Vella 2024-09-08 22:01:52 +01:00 committed by GitHub
parent 33385f9039
commit e4b1fee46c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 68 additions and 38 deletions

View file

@ -5,9 +5,9 @@ import { useRouter } from "next/navigation";
import { useSession } from "next-auth/react"; import { useSession } from "next-auth/react";
import { Logo } from "@/components/logo"; import { Logo } from "@/components/logo";
import { OptimizedAvatarImage } from "@/components/optimized-avatar-image";
import { Skeleton } from "@/components/skeleton"; import { Skeleton } from "@/components/skeleton";
import { Trans } from "@/components/trans"; import { Trans } from "@/components/trans";
import { UserAvatar } from "@/components/user";
import { usePostHog } from "@/utils/posthog"; import { usePostHog } from "@/utils/posthog";
import { trpc } from "@/utils/trpc/client"; import { trpc } from "@/utils/trpc/client";
@ -53,9 +53,13 @@ export const LoginPage = ({ magicLink, email }: PageProps) => {
<div className="mb-4 font-semibold"> <div className="mb-4 font-semibold">
<Trans i18nKey="continueAs" defaults="Continue as" /> <Trans i18nKey="continueAs" defaults="Continue as" />
</div> </div>
<div className="flex flex-col items-center gap-2">
<OptimizedAvatarImage
src={data?.image ?? undefined}
name={data?.name ?? ""}
size={56}
/>
<div className="text-center"> <div className="text-center">
<UserAvatar size="lg" name={data?.name} />
<div className="py-4 text-center">
<div className="mb-1 h-6 font-medium"> <div className="mb-1 h-6 font-medium">
{data?.name ?? <Skeleton className="inline-block h-5 w-16" />} {data?.name ?? <Skeleton className="inline-block h-5 w-16" />}
</div> </div>
@ -71,9 +75,8 @@ export const LoginPage = ({ magicLink, email }: PageProps) => {
onClick={async () => { onClick={async () => {
await magicLinkFetch.mutateAsync(); await magicLinkFetch.mutateAsync();
}} }}
size="lg"
variant="primary" variant="primary"
className="mt-4 w-full" className="mt-6 w-full"
> >
<Trans i18nKey="continue" /> <Trans i18nKey="continue" />
</Button> </Button>

View file

@ -1,18 +1,8 @@
"use client"; "use client";
import { Avatar, AvatarFallback, AvatarImage } from "@rallly/ui/avatar";
import Image from "next/image";
import { OptimizedAvatarImage } from "@/components/optimized-avatar-image";
import { useUser } from "@/components/user-provider"; import { useUser } from "@/components/user-provider";
function getAvatarUrl(imageKey: string) {
// Some users have avatars that come from external providers (e.g. Google).
if (imageKey.startsWith("https://")) {
return imageKey;
}
return `/api/storage/${imageKey}`;
}
export const CurrentUserAvatar = ({ export const CurrentUserAvatar = ({
size, size,
className, className,
@ -22,23 +12,11 @@ export const CurrentUserAvatar = ({
}) => { }) => {
const { user } = useUser(); const { user } = useUser();
return ( return (
<Avatar className={className} style={{ width: size, height: size }}> <OptimizedAvatarImage
{user.image ? ( className={className}
user.image.startsWith("http") ? ( src={user.image ?? undefined}
<AvatarImage src={user.image} /> name={user.name}
) : ( size={size}
<Image
src={getAvatarUrl(user.image)}
width={128}
height={128}
alt={user.name}
style={{ objectFit: "cover" }}
objectFit="cover"
/> />
)
) : (
<AvatarFallback>{user.name[0]}</AvatarFallback>
)}
</Avatar>
); );
}; };

View file

@ -0,0 +1,45 @@
"use client";
import { Avatar, AvatarFallback, AvatarImage } from "@rallly/ui/avatar";
import Image from "next/image";
function getAvatarUrl(imageKey: string) {
// Some users have avatars that come from external providers (e.g. Google).
if (imageKey.startsWith("https://")) {
return imageKey;
}
return `/api/storage/${imageKey}`;
}
export const OptimizedAvatarImage = ({
size,
className,
src,
name,
}: {
size: number;
src?: string;
name: string;
className?: string;
}) => {
return (
<Avatar className={className} style={{ width: size, height: size }}>
{src ? (
src.startsWith("http") ? (
<AvatarImage src={src} alt={name} />
) : (
<Image
src={getAvatarUrl(src)}
width={128}
height={128}
alt={name}
style={{ objectFit: "cover" }}
objectFit="cover"
/>
)
) : (
<AvatarFallback>{name[0]}</AvatarFallback>
)}
</Avatar>
);
};

View file

@ -43,6 +43,7 @@ export const user = router({
select: { select: {
name: true, name: true,
email: true, email: true,
image: true,
}, },
}); });
}), }),

View file

@ -7,14 +7,17 @@ import { cn } from "@rallly/ui";
const Avatar = React.forwardRef< const Avatar = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Root>, React.ElementRef<typeof AvatarPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root> React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root> & {
>(({ className, ...props }, ref) => ( size?: number;
}
>(({ className, size = 48, ...props }, ref) => (
<AvatarPrimitive.Root <AvatarPrimitive.Root
ref={ref} ref={ref}
className={cn( className={cn(
"relative flex size-10 shrink-0 overflow-hidden rounded-full", "relative flex shrink-0 overflow-hidden rounded-full",
className, className,
)} )}
style={{ width: size, height: size }}
{...props} {...props}
/> />
)); ));