feat(web): settings to keep the search open and hide home pickers; collapsible menu sections
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 2m44s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m43s
ci / ts / ts (packages + web) (push) Successful in 1m16s
ci / api / api (push) Successful in 2m27s
ci / db / db (push) Successful in 2m23s

- appearance settings get "collapse search" (off keeps the field always open)
  and separate switches for the activity and mood pickers on the home page;
  stored in ui_prefs (search_collapse, home_activities, home_moods)
- Collection and Admin headers in the sidebar fold their items; the state is
  remembered in the browser, a folded Admin shows the review queue badge;
  icon-only and phone layouts always show every item

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mrleo1nidandClaude Opus 5.5 committed 2026-10-21 08:26:48 +03:00
1 parent 73e642c1ec
commit b27b915b63
13 files changed
+470 -284

No files matched your search

+9 -3
View File
@@ -25,9 +25,15 @@ type Item = {
/**
* Поиск в топбаре: подсказки по мере ввода, Enter — страница поиска или выбранный элемент.
* Без фокуса и текста свёрнут в кнопку с лупой; поле раскрывается влево с анимацией.
* Без фокуса и текста свёрнут в кнопку с лупой (если collapsible); поле раскрывается с анимацией.
*/
export function SearchBox({ align = 'center' }: { align?: 'left' | 'center' | 'right' }) {
export function SearchBox({
align = 'center',
collapsible = true,
}: {
align?: 'left' | 'center' | 'right';
collapsible?: boolean;
}) {
const { t } = useTranslation();
const session = useSession();
const navigate = useNavigate();
@@ -40,7 +46,7 @@ export function SearchBox({ align = 'center' }: { align?: 'left' | 'center' | 'r
const [focused, setFocused] = useState(false);
const blurTimer = useRef<ReturnType<typeof setTimeout>>(undefined);
// Свёрнут в круглую кнопку, пока не нужен: раскрывается по клику, «/» или Ctrl+K.
const expanded = focused || q !== '';
const expanded = !collapsible || focused || q !== '';
useEffect(() => {
const id = setTimeout(() => setDebounced(q.trim()), DEBOUNCE_MS);