diff --git a/apps/nextjs/package.json b/apps/nextjs/package.json
index 21f9616a7..6f226d808 100644
--- a/apps/nextjs/package.json
+++ b/apps/nextjs/package.json
@@ -36,6 +36,7 @@
"@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",
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/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 54%
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 952014acb..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,6 @@
"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";
@@ -11,34 +11,36 @@ import { showErrorNotification, showSuccessNotification } from "@homarr/notifica
import { useI18n } from "@homarr/translation/client";
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 (