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

View file

@ -1,18 +1,8 @@
"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";
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 = ({
size,
className,
@ -22,23 +12,11 @@ export const CurrentUserAvatar = ({
}) => {
const { user } = useUser();
return (
<Avatar className={className} style={{ width: size, height: size }}>
{user.image ? (
user.image.startsWith("http") ? (
<AvatarImage src={user.image} />
) : (
<Image
src={getAvatarUrl(user.image)}
width={128}
height={128}
alt={user.name}
style={{ objectFit: "cover" }}
objectFit="cover"
<OptimizedAvatarImage
className={className}
src={user.image ?? undefined}
name={user.name}
size={size}
/>
)
) : (
<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: {
name: true,
email: true,
image: true,
},
});
}),

View file

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