diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index eb3bba3d6..b9d99f449 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -31,6 +31,7 @@ body:
label: Version
description: What version of Homarr are you running?
options:
+ - 1.2.0
- 1.1.0
- 1.0.1
- 1.0.0
diff --git a/apps/nextjs/package.json b/apps/nextjs/package.json
index ae9ab5072..65b54ffd3 100644
--- a/apps/nextjs/package.json
+++ b/apps/nextjs/package.json
@@ -36,23 +36,24 @@
"@homarr/old-schema": "workspace:^0.1.0",
"@homarr/redis": "workspace:^0.1.0",
"@homarr/server-settings": "workspace:^0.1.0",
+ "@homarr/settings": "workspace:^0.1.0",
"@homarr/spotlight": "workspace:^0.1.0",
"@homarr/translation": "workspace:^0.1.0",
"@homarr/ui": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@homarr/widgets": "workspace:^0.1.0",
- "@mantine/colors-generator": "^7.16.1",
- "@mantine/core": "^7.16.1",
- "@mantine/dropzone": "^7.16.1",
- "@mantine/hooks": "^7.16.1",
- "@mantine/modals": "^7.16.1",
- "@mantine/tiptap": "^7.16.1",
+ "@mantine/colors-generator": "^7.16.2",
+ "@mantine/core": "^7.16.2",
+ "@mantine/dropzone": "^7.16.2",
+ "@mantine/hooks": "^7.16.2",
+ "@mantine/modals": "^7.16.2",
+ "@mantine/tiptap": "^7.16.2",
"@million/lint": "1.0.14",
- "@t3-oss/env-nextjs": "^0.11.1",
+ "@t3-oss/env-nextjs": "^0.12.0",
"@tabler/icons-react": "^3.29.0",
- "@tanstack/react-query": "^5.64.2",
- "@tanstack/react-query-devtools": "^5.64.2",
- "@tanstack/react-query-next-experimental": "5.64.2",
+ "@tanstack/react-query": "^5.65.0",
+ "@tanstack/react-query-devtools": "^5.65.0",
+ "@tanstack/react-query-next-experimental": "^5.65.0",
"@trpc/client": "next",
"@trpc/next": "next",
"@trpc/react-query": "next",
@@ -78,7 +79,8 @@
"sass": "^1.83.4",
"superjson": "2.2.2",
"swagger-ui-react": "^5.18.2",
- "use-deep-compare-effect": "^1.8.1"
+ "use-deep-compare-effect": "^1.8.1",
+ "zod": "^3.24.1"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
@@ -89,9 +91,9 @@
"@types/prismjs": "^1.26.5",
"@types/react": "19.0.8",
"@types/react-dom": "19.0.3",
- "@types/swagger-ui-react": "^4.18.3",
+ "@types/swagger-ui-react": "^4.19.0",
"concurrently": "^9.1.2",
- "eslint": "^9.18.0",
+ "eslint": "^9.19.0",
"node-loader": "^2.1.0",
"prettier": "^3.4.2",
"typescript": "^5.7.3"
diff --git a/apps/nextjs/src/app/[locale]/auth/invite/[id]/_registration-form.tsx b/apps/nextjs/src/app/[locale]/auth/invite/[id]/_registration-form.tsx
index 4c86fa61b..3f2689234 100644
--- a/apps/nextjs/src/app/[locale]/auth/invite/[id]/_registration-form.tsx
+++ b/apps/nextjs/src/app/[locale]/auth/invite/[id]/_registration-form.tsx
@@ -2,13 +2,13 @@
import { useRouter } from "next/navigation";
import { Button, PasswordInput, Stack, TextInput } from "@mantine/core";
+import type { z } from "zod";
import { clientApi } from "@homarr/api/client";
import { useZodForm } from "@homarr/form";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useScopedI18n } from "@homarr/translation/client";
import { CustomPasswordInput } from "@homarr/ui";
-import type { z } from "@homarr/validation";
import { validation } from "@homarr/validation";
interface RegistrationFormProps {
diff --git a/apps/nextjs/src/app/[locale]/auth/login/_login-form.tsx b/apps/nextjs/src/app/[locale]/auth/login/_login-form.tsx
index f4ce00f67..6a013101f 100644
--- a/apps/nextjs/src/app/[locale]/auth/login/_login-form.tsx
+++ b/apps/nextjs/src/app/[locale]/auth/login/_login-form.tsx
@@ -5,6 +5,7 @@ import { useCallback, useEffect, useRef, useState } from "react";
import { useRouter } from "next/navigation";
import { Anchor, Button, Card, Code, Collapse, Divider, PasswordInput, Stack, Text, TextInput } from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
+import { z } from "zod";
import { signIn } from "@homarr/auth/client";
import { revalidatePathActionAsync } from "@homarr/common/client";
@@ -12,7 +13,7 @@ import type { useForm } from "@homarr/form";
import { useZodForm } from "@homarr/form";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useScopedI18n } from "@homarr/translation/client";
-import { validation, z } from "@homarr/validation";
+import { validation } from "@homarr/validation";
interface LoginFormProps {
providers: string[];
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 93839a457..849891220 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
@@ -2,12 +2,12 @@
import { Button, Card, Stack, TextInput } from "@mantine/core";
import { IconArrowRight } from "@tabler/icons-react";
+import type { z } from "zod";
import { clientApi } from "@homarr/api/client";
import { revalidatePathActionAsync } from "@homarr/common/client";
import { useZodForm } from "@homarr/form";
import { useI18n } from "@homarr/translation/client";
-import type { z } from "@homarr/validation";
import { validation } from "@homarr/validation";
export const InitGroup = () => {
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 90e8c7a8d..3d40a4445 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
@@ -3,6 +3,7 @@
import { startTransition } from "react";
import { Button, Card, Group, Stack, Switch, Text } from "@mantine/core";
import { IconArrowRight } from "@tabler/icons-react";
+import type { z } from "zod";
import { clientApi } from "@homarr/api/client";
import { revalidatePathActionAsync } from "@homarr/common/client";
@@ -11,7 +12,6 @@ import type { CheckboxProps } from "@homarr/form/types";
import { defaultServerSettings } from "@homarr/server-settings";
import type { TranslationObject } from "@homarr/translation";
import { useI18n, useScopedI18n } from "@homarr/translation/client";
-import type { z } from "@homarr/validation";
import { validation } from "@homarr/validation";
export const InitSettings = () => {
diff --git a/apps/nextjs/src/app/[locale]/init/_steps/user/init-user-form.tsx b/apps/nextjs/src/app/[locale]/init/_steps/user/init-user-form.tsx
index 2dcfac8f1..e094ce4ce 100644
--- a/apps/nextjs/src/app/[locale]/init/_steps/user/init-user-form.tsx
+++ b/apps/nextjs/src/app/[locale]/init/_steps/user/init-user-form.tsx
@@ -1,6 +1,7 @@
"use client";
import { Button, PasswordInput, Stack, TextInput } from "@mantine/core";
+import type { z } from "zod";
import { clientApi } from "@homarr/api/client";
import { revalidatePathActionAsync } from "@homarr/common/client";
@@ -8,7 +9,6 @@ import { useZodForm } from "@homarr/form";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useScopedI18n } from "@homarr/translation/client";
import { CustomPasswordInput } from "@homarr/ui";
-import type { z } from "@homarr/validation";
import { validation } from "@homarr/validation";
export const InitUserForm = () => {
diff --git a/apps/nextjs/src/app/[locale]/layout.tsx b/apps/nextjs/src/app/[locale]/layout.tsx
index 8f145ee3c..1a04d8c7e 100644
--- a/apps/nextjs/src/app/[locale]/layout.tsx
+++ b/apps/nextjs/src/app/[locale]/layout.tsx
@@ -9,10 +9,14 @@ import "~/styles/scroll-area.scss";
import { notFound } from "next/navigation";
import { NextIntlClientProvider } from "next-intl";
+import { api } from "@homarr/api/server";
import { env } from "@homarr/auth/env";
import { auth } from "@homarr/auth/next";
+import { db } from "@homarr/db";
+import { getServerSettingsAsync } from "@homarr/db/queries";
import { ModalProvider } from "@homarr/modals";
import { Notifications } from "@homarr/notifications";
+import { SettingsProvider } from "@homarr/settings";
import { SpotlightProvider } from "@homarr/spotlight";
import type { SupportedLanguage } from "@homarr/translation";
import { isLocaleRTL, isLocaleSupported } from "@homarr/translation";
@@ -73,6 +77,8 @@ export default async function Layout(props: {
}
const session = await auth();
+ const user = session ? await api.user.getById({ userId: session.user.id }).catch(() => null) : null;
+ const serverSettings = await getServerSettingsAsync(db);
const colorScheme = await getCurrentColorSchemeAsync();
const direction = isLocaleRTL((await props.params).locale) ? "rtl" : "ltr";
const i18nMessages = await getI18nMessages();
@@ -81,6 +87,19 @@ export default async function Layout(props: {
(innerProps) => {
return ;
},
+ (innerProps) => (
+
+ ),
(innerProps) => ,
(innerProps) => ,
(innerProps) => ,
diff --git a/apps/nextjs/src/app/[locale]/manage/apps/_form.tsx b/apps/nextjs/src/app/[locale]/manage/apps/_form.tsx
index 2cf9bf9b3..75d75e472 100644
--- a/apps/nextjs/src/app/[locale]/manage/apps/_form.tsx
+++ b/apps/nextjs/src/app/[locale]/manage/apps/_form.tsx
@@ -2,11 +2,11 @@
import Link from "next/link";
import { Button, Group, Stack, Textarea, TextInput } from "@mantine/core";
+import type { z } from "zod";
import { useZodForm } from "@homarr/form";
import type { TranslationFunction } from "@homarr/translation";
import { useI18n } from "@homarr/translation/client";
-import type { z } from "@homarr/validation";
import { validation } from "@homarr/validation";
import { IconPicker } from "~/components/icons/picker/icon-picker";
@@ -25,11 +25,11 @@ export const AppForm = (props: AppFormProps) => {
const t = useI18n();
const form = useZodForm(validation.app.manage, {
- initialValues: initialValues ?? {
- name: "",
- description: "",
- iconUrl: "",
- href: "",
+ initialValues: {
+ name: initialValues?.name ?? "",
+ description: initialValues?.description ?? "",
+ iconUrl: initialValues?.iconUrl ?? "",
+ href: initialValues?.href ?? "",
},
});
diff --git a/apps/nextjs/src/app/[locale]/manage/apps/edit/[id]/_app-edit-form.tsx b/apps/nextjs/src/app/[locale]/manage/apps/edit/[id]/_app-edit-form.tsx
index 9c34c160a..69df2bcb4 100644
--- a/apps/nextjs/src/app/[locale]/manage/apps/edit/[id]/_app-edit-form.tsx
+++ b/apps/nextjs/src/app/[locale]/manage/apps/edit/[id]/_app-edit-form.tsx
@@ -2,6 +2,7 @@
import { useCallback } from "react";
import { useRouter } from "next/navigation";
+import type { z } from "zod";
import type { RouterOutputs } from "@homarr/api";
import { clientApi } from "@homarr/api/client";
@@ -9,7 +10,7 @@ import { revalidatePathActionAsync } from "@homarr/common/client";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import type { TranslationFunction } from "@homarr/translation";
import { useScopedI18n } from "@homarr/translation/client";
-import type { validation, z } from "@homarr/validation";
+import type { validation } from "@homarr/validation";
import { AppForm } from "../../_form";
diff --git a/apps/nextjs/src/app/[locale]/manage/apps/new/_app-new-form.tsx b/apps/nextjs/src/app/[locale]/manage/apps/new/_app-new-form.tsx
index 42a9ea40f..d78f6bba5 100644
--- a/apps/nextjs/src/app/[locale]/manage/apps/new/_app-new-form.tsx
+++ b/apps/nextjs/src/app/[locale]/manage/apps/new/_app-new-form.tsx
@@ -2,13 +2,14 @@
import { useCallback } from "react";
import { useRouter } from "next/navigation";
+import type { z } from "zod";
import { clientApi } from "@homarr/api/client";
import { revalidatePathActionAsync } from "@homarr/common/client";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import type { TranslationFunction } from "@homarr/translation";
import { useScopedI18n } from "@homarr/translation/client";
-import type { validation, z } from "@homarr/validation";
+import type { validation } from "@homarr/validation";
import { AppForm } from "../_form";
diff --git a/apps/nextjs/src/app/[locale]/manage/apps/page.tsx b/apps/nextjs/src/app/[locale]/manage/apps/page.tsx
index 5193166f3..c53f5e19f 100644
--- a/apps/nextjs/src/app/[locale]/manage/apps/page.tsx
+++ b/apps/nextjs/src/app/[locale]/manage/apps/page.tsx
@@ -2,6 +2,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 { IconBox, IconPencil } from "@tabler/icons-react";
+import { z } from "zod";
import type { RouterOutputs } from "@homarr/api";
import { api } from "@homarr/api/server";
@@ -9,7 +10,6 @@ import { auth } from "@homarr/auth/next";
import type { inferSearchParamsFromSchema } from "@homarr/common/types";
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";
diff --git a/apps/nextjs/src/app/[locale]/manage/integrations/edit/[id]/_integration-edit-form.tsx b/apps/nextjs/src/app/[locale]/manage/integrations/edit/[id]/_integration-edit-form.tsx
index 867689b7e..b1b053e23 100644
--- a/apps/nextjs/src/app/[locale]/manage/integrations/edit/[id]/_integration-edit-form.tsx
+++ b/apps/nextjs/src/app/[locale]/manage/integrations/edit/[id]/_integration-edit-form.tsx
@@ -3,6 +3,7 @@
import Link from "next/link";
import { useRouter } from "next/navigation";
import { Button, Fieldset, Group, Stack, TextInput } from "@mantine/core";
+import type { z } from "zod";
import type { RouterOutputs } from "@homarr/api";
import { clientApi } from "@homarr/api/client";
@@ -13,7 +14,6 @@ import { convertIntegrationTestConnectionError } from "@homarr/integrations/clie
import { useConfirmModal } from "@homarr/modals";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useI18n } from "@homarr/translation/client";
-import type { z } from "@homarr/validation";
import { validation } from "@homarr/validation";
import { SecretCard } from "../../_components/secrets/integration-secret-card";
diff --git a/apps/nextjs/src/app/[locale]/manage/integrations/new/_integration-new-form.tsx b/apps/nextjs/src/app/[locale]/manage/integrations/new/_integration-new-form.tsx
index a223e3bfc..5b11392a2 100644
--- a/apps/nextjs/src/app/[locale]/manage/integrations/new/_integration-new-form.tsx
+++ b/apps/nextjs/src/app/[locale]/manage/integrations/new/_integration-new-form.tsx
@@ -5,6 +5,7 @@ import Link from "next/link";
import { useRouter } from "next/navigation";
import { Alert, Button, Checkbox, Fieldset, Group, SegmentedControl, Stack, Text, TextInput } from "@mantine/core";
import { IconInfoCircle } from "@tabler/icons-react";
+import type { z } from "zod";
import { clientApi } from "@homarr/api/client";
import { revalidatePathActionAsync } from "@homarr/common/client";
@@ -15,7 +16,6 @@ import { useZodForm } from "@homarr/form";
import { convertIntegrationTestConnectionError } from "@homarr/integrations/client";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useI18n, useScopedI18n } from "@homarr/translation/client";
-import type { z } from "@homarr/validation";
import { validation } from "@homarr/validation";
import { IntegrationSecretInput } from "../_components/secrets/integration-secret-inputs";
diff --git a/apps/nextjs/src/app/[locale]/manage/integrations/new/page.tsx b/apps/nextjs/src/app/[locale]/manage/integrations/new/page.tsx
index 4237c1422..dba8e5c1f 100644
--- a/apps/nextjs/src/app/[locale]/manage/integrations/new/page.tsx
+++ b/apps/nextjs/src/app/[locale]/manage/integrations/new/page.tsx
@@ -1,5 +1,6 @@
import { notFound } from "next/navigation";
import { Container, Group, Stack, Title } from "@mantine/core";
+import { z } from "zod";
import { auth } from "@homarr/auth/next";
import type { IntegrationKind } from "@homarr/definitions";
@@ -7,7 +8,6 @@ import { getIntegrationName, integrationKinds } from "@homarr/definitions";
import { getScopedI18n } from "@homarr/translation/server";
import { IntegrationAvatar } from "@homarr/ui";
import type { validation } from "@homarr/validation";
-import { z } from "@homarr/validation";
import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb";
import { NewIntegrationForm } from "./_integration-new-form";
diff --git a/apps/nextjs/src/app/[locale]/manage/medias/page.tsx b/apps/nextjs/src/app/[locale]/manage/medias/page.tsx
index e5c9b98e1..3883fcb24 100644
--- a/apps/nextjs/src/app/[locale]/manage/medias/page.tsx
+++ b/apps/nextjs/src/app/[locale]/manage/medias/page.tsx
@@ -16,6 +16,7 @@ import {
Tooltip,
} from "@mantine/core";
import { IconExternalLink } from "@tabler/icons-react";
+import { z } from "zod";
import type { RouterOutputs } from "@homarr/api";
import { api } from "@homarr/api/server";
@@ -25,7 +26,6 @@ import type { inferSearchParamsFromSchema } from "@homarr/common/types";
import { createLocalImageUrl } from "@homarr/icons/local";
import { getI18n } from "@homarr/translation/server";
import { SearchInput, TablePagination, UserAvatar } from "@homarr/ui";
-import { z } from "@homarr/validation";
import { ManageContainer } from "~/components/manage/manage-container";
import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb";
diff --git a/apps/nextjs/src/app/[locale]/manage/search-engines/_form.tsx b/apps/nextjs/src/app/[locale]/manage/search-engines/_form.tsx
index 4db3ba01a..9fa71510b 100644
--- a/apps/nextjs/src/app/[locale]/manage/search-engines/_form.tsx
+++ b/apps/nextjs/src/app/[locale]/manage/search-engines/_form.tsx
@@ -4,13 +4,13 @@ import Link from "next/link";
import type { SegmentedControlItem } from "@mantine/core";
import { Button, Fieldset, Grid, Group, SegmentedControl, Stack, Textarea, TextInput } from "@mantine/core";
import { WidgetIntegrationSelect } from "node_modules/@homarr/widgets/src/widget-integration-select";
+import type { z } from "zod";
import { clientApi } from "@homarr/api/client";
import { searchEngineTypes } from "@homarr/definitions";
import { useZodForm } from "@homarr/form";
import type { TranslationFunction } from "@homarr/translation";
import { useI18n } from "@homarr/translation/client";
-import type { z } from "@homarr/validation";
import { validation } from "@homarr/validation";
import { IconPicker } from "~/components/icons/picker/icon-picker";
diff --git a/apps/nextjs/src/app/[locale]/manage/search-engines/edit/[id]/_search-engine-edit-form.tsx b/apps/nextjs/src/app/[locale]/manage/search-engines/edit/[id]/_search-engine-edit-form.tsx
index 93782e597..cc4c1eb79 100644
--- a/apps/nextjs/src/app/[locale]/manage/search-engines/edit/[id]/_search-engine-edit-form.tsx
+++ b/apps/nextjs/src/app/[locale]/manage/search-engines/edit/[id]/_search-engine-edit-form.tsx
@@ -2,6 +2,7 @@
import { useCallback } from "react";
import { useRouter } from "next/navigation";
+import type { z } from "zod";
import type { RouterOutputs } from "@homarr/api";
import { clientApi } from "@homarr/api/client";
@@ -9,7 +10,7 @@ import { revalidatePathActionAsync } from "@homarr/common/client";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import type { TranslationFunction } from "@homarr/translation";
import { useScopedI18n } from "@homarr/translation/client";
-import type { validation, z } from "@homarr/validation";
+import type { validation } from "@homarr/validation";
import { SearchEngineForm } from "../../_form";
diff --git a/apps/nextjs/src/app/[locale]/manage/search-engines/new/_search-engine-new-form.tsx b/apps/nextjs/src/app/[locale]/manage/search-engines/new/_search-engine-new-form.tsx
index 59fe95ccd..b5824d3c1 100644
--- a/apps/nextjs/src/app/[locale]/manage/search-engines/new/_search-engine-new-form.tsx
+++ b/apps/nextjs/src/app/[locale]/manage/search-engines/new/_search-engine-new-form.tsx
@@ -2,13 +2,14 @@
import { useCallback } from "react";
import { useRouter } from "next/navigation";
+import type { z } from "zod";
import { clientApi } from "@homarr/api/client";
import { revalidatePathActionAsync } from "@homarr/common/client";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import type { TranslationFunction } from "@homarr/translation";
import { useScopedI18n } from "@homarr/translation/client";
-import type { validation, z } from "@homarr/validation";
+import type { validation } from "@homarr/validation";
import { SearchEngineForm } from "../_form";
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 8caeefbe7..0ecfa0cec 100644
--- a/apps/nextjs/src/app/[locale]/manage/search-engines/page.tsx
+++ b/apps/nextjs/src/app/[locale]/manage/search-engines/page.tsx
@@ -2,6 +2,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 { IconPencil, IconSearch } from "@tabler/icons-react";
+import { z } from "zod";
import type { RouterOutputs } from "@homarr/api";
import { api } from "@homarr/api/server";
@@ -9,7 +10,6 @@ import { auth } from "@homarr/auth/next";
import type { inferSearchParamsFromSchema } from "@homarr/common/types";
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";
diff --git a/apps/nextjs/src/app/[locale]/manage/tools/certificates/_components/add-certificate.tsx b/apps/nextjs/src/app/[locale]/manage/tools/certificates/_components/add-certificate.tsx
index 312abdffb..87aaa058f 100644
--- a/apps/nextjs/src/app/[locale]/manage/tools/certificates/_components/add-certificate.tsx
+++ b/apps/nextjs/src/app/[locale]/manage/tools/certificates/_components/add-certificate.tsx
@@ -2,6 +2,7 @@
import { Button, FileInput, Group, Stack } from "@mantine/core";
import { IconCertificate } from "@tabler/icons-react";
+import { z } from "zod";
import { clientApi } from "@homarr/api/client";
import { revalidatePathActionAsync } from "@homarr/common/client";
@@ -9,7 +10,7 @@ import { useZodForm } from "@homarr/form";
import { createModal, useModalAction } from "@homarr/modals";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useI18n } from "@homarr/translation/client";
-import { superRefineCertificateFile, z } from "@homarr/validation";
+import { superRefineCertificateFile } from "@homarr/validation";
export const AddCertificateButton = () => {
const { openModal } = useModalAction(AddCertificateModal);
diff --git a/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_change-home-board.tsx b/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_change-home-board.tsx
index 7a5b58817..9dc3a6491 100644
--- a/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_change-home-board.tsx
+++ b/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_change-home-board.tsx
@@ -1,6 +1,7 @@
"use client";
import { Button, Group, Select, Stack } from "@mantine/core";
+import type { z } from "zod";
import type { RouterOutputs } from "@homarr/api";
import { clientApi } from "@homarr/api/client";
@@ -8,7 +9,6 @@ import { revalidatePathActionAsync } from "@homarr/common/client";
import { useZodForm } from "@homarr/form";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useI18n } from "@homarr/translation/client";
-import type { z } from "@homarr/validation";
import { validation } from "@homarr/validation";
interface ChangeHomeBoardFormProps {
diff --git a/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_change-default-search-engine.tsx b/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_change-search-preferences.tsx
similarity index 53%
rename from apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_change-default-search-engine.tsx
rename to apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_change-search-preferences.tsx
index 367fa4098..5fabe8d4f 100644
--- a/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_change-default-search-engine.tsx
+++ b/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_change-search-preferences.tsx
@@ -1,6 +1,7 @@
"use client";
-import { Button, Group, Select, Stack } from "@mantine/core";
+import { Button, Group, Select, Stack, Switch } from "@mantine/core";
+import type { z } from "zod";
import type { RouterOutputs } from "@homarr/api";
import { clientApi } from "@homarr/api/client";
@@ -8,37 +9,38 @@ import { revalidatePathActionAsync } from "@homarr/common/client";
import { useZodForm } from "@homarr/form";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useI18n } from "@homarr/translation/client";
-import type { z } from "@homarr/validation";
import { validation } from "@homarr/validation";
-interface ChangeDefaultSearchEngineFormProps {
+interface ChangeSearchPreferencesFormProps {
user: RouterOutputs["user"]["getById"];
searchEnginesData: { value: string; label: string }[];
}
-export const ChangeDefaultSearchEngineForm = ({ user, searchEnginesData }: ChangeDefaultSearchEngineFormProps) => {
+export const ChangeSearchPreferencesForm = ({ user, searchEnginesData }: ChangeSearchPreferencesFormProps) => {
const t = useI18n();
- const { mutate, isPending } = clientApi.user.changeDefaultSearchEngine.useMutation({
+ const { mutate, isPending } = clientApi.user.changeSearchPreferences.useMutation({
async onSettled() {
await revalidatePathActionAsync(`/manage/users/${user.id}`);
},
onSuccess(_, variables) {
form.setInitialValues({
defaultSearchEngineId: variables.defaultSearchEngineId,
+ openInNewTab: variables.openInNewTab,
});
showSuccessNotification({
- message: t("user.action.changeDefaultSearchEngine.notification.success.message"),
+ message: t("user.action.changeSearchPreferences.notification.success.message"),
});
},
onError() {
showErrorNotification({
- message: t("user.action.changeDefaultSearchEngine.notification.error.message"),
+ message: t("user.action.changeSearchPreferences.notification.error.message"),
});
},
});
- const form = useZodForm(validation.user.changeDefaultSearchEngine, {
+ const form = useZodForm(validation.user.changeSearchPreferences, {
initialValues: {
- defaultSearchEngineId: user.defaultSearchEngineId ?? "",
+ defaultSearchEngineId: user.defaultSearchEngineId,
+ openInNewTab: user.openSearchInNewTab,
},
});
@@ -52,7 +54,16 @@ export const ChangeDefaultSearchEngineForm = ({ user, searchEnginesData }: Chang
return (