refactor: improve design of no integrations found (#1543)

* refactor: improve design of no integrations found

* fix: deepsource issue
This commit is contained in:
Meier Lukas
2024-11-25 17:31:14 +01:00
committed by GitHub
parent b68977c52c
commit 7e349bb04b
5 changed files with 55 additions and 28 deletions

View File

@@ -1,7 +1,7 @@
import Link from "next/link";
import { redirect } from "next/navigation";
import { ActionIcon, ActionIconGroup, Anchor, Avatar, Card, Group, Stack, Text, Title } from "@mantine/core";
import { IconApps, IconPencil } from "@tabler/icons-react";
import { IconBox, IconPencil } from "@tabler/icons-react";
import type { RouterOutputs } from "@homarr/api";
import { api } from "@homarr/api/server";
@@ -12,6 +12,7 @@ import { getI18n, getScopedI18n } from "@homarr/translation/server";
import { ManageContainer } from "~/components/manage/manage-container";
import { MobileAffixButton } from "~/components/manage/mobile-affix-button";
import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb";
import { NoResults } from "~/components/no-results";
import { AppDeleteButton } from "./_app-delete-button";
export default async function AppsPage() {
@@ -113,16 +114,14 @@ const AppNoResults = async () => {
const session = await auth();
return (
<Card withBorder bg="transparent">
<Stack align="center" gap="sm">
<IconApps size="2rem" />
<Text fw={500} size="lg">
{t("app.page.list.noResults.title")}
</Text>
{session?.user.permissions.includes("app-create") && (
<Anchor href="/manage/apps/new">{t("app.page.list.noResults.action")}</Anchor>
)}
</Stack>
</Card>
<NoResults
icon={IconBox}
title={t("app.page.list.noResults.title")}
action={{
label: t("app.page.list.noResults.action"),
href: "/manage/apps/new",
hidden: !session?.user.permissions.includes("app-create"),
}}
/>
);
};

View File

@@ -27,7 +27,7 @@ import {
Text,
Title,
} from "@mantine/core";
import { IconChevronDown, IconChevronUp, IconPencil } from "@tabler/icons-react";
import { IconChevronDown, IconChevronUp, IconPencil, IconPlugX } from "@tabler/icons-react";
import type { RouterOutputs } from "@homarr/api";
import { api } from "@homarr/api/server";
@@ -40,6 +40,7 @@ import { CountBadge, IntegrationAvatar } from "@homarr/ui";
import { ManageContainer } from "~/components/manage/manage-container";
import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb";
import { NoResults } from "~/components/no-results";
import { ActiveTabAccordion } from "../../../../components/active-tab-accordion";
import { DeleteIntegrationActionButton } from "./_integration-buttons";
import { IntegrationCreateDropdownContent } from "./new/_integration-new-dropdown";
@@ -120,7 +121,7 @@ const IntegrationList = async ({ integrations, activeTab }: IntegrationListProps
const hasFullAccess = session?.user.permissions.includes("integration-full-all") ?? false;
if (integrations.length === 0) {
return <div>{t("page.list.empty")}</div>;
return <NoResults icon={IconPlugX} title={t("page.list.noResults.title")} />;
}
const grouppedIntegrations = integrations.reduce(

View File

@@ -13,6 +13,7 @@ import { z } from "@homarr/validation";
import { ManageContainer } from "~/components/manage/manage-container";
import { MobileAffixButton } from "~/components/manage/mobile-affix-button";
import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb";
import { NoResults } from "~/components/no-results";
import { SearchEngineDeleteButton } from "./_search-engine-delete-button";
const searchParamsSchema = z.object({
@@ -142,16 +143,14 @@ const SearchEngineNoResults = async () => {
const session = await auth();
return (
<Card withBorder bg="transparent">
<Stack align="center" gap="sm">
<IconSearch size="2rem" />
<Text fw={500} size="lg">
{t("search.engine.page.list.noResults.title")}
</Text>
{session?.user.permissions.includes("search-engine-create") && (
<Anchor href="/manage/search-engines/new">{t("search.engine.page.list.noResults.action")}</Anchor>
)}
</Stack>
</Card>
<NoResults
icon={IconSearch}
title={t("search.engine.page.list.noResults.title")}
action={{
label: t("search.engine.page.list.noResults.action"),
href: "/manage/search-engines/new",
hidden: !session?.user.permissions.includes("search-engine-create"),
}}
/>
);
};

View File

@@ -0,0 +1,26 @@
import { Anchor, Card, Stack, Text } from "@mantine/core";
import type { TablerIcon } from "@tabler/icons-react";
interface NoResultsProps {
icon: TablerIcon;
title: string;
action?: {
label: string;
href: string;
hidden?: boolean;
};
}
export const NoResults = ({ icon: Icon, title, action }: NoResultsProps) => {
return (
<Card withBorder bg="transparent">
<Stack align="center" gap="sm">
<Icon size="2rem" />
<Text fw={500} size="lg">
{title}
</Text>
{!action?.hidden && <Anchor href={action?.href}>{action?.label}</Anchor>}
</Stack>
</Card>
);
};

View File

@@ -388,7 +388,7 @@
"list": {
"title": "Apps",
"noResults": {
"title": "There aren't any apps",
"title": "There are no apps yet",
"action": "Create your first app"
}
},
@@ -456,7 +456,9 @@
"list": {
"title": "Integrations",
"search": "Search integrations",
"empty": "No integrations found"
"noResults": {
"title": "There are no integrations yet"
}
},
"create": {
"title": "New {name} integration",
@@ -2676,7 +2678,7 @@
"list": {
"title": "Search engines",
"noResults": {
"title": "There aren't any search engines",
"title": "There are no search engines yet",
"action": "Create your first search engine"
},
"interactive": "Interactive, uses an integration"