import Link from "next/link"; import { redirect } from "next/navigation"; import { ActionIcon, ActionIconGroup, Anchor, Avatar, Card, Group, Stack, Text, Title } from "@mantine/core"; import { IconPencil, IconSearch } from "@tabler/icons-react"; import type { RouterOutputs } from "@homarr/api"; import { api } from "@homarr/api/server"; import { auth } from "@homarr/auth/next"; import { getI18n, getScopedI18n } from "@homarr/translation/server"; import { SearchInput, TablePagination } from "@homarr/ui"; 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({ search: z.string().optional(), pageSize: z.string().regex(/\d+/).transform(Number).catch(10), page: z.string().regex(/\d+/).transform(Number).catch(1), }); type SearchParamsSchemaInputFromSchema> = Partial<{ [K in keyof TSchema]: Exclude extends unknown[] ? string[] : string; }>; interface SearchEnginesPageProps { searchParams: SearchParamsSchemaInputFromSchema>; } export default async function SearchEnginesPage(props: SearchEnginesPageProps) { const session = await auth(); if (!session) { redirect("/auth/login"); } const searchParams = searchParamsSchema.parse(props.searchParams); const { items: searchEngines, totalCount } = await api.searchEngine.getPaginated(searchParams); const tEngine = await getScopedI18n("search.engine"); return ( {tEngine("page.list.title")} {session.user.permissions.includes("search-engine-create") && ( {tEngine("page.create.title")} )} {searchEngines.length === 0 && } {searchEngines.length > 0 && ( {searchEngines.map((searchEngine) => ( ))} )} ); } interface SearchEngineCardProps { searchEngine: RouterOutputs["searchEngine"]["getPaginated"]["items"][number]; } const SearchEngineCard = async ({ searchEngine }: SearchEngineCardProps) => { const t = await getScopedI18n("search.engine"); const session = await auth(); return ( {searchEngine.name} {searchEngine.description && ( {searchEngine.description} )} {searchEngine.type === "generic" && searchEngine.urlTemplate !== null && ( {searchEngine.urlTemplate} )} {searchEngine.type === "fromIntegration" && searchEngine.integrationId !== null && ( {t("page.list.interactive")} )} {session?.user.permissions.includes("search-engine-modify-all") && ( )} {session?.user.permissions.includes("search-engine-full-all") && ( )} ); }; const SearchEngineNoResults = async () => { const t = await getI18n(); const session = await auth(); return ( ); };