feat: #1254 display group owner (#1406)

* feat: #1254 display group owner

* fix: format

* fix: format issue

---------

Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
This commit is contained in:
Manuel
2024-11-03 00:33:49 +01:00
committed by GitHub
parent 0ff7c8903b
commit 34506b6339
6 changed files with 57 additions and 9 deletions

View File

@@ -2,7 +2,7 @@
import { useCallback } from "react"; import { useCallback } from "react";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { Button } from "@mantine/core"; import { Button, useMatches } from "@mantine/core";
import { clientApi } from "@homarr/api/client"; import { clientApi } from "@homarr/api/client";
import { revalidatePathActionAsync } from "@homarr/common/client"; import { revalidatePathActionAsync } from "@homarr/common/client";
@@ -61,8 +61,14 @@ export const DeleteGroup = ({ group }: DeleteGroupProps) => {
}); });
}, [tDelete, tRoot, openConfirmModal, group.id, group.name, mutateAsync, router]); }, [tDelete, tRoot, openConfirmModal, group.id, group.name, mutateAsync, router]);
const fullWidth = useMatches({
xs: true,
sm: true,
md: false,
});
return ( return (
<Button variant="subtle" color="red" onClick={handleDeletion}> <Button variant="subtle" color="red" onClick={handleDeletion} fullWidth={fullWidth}>
{tDelete("label")} {tDelete("label")}
</Button> </Button>
); );

View File

@@ -1,7 +1,7 @@
"use client"; "use client";
import { useCallback, useState } from "react"; import { useCallback, useState } from "react";
import { Button } from "@mantine/core"; import { Button, useMatches } from "@mantine/core";
import { clientApi } from "@homarr/api/client"; import { clientApi } from "@homarr/api/client";
import { useConfirmModal, useModalAction } from "@homarr/modals"; import { useConfirmModal, useModalAction } from "@homarr/modals";
@@ -74,8 +74,14 @@ export const TransferGroupOwnership = ({ group }: TransferGroupOwnershipProps) =
); );
}, [group.id, group.name, innerOwnerId, mutateAsync, openConfirmModal, openModal, tRoot, tTransfer]); }, [group.id, group.name, innerOwnerId, mutateAsync, openConfirmModal, openModal, tRoot, tTransfer]);
const fullWidth = useMatches({
xs: true,
sm: true,
md: false,
});
return ( return (
<Button variant="subtle" color="red" onClick={handleTransfer}> <Button variant="subtle" color="red" onClick={handleTransfer} fullWidth={fullWidth}>
{tTransfer("label")} {tTransfer("label")}
</Button> </Button>
); );

View File

@@ -1,8 +1,9 @@
import { Stack, Title } from "@mantine/core"; import { Card, Group, Stack, Text, Title } from "@mantine/core";
import { api } from "@homarr/api/server"; import { api } from "@homarr/api/server";
import { everyoneGroup } from "@homarr/definitions"; import { everyoneGroup } from "@homarr/definitions";
import { getScopedI18n } from "@homarr/translation/server"; import { getScopedI18n } from "@homarr/translation/server";
import { UserAvatar } from "@homarr/ui";
import { DangerZoneItem, DangerZoneRoot } from "~/components/manage/danger-zone"; import { DangerZoneItem, DangerZoneRoot } from "~/components/manage/danger-zone";
import { DeleteGroup } from "./_delete-group"; import { DeleteGroup } from "./_delete-group";
@@ -30,6 +31,30 @@ export default async function GroupsDetailPage({ params }: GroupsDetailPageProps
<RenameGroupForm group={group} disabled={isReserved} /> <RenameGroupForm group={group} disabled={isReserved} />
<Title order={2}>{tGeneral("owner")}</Title>
<Card>
{group.owner ? (
<Group>
<UserAvatar user={{ name: group.owner.name, image: group.owner.image }} size={"lg"} />
<Stack align={"start"} gap={3}>
<Text fw={"bold"}>{group.owner.name}</Text>
<Text>{group.owner.email}</Text>
<Text c={"dimmed"} size={"sm"}>
{tGeneral("ownerOfGroup")}
</Text>
</Stack>
</Group>
) : (
<Group>
<Stack align={"start"} gap={3}>
<Text c={"dimmed"} size={"sm"}>
{tGeneral("ownerOfGroupDeleted")}
</Text>
</Stack>
</Group>
)}
</Card>
{!isReserved && ( {!isReserved && (
<DangerZoneRoot> <DangerZoneRoot>
<DangerZoneItem <DangerZoneItem

View File

@@ -15,7 +15,7 @@ export const DangerZoneRoot = async ({ children }: DangerZoneRootProps) => {
<Title c="red.8" order={2}> <Title c="red.8" order={2}>
{t("common.dangerZone")} {t("common.dangerZone")}
</Title> </Title>
<Card withBorder style={{ borderColor: "var(--mantine-color-red-8)" }}> <Card withBorder style={{ borderColor: "var(--mantine-color-red-8)", borderWidth: 3 }}>
<Stack gap="sm"> <Stack gap="sm">
{Array.isArray(children) {Array.isArray(children)
? children.map((child, index) => ( ? children.map((child, index) => (
@@ -43,14 +43,14 @@ interface DangerZoneItemProps {
export const DangerZoneItem = ({ label, description, action }: DangerZoneItemProps) => { export const DangerZoneItem = ({ label, description, action }: DangerZoneItemProps) => {
return ( return (
<Group justify="space-between" px="md"> <Group justify="space-between" px="md" w={"100%"}>
<Stack gap={0}> <Stack gap={0}>
<Text fw="bold" size="sm"> <Text fw="bold" size="sm">
{label} {label}
</Text> </Text>
<Text size="sm">{description}</Text> <Text size="sm">{description}</Text>
</Stack> </Stack>
<Group justify="end" w={{ base: "100%", xs: "auto" }}> <Group justify="end" w={{ xs: "100%", sm: "100%", md: "auto" }}>
{action} {action}
</Group> </Group>
</Group> </Group>

View File

@@ -75,6 +75,14 @@ export const groupRouter = createTRPCRouter({
permission: true, permission: true,
}, },
}, },
owner: {
columns: {
id: true,
name: true,
image: true,
email: true,
},
},
}, },
}); });

View File

@@ -1932,7 +1932,10 @@
"back": "Back to groups", "back": "Back to groups",
"setting": { "setting": {
"general": { "general": {
"title": "General" "title": "General",
"owner": "Owner",
"ownerOfGroup": "Owner of this group",
"ownerOfGroupDeleted": "The owner of this group was deleted. It currently has no owner."
}, },
"members": { "members": {
"title": "Members", "title": "Members",