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 (
- +