refactor: add color initials to avatar, improve usage of user avatar (#753)
This commit is contained in:
@@ -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>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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>;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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>;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user