diff --git a/server/src/routes/rootRouter.js b/server/src/routes/rootRouter.js index a2feb1428..4148f8bfa 100644 --- a/server/src/routes/rootRouter.js +++ b/server/src/routes/rootRouter.js @@ -180,6 +180,9 @@ rootRouter.get('/api/settings', async (req, res, next) => { req.session.save() } } + if (user.data !== undefined) { + req.user.data = user.data + } } } catch (e) { log.warn(TAGS.session, 'Issue finding user, User ID:', req?.user?.id, e) diff --git a/src/features/profile/ExtraFields.jsx b/src/features/profile/ExtraFields.jsx index 3a5daef79..b08684cbc 100644 --- a/src/features/profile/ExtraFields.jsx +++ b/src/features/profile/ExtraFields.jsx @@ -8,7 +8,8 @@ import { useTranslation } from 'react-i18next' import { useMemory } from '@store/useMemory' import { Query } from '@services/queries' -export function ExtraUserFields() { +/** @param {{ refreshing?: boolean }} props */ +export function ExtraUserFields({ refreshing = false } = {}) { const fields = useMemory((s) => s.extraUserFields) return fields?.length ? ( @@ -16,14 +17,20 @@ export function ExtraUserFields() { ))} ) : null } -/** @param {{ field: import('@rm/types').ExtraField | string}} props */ -export function FieldValue({ field }) { +/** + * @param {{ + * field: import('@rm/types').ExtraField | string, + * refreshing?: boolean, + * }} props + */ +export function FieldValue({ field, refreshing = false }) { const { i18n } = useTranslation() const label = typeof field === 'string' ? field : field[i18n.language] || field.name @@ -37,24 +44,25 @@ export function FieldValue({ field }) { return ( { + const nextValue = target.value useMemory.setState((prev) => ({ auth: { ...prev.auth, data: { ...prev.auth.data, - [key]: target.value, + [key]: nextValue, }, }, })) setField({ variables: { key, - value, + value: nextValue, }, }) }} diff --git a/src/features/profile/index.jsx b/src/features/profile/index.jsx index 564e1e113..852ab874e 100644 --- a/src/features/profile/index.jsx +++ b/src/features/profile/index.jsx @@ -15,6 +15,7 @@ import { Header } from '@components/dialogs/Header' import { Footer } from '@components/dialogs/Footer' import { DialogWrapper } from '@components/dialogs/DialogWrapper' import { useAnalytics } from '@hooks/useAnalytics' +import { getSettings } from '@services/fetches' import { UserBackups } from './Backups' import { UserPermissions } from './Permissions' @@ -32,6 +33,49 @@ export function UserProfile() { const [tab, setTab] = React.useState('profile') const [tabsHeight, setTabsHeight] = React.useState(0) + const [refreshing, setRefreshing] = React.useState(false) + const isOpen = useLayoutStore((s) => s.userProfile) + React.useEffect(() => { + if (!isOpen) return + let active = true + setRefreshing(true) + ;(async () => { + try { + const data = await getSettings() + if (data && !('error' in data) && data.user) { + const parsed = data.user?.data + ? typeof data.user.data === 'string' + ? JSON.parse(data.user.data) + : data.user.data + : {} + if (active) { + useMemory.setState((prev) => ({ + auth: { + ...prev.auth, + data: + parsed && typeof parsed === 'object' + ? parsed + : /** @type {Record} */ ({}), + }, + })) + } + } + } catch (error) { + if (active) { + // eslint-disable-next-line no-console + console.error('Failed to refresh user profile data', error) + } + } finally { + if (active) { + setRefreshing(false) + } + } + })() + return () => { + active = false + setRefreshing(false) + } + }, [isOpen]) const handleTabChange = (_event, newValue) => { setTab(newValue) @@ -67,7 +111,7 @@ export function UserProfile() { > - +