diff --git a/apps/nextjs/src/app/[locale]/_client-providers/mantine.tsx b/apps/nextjs/src/app/[locale]/_client-providers/mantine.tsx index d81b828f3..508074ead 100644 --- a/apps/nextjs/src/app/[locale]/_client-providers/mantine.tsx +++ b/apps/nextjs/src/app/[locale]/_client-providers/mantine.tsx @@ -2,13 +2,14 @@ import type { PropsWithChildren } from "react"; import type { MantineColorScheme, MantineColorSchemeManager } from "@mantine/core"; -import { createTheme, DirectionProvider, MantineProvider } from "@mantine/core"; +import { DirectionProvider, MantineProvider } from "@mantine/core"; import dayjs from "dayjs"; import { clientApi } from "@homarr/api/client"; import { useSession } from "@homarr/auth/client"; import { parseCookies, setClientCookie } from "@homarr/common"; import { colorSchemeCookieKey } from "@homarr/definitions"; +import { theme } from "@homarr/ui"; export const CustomMantineProvider = ({ children, @@ -17,14 +18,7 @@ export const CustomMantineProvider = ({ const manager = useColorSchemeManager(); return ( - + {children} diff --git a/apps/nextjs/src/app/[locale]/auth/invite/[id]/page.tsx b/apps/nextjs/src/app/[locale]/auth/invite/[id]/page.tsx index cc6535703..dbf6306c3 100644 --- a/apps/nextjs/src/app/[locale]/auth/invite/[id]/page.tsx +++ b/apps/nextjs/src/app/[locale]/auth/invite/[id]/page.tsx @@ -59,7 +59,7 @@ export default async function InviteUsagePage(props: InviteUsagePageProps) { {t("subtitle")} - + diff --git a/apps/nextjs/src/app/[locale]/auth/login/page.tsx b/apps/nextjs/src/app/[locale]/auth/login/page.tsx index 22adf3b87..6cf00b6b3 100644 --- a/apps/nextjs/src/app/[locale]/auth/login/page.tsx +++ b/apps/nextjs/src/app/[locale]/auth/login/page.tsx @@ -37,7 +37,7 @@ export default async function Login(props: LoginProps) { {t("subtitle")} - + { }, [openAppSelectModal, createItem]); return ( - + @@ -183,7 +183,7 @@ const SelectBoardsMenu = () => { const { data: boards = [] } = clientApi.board.getAllBoards.useQuery(); return ( - + diff --git a/apps/nextjs/src/app/[locale]/init/_steps/finish/init-finish.tsx b/apps/nextjs/src/app/[locale]/init/_steps/finish/init-finish.tsx index 288b9adae..133581d58 100644 --- a/apps/nextjs/src/app/[locale]/init/_steps/finish/init-finish.tsx +++ b/apps/nextjs/src/app/[locale]/init/_steps/finish/init-finish.tsx @@ -15,7 +15,7 @@ export const InitFinish = async () => { const tFinish = await getScopedI18n("init.step.finish"); return ( - + {tFinish("description")} diff --git a/apps/nextjs/src/app/[locale]/init/_steps/group/init-group.tsx b/apps/nextjs/src/app/[locale]/init/_steps/group/init-group.tsx index 0a91d4ced..94424ef7d 100644 --- a/apps/nextjs/src/app/[locale]/init/_steps/group/init-group.tsx +++ b/apps/nextjs/src/app/[locale]/init/_steps/group/init-group.tsx @@ -34,7 +34,7 @@ export const InitGroup = () => { }; return ( - +
{ const tFileInfo = useScopedI18n("init.step.import.fileInfo"); return ( - + diff --git a/apps/nextjs/src/app/[locale]/init/_steps/import/init-import.tsx b/apps/nextjs/src/app/[locale]/init/_steps/import/init-import.tsx index 8b7124a03..cdb3faf50 100644 --- a/apps/nextjs/src/app/[locale]/init/_steps/import/init-import.tsx +++ b/apps/nextjs/src/app/[locale]/init/_steps/import/init-import.tsx @@ -20,7 +20,7 @@ export const InitImport = () => { if (!file) { return ( - + { diff --git a/apps/nextjs/src/app/[locale]/init/_steps/settings/init-settings.tsx b/apps/nextjs/src/app/[locale]/init/_steps/settings/init-settings.tsx index 3badc014e..cb024fc2f 100644 --- a/apps/nextjs/src/app/[locale]/init/_steps/settings/init-settings.tsx +++ b/apps/nextjs/src/app/[locale]/init/_steps/settings/init-settings.tsx @@ -30,7 +30,7 @@ export const InitSettings = () => { return ( - + {tSection("analytics.title")} @@ -39,7 +39,7 @@ export const InitSettings = () => { - + {tSection("crawlingAndIndexing.title")} diff --git a/apps/nextjs/src/app/[locale]/init/_steps/start/init-start.tsx b/apps/nextjs/src/app/[locale]/init/_steps/start/init-start.tsx index b5005f8b4..da858f1f4 100644 --- a/apps/nextjs/src/app/[locale]/init/_steps/start/init-start.tsx +++ b/apps/nextjs/src/app/[locale]/init/_steps/start/init-start.tsx @@ -10,7 +10,7 @@ export const InitStart = async () => { const tStart = await getScopedI18n("init.step.start"); return ( - + {tStart("description")} diff --git a/apps/nextjs/src/app/[locale]/init/_steps/user/init-user.tsx b/apps/nextjs/src/app/[locale]/init/_steps/user/init-user.tsx index 0f52de3dc..fa0ed777d 100644 --- a/apps/nextjs/src/app/[locale]/init/_steps/user/init-user.tsx +++ b/apps/nextjs/src/app/[locale]/init/_steps/user/init-user.tsx @@ -4,7 +4,7 @@ import { InitUserForm } from "./init-user-form"; export const InitUser = () => { return ( - + ); diff --git a/apps/nextjs/src/app/[locale]/layout.tsx b/apps/nextjs/src/app/[locale]/layout.tsx index 5449e1252..7cdd8dc7e 100644 --- a/apps/nextjs/src/app/[locale]/layout.tsx +++ b/apps/nextjs/src/app/[locale]/layout.tsx @@ -44,13 +44,13 @@ const fontSans = Inter({ export const generateMetadata = async (): Promise => ({ title: "Homarr", description: - "Simplify the management of your server with Homarr - a sleek, modern dashboard that puts all of your apps and services at your fingertips.", + "A self-hosted dashboard for the *arr stack and your entire homelab. Integrates with 50+ services, real-time widgets, no config files.", openGraph: { title: "Homarr Dashboard", description: - "Simplify the management of your server with Homarr - a sleek, modern dashboard that puts all of your apps and services at your fingertips.", + "A self-hosted dashboard for the *arr stack and your entire homelab. Integrates with 50+ services, real-time widgets, no config files.", url: "https://homarr.dev", - siteName: "Homarr Documentation", + siteName: "Homarr", }, icons: { icon: "/logo/logo.png", diff --git a/apps/nextjs/src/app/[locale]/manage/_components/hero-banner.tsx b/apps/nextjs/src/app/[locale]/manage/_components/hero-banner.tsx index b694ee81d..66c9e0398 100644 --- a/apps/nextjs/src/app/[locale]/manage/_components/hero-banner.tsx +++ b/apps/nextjs/src/app/[locale]/manage/_components/hero-banner.tsx @@ -45,7 +45,6 @@ export const HeroBanner = async () => { { - - Homarr - + Homarr {t("version", { version })} @@ -184,6 +182,7 @@ export default async function AboutPage() { + {" "} {Object.entries(dependencies) .filter(([, value]) => !value.includes("workspace:")) @@ -195,9 +194,9 @@ export default async function AboutPage() { href={`https://www.npmjs.com/package/${name}`} target="_blank" > - + - + diff --git a/apps/nextjs/src/app/[locale]/manage/apps/page.tsx b/apps/nextjs/src/app/[locale]/manage/apps/page.tsx index 27ab01fb5..5a8ec43d2 100644 --- a/apps/nextjs/src/app/[locale]/manage/apps/page.tsx +++ b/apps/nextjs/src/app/[locale]/manage/apps/page.tsx @@ -79,7 +79,7 @@ const AppCard = async ({ app }: AppCardProps) => { const session = await auth(); return ( - + { const VisibilityIcon = board.isPublic ? IconWorld : IconLock; return ( - + - - {board.name} - + {board.name} @@ -123,6 +121,7 @@ const BoardCard = async ({ board }: BoardCardProps) => { style={{ borderTop: "none", borderBottom: "none", borderRight: "none", borderRadius: 0 }} variant="default" size="lg" + aria-label={t("action.settings.label")} > diff --git a/apps/nextjs/src/app/[locale]/manage/integrations/_components/secrets/integration-secret-card.tsx b/apps/nextjs/src/app/[locale]/manage/integrations/_components/secrets/integration-secret-card.tsx index 06c4baff3..27ad484c4 100644 --- a/apps/nextjs/src/app/[locale]/manage/integrations/_components/secrets/integration-secret-card.tsx +++ b/apps/nextjs/src/app/[locale]/manage/integrations/_components/secrets/integration-secret-card.tsx @@ -33,7 +33,7 @@ export const SecretCard = ({ secret, children, onCancel }: SecretCardProps) => { const KindIcon = integrationSecretIcons[secret.kind]; return ( - + @@ -58,7 +58,12 @@ export const SecretCard = ({ secret, children, onCancel }: SecretCardProps) => { )} {isPublic ? ( - + ) : null} diff --git a/apps/nextjs/src/app/[locale]/manage/integrations/_components/test-connection/integration-test-connection-error.tsx b/apps/nextjs/src/app/[locale]/manage/integrations/_components/test-connection/integration-test-connection-error.tsx index cdaa70d93..a50625106 100644 --- a/apps/nextjs/src/app/[locale]/manage/integrations/_components/test-connection/integration-test-connection-error.tsx +++ b/apps/nextjs/src/app/[locale]/manage/integrations/_components/test-connection/integration-test-connection-error.tsx @@ -18,7 +18,7 @@ export const IntegrationTestConnectionError = ({ error, url }: IntegrationTestCo const causeArray = useMemo(() => toCauseArray(error.cause), [error.cause]); return ( - + diff --git a/apps/nextjs/src/app/[locale]/manage/integrations/_components/test-connection/test-connection-certificate.tsx b/apps/nextjs/src/app/[locale]/manage/integrations/_components/test-connection/test-connection-certificate.tsx index 9f7b00530..6ebbdbb6d 100644 --- a/apps/nextjs/src/app/[locale]/manage/integrations/_components/test-connection/test-connection-certificate.tsx +++ b/apps/nextjs/src/app/[locale]/manage/integrations/_components/test-connection/test-connection-certificate.tsx @@ -216,7 +216,7 @@ export const CertificateDetailsCard = ({ certificate }: CertificateDetailsProps) const tCertificateField = useScopedI18n("certificate.field"); return ( - + {tDetails("title")} diff --git a/apps/nextjs/src/app/[locale]/manage/integrations/page.module.css b/apps/nextjs/src/app/[locale]/manage/integrations/page.module.css index 34001e53b..551deb5ab 100644 --- a/apps/nextjs/src/app/[locale]/manage/integrations/page.module.css +++ b/apps/nextjs/src/app/[locale]/manage/integrations/page.module.css @@ -8,7 +8,7 @@ border: 1px solid transparent; position: relative; z-index: 0; - transition: transform 150ms ease; + transition: background-color 150ms ease; overflow: hidden; &[data-first="true"] { @@ -20,11 +20,9 @@ } &[data-active] { - transform: scale(1.01); z-index: 1; background-color: var(--mantine-color-body); border-color: light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-4)); - box-shadow: var(--mantine-shadow-md); border-radius: var(--mantine-radius-lg); } } diff --git a/apps/nextjs/src/app/[locale]/manage/not-found.tsx b/apps/nextjs/src/app/[locale]/manage/not-found.tsx index 8579e45c4..f6931af9f 100644 --- a/apps/nextjs/src/app/[locale]/manage/not-found.tsx +++ b/apps/nextjs/src/app/[locale]/manage/not-found.tsx @@ -7,9 +7,7 @@ export default async function NotFound() { return (
- - {t("title")} - + {t("title")} {t("text")}
diff --git a/apps/nextjs/src/app/[locale]/manage/page.tsx b/apps/nextjs/src/app/[locale]/manage/page.tsx index 256eaddb5..c7a3a1813 100644 --- a/apps/nextjs/src/app/[locale]/manage/page.tsx +++ b/apps/nextjs/src/app/[locale]/manage/page.tsx @@ -29,20 +29,20 @@ export default async function ManagementPage() { {statistics.map((statistic) => ( - + - + {statistic.count} - + {t(`statisticLabel.${statistic.subtitleKey}`)} - {t(`statistic.${statistic.titleKey}`)} + {t(`statistic.${statistic.titleKey}`)} - + ))} diff --git a/apps/nextjs/src/app/[locale]/manage/search-engines/page.tsx b/apps/nextjs/src/app/[locale]/manage/search-engines/page.tsx index ce2500d02..0ab5b814d 100644 --- a/apps/nextjs/src/app/[locale]/manage/search-engines/page.tsx +++ b/apps/nextjs/src/app/[locale]/manage/search-engines/page.tsx @@ -78,7 +78,7 @@ const SearchEngineCard = async ({ searchEngine }: SearchEngineCardProps) => { const session = await auth(); return ( - + { <> {t("title")} - - + + diff --git a/apps/nextjs/src/app/[locale]/manage/settings/_components/crawling-and-indexing.settings.tsx b/apps/nextjs/src/app/[locale]/manage/settings/_components/crawling-and-indexing.settings.tsx index b99f298ee..29206a473 100644 --- a/apps/nextjs/src/app/[locale]/manage/settings/_components/crawling-and-indexing.settings.tsx +++ b/apps/nextjs/src/app/[locale]/manage/settings/_components/crawling-and-indexing.settings.tsx @@ -41,11 +41,11 @@ export const CrawlingAndIndexingSettings = ({ initialData }: CrawlingAndIndexing <> {t("title")} - + {t("warning")} - + diff --git a/apps/nextjs/src/app/[locale]/manage/tools/certificates/page.tsx b/apps/nextjs/src/app/[locale]/manage/tools/certificates/page.tsx index cf1730736..422b9f858 100644 --- a/apps/nextjs/src/app/[locale]/manage/tools/certificates/page.tsx +++ b/apps/nextjs/src/app/[locale]/manage/tools/certificates/page.tsx @@ -79,7 +79,7 @@ export default async function CertificatesPage({ params }: CertificatesPageProps {x509Certificates.map((cert) => ( - + {cert.isError ? ( - @@ -253,7 +253,6 @@ const ContainerActionBarButton = (props: ContainerActionBarButtonProps) => { onClick={handleClickAsync} loading={isPending} variant="light" - radius="md" > {t(`${props.action}.label`)} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-card.module.css b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-card.module.css index b439e7f4b..dbc035932 100644 --- a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-card.module.css +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-card.module.css @@ -4,28 +4,16 @@ overflow: hidden; padding: var(--mantine-spacing-xs); padding-left: calc(var(--mantine-spacing-xs) * 2); - - @mixin hover { - box-shadow: var(--mantine-shadow-md); - } - - &::before { - content: ""; - position: absolute; - top: 0; - bottom: 0; - left: 0; - width: 6px; - background-image: linear-gradient(0, var(--mantine-color-blue-4), var(--mantine-color-blue-9)); - } + border-left: 1px solid var(--mantine-color-blue-6); + background-color: light-dark( + var(--mantine-color-blue-0), + color-mix(in oklch, var(--mantine-color-blue-9), transparent 85%) + ); @mixin rtl { padding-left: var(--mantine-spacing-xs); padding-right: calc(var(--mantine-spacing-xs) * 2); - - &::before { - left: unset; - right: 0; - } + border-left: none; + border-right: 1px solid var(--mantine-color-blue-6); } } diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-card.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-card.tsx index a8704e1b5..37ed66fe2 100644 --- a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-card.tsx +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-card.tsx @@ -23,7 +23,6 @@ export function HeaderCard(props: HeaderCardProps) { - + + diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-tile/resource-tile.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-tile/resource-tile.tsx index d2405fcf7..17c922c90 100644 --- a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-tile/resource-tile.tsx +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-tile/resource-tile.tsx @@ -17,12 +17,7 @@ interface ResourceTileProps { export function ResourceTile(props: ResourceTileProps) { const t = useI18n(); return ( - + {props.label} diff --git a/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_profile-avatar-form.tsx b/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_profile-avatar-form.tsx index e4ee64583..2137add34 100644 --- a/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_profile-avatar-form.tsx +++ b/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_profile-avatar-form.tsx @@ -95,7 +95,7 @@ export const UserProfileAvatarForm = ({ user }: UserProfileAvatarForm) => { return ( - + diff --git a/apps/nextjs/src/app/[locale]/manage/users/create/_components/create-user-stepper.tsx b/apps/nextjs/src/app/[locale]/manage/users/create/_components/create-user-stepper.tsx index fbaae76c7..f443ae585 100644 --- a/apps/nextjs/src/app/[locale]/manage/users/create/_components/create-user-stepper.tsx +++ b/apps/nextjs/src/app/[locale]/manage/users/create/_components/create-user-stepper.tsx @@ -149,7 +149,7 @@ export const UserCreateStepperComponent = ({ initialGroups }: UserCreateStepperC color={!generalForm.isValid() ? "red" : undefined} > - + - + - + @@ -198,20 +198,20 @@ export const UserCreateStepperComponent = ({ initialGroups }: UserCreateStepperC - + - + {generalForm.values.username} - + {t("step.completed.title")} diff --git a/apps/nextjs/src/app/[locale]/manage/users/create/_components/stepper-navigation.tsx b/apps/nextjs/src/app/[locale]/manage/users/create/_components/stepper-navigation.tsx index 24d003a84..675f3f435 100644 --- a/apps/nextjs/src/app/[locale]/manage/users/create/_components/stepper-navigation.tsx +++ b/apps/nextjs/src/app/[locale]/manage/users/create/_components/stepper-navigation.tsx @@ -25,7 +25,7 @@ export const StepperNavigationComponent = ({ }: StepperNavigationComponentProps) => { const t = useI18n(); return ( - + {!isComplete ? ( @@ -129,7 +129,7 @@ const SupportedIntegrations = ({ integrations, mt }: SupportedIntegrationsProps) return (
- + {integrations.slice(0, countToShow).map((integration) => ( diff --git a/apps/nextjs/src/components/board/sections/category-section.tsx b/apps/nextjs/src/components/board/sections/category-section.tsx index df204998b..2f6a65d72 100644 --- a/apps/nextjs/src/components/board/sections/category-section.tsx +++ b/apps/nextjs/src/components/board/sections/category-section.tsx @@ -27,13 +27,7 @@ export const BoardCategorySection = ({ section }: Props) => { }); return ( - + diff --git a/apps/nextjs/src/components/board/sections/category/category-menu.tsx b/apps/nextjs/src/components/board/sections/category/category-menu.tsx index 894db8949..9e3928198 100644 --- a/apps/nextjs/src/components/board/sections/category/category-menu.tsx +++ b/apps/nextjs/src/components/board/sections/category/category-menu.tsx @@ -30,9 +30,9 @@ export const CategoryMenu = ({ category }: Props) => { const t = useScopedI18n("section.category"); return ( - + - + diff --git a/apps/nextjs/src/components/board/sections/dynamic-section.tsx b/apps/nextjs/src/components/board/sections/dynamic-section.tsx index 39818c5de..8bb0a52c3 100644 --- a/apps/nextjs/src/components/board/sections/dynamic-section.tsx +++ b/apps/nextjs/src/components/board/sections/dynamic-section.tsx @@ -28,7 +28,6 @@ export const BoardDynamicSection = ({ section }: Props) => { className={combineClasses(classes.itemCard, section.options.customCssClasses.join(" "))} w="100%" h="100%" - withBorder styles={{ root: { overflow: "visible", diff --git a/apps/nextjs/src/components/board/sections/dynamic/dynamic-menu.tsx b/apps/nextjs/src/components/board/sections/dynamic/dynamic-menu.tsx index f73328024..cffc3446f 100644 --- a/apps/nextjs/src/components/board/sections/dynamic/dynamic-menu.tsx +++ b/apps/nextjs/src/components/board/sections/dynamic/dynamic-menu.tsx @@ -43,9 +43,17 @@ export const BoardDynamicSectionMenu = ({ section }: { section: DynamicSectionIt }; return ( - + - + diff --git a/apps/nextjs/src/components/layout/navigation-link.tsx b/apps/nextjs/src/components/layout/navigation-link.tsx index dd6949682..2d98d42ec 100644 --- a/apps/nextjs/src/components/layout/navigation-link.tsx +++ b/apps/nextjs/src/components/layout/navigation-link.tsx @@ -12,16 +12,7 @@ export const CommonNavLink = (props: ClientNavigationLink) => const NavLinkHref = (props: NavigationLinkHref) => { const pathname = usePathname(); return props.external ? ( - + ) : ( { leftSection={props.icon} href={props.href} active={pathname === props.href} - style={{ - borderRadius: 5, - }} /> ); }; @@ -40,14 +28,7 @@ const NavLinkWithItems = (props: NavigationLinkWithItems) => { const pathname = usePathname(); const isActive = props.items.some((item) => item.href === pathname); return ( - + {props.items.map((item) => ( ))} diff --git a/apps/nextjs/src/components/manage/danger-zone.tsx b/apps/nextjs/src/components/manage/danger-zone.tsx index 30bfb3e37..38f63185b 100644 --- a/apps/nextjs/src/components/manage/danger-zone.tsx +++ b/apps/nextjs/src/components/manage/danger-zone.tsx @@ -15,7 +15,7 @@ export const DangerZoneRoot = async ({ children }: DangerZoneRootProps) => { {t("common.dangerZone")} - + {Array.isArray(children) ? children.map((child, index) => ( diff --git a/apps/nextjs/src/components/no-results.tsx b/apps/nextjs/src/components/no-results.tsx index db492c2e1..992cd5c2b 100644 --- a/apps/nextjs/src/components/no-results.tsx +++ b/apps/nextjs/src/components/no-results.tsx @@ -14,7 +14,7 @@ interface NoResultsProps { export const NoResults = ({ icon: Icon, title, action }: NoResultsProps) => { return ( - + diff --git a/apps/nextjs/src/components/user-avatar-menu.tsx b/apps/nextjs/src/components/user-avatar-menu.tsx index 454ecca78..8faa8f6fa 100644 --- a/apps/nextjs/src/components/user-avatar-menu.tsx +++ b/apps/nextjs/src/components/user-avatar-menu.tsx @@ -52,7 +52,7 @@ export const UserAvatarMenu = ({ children, availableUpdatesPromise }: UserAvatar return ( // We use keepMounted so we can add event listeners to prevent navigating away without saving the board - + }>