From c33b09c5d434edba9a7b6d6527921d4ba4037ae9 Mon Sep 17 00:00:00 2001 From: Thomas Camlong Date: Mon, 18 May 2026 17:25:35 +0200 Subject: [PATCH] fix(users): fix mobile layout and add missing ddgBangsEnabled field to general settings form - Make avatar responsive on mobile (120px) vs desktop (200px) and center on mobile - Add missing ddgBangsEnabled field to form schema, initial values, mutation, and UI - Fix async function naming to satisfy lint rule --- .../general/_components/_general-settings-form.tsx | 13 ++++++++++--- .../general/_components/_profile-avatar-form.tsx | 7 ++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_general-settings-form.tsx b/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_general-settings-form.tsx index b142ceeb9..6d66d5abf 100644 --- a/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_general-settings-form.tsx +++ b/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_general-settings-form.tsx @@ -48,6 +48,7 @@ const userGeneralSettingsSchema = z.object({ mobileHomeBoardId: userChangeHomeBoardsSchema.shape.mobileHomeBoardId, defaultSearchEngineId: userChangeSearchPreferencesSchema.shape.defaultSearchEngineId, openInNewTab: userChangeSearchPreferencesSchema.shape.openInNewTab, + ddgBangsEnabled: userChangeSearchPreferencesSchema.shape.ddgBangsEnabled, firstDayOfWeek: userFirstDayOfWeekSchema.shape.firstDayOfWeek, pingIconsEnabled: userPingIconsEnabledSchema.shape.pingIconsEnabled, }); @@ -74,6 +75,7 @@ const buildInitialValues = (user: RouterOutputs["user"]["getById"]): FormValues mobileHomeBoardId: user.mobileHomeBoardId, defaultSearchEngineId: user.defaultSearchEngineId, openInNewTab: user.openSearchInNewTab, + ddgBangsEnabled: user.ddgBangs, firstDayOfWeek: user.firstDayOfWeek as DayOfWeek, pingIconsEnabled: user.pingIconsEnabled, }); @@ -124,7 +126,7 @@ export const UserGeneralSettingsForm = ({ return () => window.removeEventListener("beforeunload", handler); }, []); - const handleSubmit = async (values: FormValues) => { + const handleSubmitAsync = async (values: FormValues) => { const parsed = userGeneralSettingsSchema.safeParse(values); if (!parsed.success) return; @@ -148,12 +150,13 @@ export const UserGeneralSettingsForm = ({ }), }, { - when: changed("defaultSearchEngineId", "openInNewTab"), + when: changed("defaultSearchEngineId", "openInNewTab", "ddgBangsEnabled"), action: () => changeSearchPreferencesMutation.mutateAsync({ userId: user.id, defaultSearchEngineId: parsed.data.defaultSearchEngineId, openInNewTab: parsed.data.openInNewTab, + ddgBangsEnabled: parsed.data.ddgBangsEnabled, }), }, { @@ -196,7 +199,7 @@ export const UserGeneralSettingsForm = ({ }; return ( -
+ @@ -263,6 +266,10 @@ export const UserGeneralSettingsForm = ({ label={t("user.field.openSearchInNewTab.label")} {...form.getInputProps("openInNewTab", { type: "checkbox" })} /> + 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..58ff5ff6d 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 @@ -2,7 +2,7 @@ import { useCallback } from "react"; import { Box, Button, FileButton, Menu, UnstyledButton } from "@mantine/core"; -import { useDisclosure } from "@mantine/hooks"; +import { useDisclosure, useMediaQuery } from "@mantine/hooks"; import { IconPencil, IconPhotoEdit, IconPhotoX } from "@tabler/icons-react"; import type { RouterOutputs } from "@homarr/api"; @@ -25,6 +25,7 @@ export const UserProfileAvatarForm = ({ user }: UserProfileAvatarForm) => { }, }); const [opened, { toggle }] = useDisclosure(false); + const isMobile = useMediaQuery("(max-width: 48em)"); const { openConfirmModal } = useConfirmModal(); const t = useI18n(); const tManageAvatar = useScopedI18n("user.action.manageAvatar"); @@ -94,11 +95,11 @@ export const UserProfileAvatarForm = ({ user }: UserProfileAvatarForm) => { }, [mutate, user.id, openConfirmModal, tManageAvatar]); return ( - + - +