mirror of
https://github.com/ajnart/homarr.git
synced 2026-02-26 16:30:57 +01:00
refactor: improve design of no integrations found (#1543)
* refactor: improve design of no integrations found * fix: deepsource issue
This commit is contained in:
@@ -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"),
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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"),
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
26
apps/nextjs/src/components/no-results.tsx
Normal file
26
apps/nextjs/src/components/no-results.tsx
Normal 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>
|
||||
);
|
||||
};
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user