refactor: add color initials to avatar, improve usage of user avatar (#753)

This commit is contained in:
Meier Lukas
2024-07-08 00:00:54 +02:00
committed by GitHub
parent 408cdeb5c3
commit 3214d889fa
7 changed files with 25 additions and 33 deletions

View File

@@ -2,7 +2,7 @@
import { useMemo } from "react"; import { useMemo } from "react";
import Link from "next/link"; import Link from "next/link";
import { Avatar, Button, Group, Text, ThemeIcon, Title } from "@mantine/core"; import { Anchor, Button, Group, Text, ThemeIcon, Title } from "@mantine/core";
import { IconCheck } from "@tabler/icons-react"; import { IconCheck } from "@tabler/icons-react";
import type { MRT_ColumnDef } from "mantine-react-table"; import type { MRT_ColumnDef } from "mantine-react-table";
import { MantineReactTable, useMantineReactTable } from "mantine-react-table"; import { MantineReactTable, useMantineReactTable } from "mantine-react-table";
@@ -10,6 +10,7 @@ import { MantineReactTable, useMantineReactTable } from "mantine-react-table";
import type { RouterOutputs } from "@homarr/api"; import type { RouterOutputs } from "@homarr/api";
import { clientApi } from "@homarr/api/client"; import { clientApi } from "@homarr/api/client";
import { useI18n, useScopedI18n } from "@homarr/translation/client"; import { useI18n, useScopedI18n } from "@homarr/translation/client";
import { UserAvatar } from "@homarr/ui";
interface UserListComponentProps { interface UserListComponentProps {
initialUserList: RouterOutputs["user"]["getAll"]; initialUserList: RouterOutputs["user"]["getAll"];
@@ -29,12 +30,12 @@ export const UserListComponent = ({ initialUserList }: UserListComponentProps) =
header: t("user.field.username.label"), header: t("user.field.username.label"),
grow: 100, grow: 100,
Cell: ({ renderedCellValue, row }) => ( Cell: ({ renderedCellValue, row }) => (
<Link href={`/manage/users/${row.original.id}/general`}> <Group>
<Group> <UserAvatar size="sm" user={row.original} />
<Avatar size="sm"></Avatar> <Anchor component={Link} href={`/manage/users/${row.original.id}/general`}>
{renderedCellValue} {renderedCellValue}
</Group> </Anchor>
</Link> </Group>
), ),
}, },
{ {

View File

@@ -1,17 +1,18 @@
"use client"; "use client";
import { useCallback, useMemo, useState } from "react"; import { useCallback, useMemo, useState } from "react";
import { Avatar, Card, PasswordInput, Stack, Stepper, Text, TextInput, Title } from "@mantine/core"; import { Card, PasswordInput, Stack, Stepper, Text, TextInput, Title } from "@mantine/core";
import { IconUserCheck } from "@tabler/icons-react"; import { IconUserCheck } from "@tabler/icons-react";
import { clientApi } from "@homarr/api/client"; import { clientApi } from "@homarr/api/client";
import { useZodForm } from "@homarr/form"; import { useZodForm } from "@homarr/form";
import { showErrorNotification } from "@homarr/notifications"; import { showErrorNotification } from "@homarr/notifications";
import { useScopedI18n } from "@homarr/translation/client"; import { useScopedI18n } from "@homarr/translation/client";
import { UserAvatar } from "@homarr/ui";
import { validation, z } from "@homarr/validation"; import { validation, z } from "@homarr/validation";
import { createCustomErrorParams } from "@homarr/validation/form"; import { createCustomErrorParams } from "@homarr/validation/form";
import { StepperNavigationComponent } from "./stepper-navigation.component"; import { StepperNavigationComponent } from "./stepper-navigation";
export const UserCreateStepperComponent = () => { export const UserCreateStepperComponent = () => {
const t = useScopedI18n("management.page.user.create"); const t = useScopedI18n("management.page.user.create");
@@ -150,7 +151,7 @@ export const UserCreateStepperComponent = () => {
<Stepper.Step label={t("step.review.label")} allowStepSelect={false} allowStepClick={false}> <Stepper.Step label={t("step.review.label")} allowStepSelect={false} allowStepClick={false}>
<Card p="xl"> <Card p="xl">
<Stack maw={300} align="center" mx="auto"> <Stack maw={300} align="center" mx="auto">
<Avatar size="xl">{generalForm.values.username}</Avatar> <UserAvatar size="xl" user={{ name: generalForm.values.username, image: null }} />
<Text tt="uppercase" fw="bolder" size="xl"> <Text tt="uppercase" fw="bolder" size="xl">
{generalForm.values.username} {generalForm.values.username}
</Text> </Text>

View File

@@ -3,7 +3,7 @@ import { getScopedI18n } from "@homarr/translation/server";
import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb"; import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb";
import { createMetaTitle } from "~/metadata"; import { createMetaTitle } from "~/metadata";
import { UserListComponent } from "./_components/user-list.component"; import { UserListComponent } from "./_components/user-list";
export async function generateMetadata() { export async function generateMetadata() {
const t = await getScopedI18n("management.page.user.list"); const t = await getScopedI18n("management.page.user.list");

View File

@@ -1,13 +1,13 @@
import { UnstyledButton } from "@mantine/core"; import { UnstyledButton } from "@mantine/core";
import { UserAvatar } from "~/components/user-avatar"; import { CurrentUserAvatar } from "~/components/user-avatar";
import { UserAvatarMenu } from "~/components/user-avatar-menu"; import { UserAvatarMenu } from "~/components/user-avatar-menu";
export const UserButton = () => { export const UserButton = () => {
return ( return (
<UserAvatarMenu> <UserAvatarMenu>
<UnstyledButton> <UnstyledButton>
<UserAvatar size="md" /> <CurrentUserAvatar size="md" />
</UnstyledButton> </UnstyledButton>
</UserAvatarMenu> </UserAvatarMenu>
); );

View File

@@ -1,24 +1,19 @@
import type { AvatarProps, MantineSize } from "@mantine/core"; import type { MantineSize } from "@mantine/core";
import { Avatar } from "@mantine/core";
import { auth } from "@homarr/auth/next"; import { auth } from "@homarr/auth/next";
import { UserAvatar } from "@homarr/ui";
interface UserAvatarProps { interface UserAvatarProps {
size: MantineSize; size: MantineSize;
} }
export const UserAvatar = async ({ size }: UserAvatarProps) => { export const CurrentUserAvatar = async ({ size }: UserAvatarProps) => {
const currentSession = await auth(); const currentSession = await auth();
const commonProps = { const user = {
size, name: currentSession?.user.name ?? null,
color: "primaryColor", image: currentSession?.user.image ?? null,
} satisfies Partial<AvatarProps>; };
if (!currentSession?.user) return <Avatar {...commonProps} />; return <UserAvatar user={user} size={size} />;
if (currentSession.user.image)
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return <Avatar {...commonProps} src={currentSession.user.image} alt={currentSession.user.name!} />;
return <Avatar {...commonProps}>{currentSession.user.name?.substring(0, 2).toUpperCase()}</Avatar>;
}; };

View File

@@ -12,15 +12,10 @@ interface UserAvatarProps {
} }
export const UserAvatar = ({ user, size }: UserAvatarProps) => { export const UserAvatar = ({ user, size }: UserAvatarProps) => {
const commonProps = { if (!user?.name) return <Avatar size={size} />;
size,
color: "primaryColor",
} satisfies Partial<AvatarProps>;
if (!user?.name) return <Avatar {...commonProps} />;
if (user.image) { if (user.image) {
return <Avatar {...commonProps} src={user.image} alt={user.name} />; return <Avatar src={user.image} alt={user.name} size={size} />;
} }
return <Avatar {...commonProps}>{user.name.substring(0, 2).toUpperCase()}</Avatar>; return <Avatar name={user.name} color="initials" size={size}></Avatar>;
}; };