createTheme was called without being imported, causing a runtime
ReferenceError on every page load. Use the already-imported theme
object from @homarr/ui which contains the full Mantine configuration.
* feat(board): persist category collapse state in localStorage for guests
Authenticated users already had their collapse state saved server-side.
This extends the same behaviour to unauthenticated (guest) users by
reading/writing localStorage keyed by section ID.
On mount, if the user is a guest, the stored value is applied to the
disclosure. On toggle, guests write to localStorage instead of calling
the protected API mutation.
Closes#3355
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor: set localStorage value as useDisclosure default instead of useEffect
Replaces the useEffect that read localStorage after mount with a direct
initial value computation passed to useDisclosure. Removes the effect,
the open/close destructuring, and the useEffect import.
Note: initialCollapsed is computed during render rather than post-mount,
which may cause a hydration mismatch on SSR if localStorage differs from
the server-provided section.collapsed. The typeof window guard handles
the SSR case.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
When adding a widget from the "Choose item to add" modal, the widget
edit modal now opens immediately after placement, allowing the user to
configure options and integrations before the widget renders.
All available integrations for the widget are selected by default.
Wrap getInitialBoardAsync in React cache() so the same board data is
fetched once per request instead of 3 times (layout, page, metadata).
This is the same pattern used for auth() in the codebase.
Remove useIsBoardReady and LoadingOverlay from edit mode board,
aligning with the dev branch's perf improvement that shows the board
immediately without waiting for ready state.
Provide estimated width/height to widgets before useElementSize
measures the DOM, preventing responsive breakpoint shifts during
hydration. Replace the Loader spinner with a Skeleton for widget
loading states.
Add useOptionalSectionContext to gracefully handle rendering outside
GridStack (view mode). The item menu now uses optional chaining for
gridstack access instead of throwing when context is absent.
Split board rendering into two modes: a static CSS Grid for view mode
(SSR-friendly, no JS required for layout) and a lazy-loaded GridStack
for edit mode. This eliminates widget "pop-in" on page load by rendering
the full grid layout server-side.
When adding a widget from the "Choose item to add" modal, the widget
edit modal now opens immediately after placement, allowing the user to
configure options and integrations before the widget renders.
All available integrations for the widget are selected by default.