diff --git a/src/renderer/src/i18n/dict.ts b/src/renderer/src/i18n/dict.ts index b36973b..090a059 100644 --- a/src/renderer/src/i18n/dict.ts +++ b/src/renderer/src/i18n/dict.ts @@ -100,6 +100,7 @@ export const ru: Dict = { 'meals.kicker': 'Режим питания', 'meals.title': 'Питание', 'meals.presets': 'Быстрое добавление', + 'meals.schedule': 'Расписание', 'meals.section.active': 'Активные · {n}', 'meals.section.disabled': 'Выключенные · {n}', 'meals.empty': 'Пока нет приёмов пищи — добавь первый или выбери пресет', @@ -460,6 +461,7 @@ export const en: Dict = { 'meals.kicker': 'Eating schedule', 'meals.title': 'Meals', 'meals.presets': 'Quick add', + 'meals.schedule': 'Schedule', 'meals.section.active': 'Active · {n}', 'meals.section.disabled': 'Disabled · {n}', 'meals.empty': 'No meals yet — add one or pick a preset', diff --git a/src/renderer/src/pages/Meals.tsx b/src/renderer/src/pages/Meals.tsx index 72c635d..68eb937 100644 --- a/src/renderer/src/pages/Meals.tsx +++ b/src/renderer/src/pages/Meals.tsx @@ -1,5 +1,6 @@ import { useState } from 'react' import { Plus, ChevronRight, UtensilsCrossed } from 'lucide-react' +import { AnimatePresence, motion } from 'framer-motion' import { useAppStore } from '../store/appStore' import { MealEditor, type MealDraft } from '../components/MealEditor' import { Button } from '../components/ui/Button' @@ -27,8 +28,15 @@ export default function Meals(): JSX.Element { const [editing, setEditing] = useState(null) const { t } = useT() - const enabled = meals.filter((m) => m.enabled) - const disabled = meals.filter((m) => !m.enabled) + // Единый список (включённые сверху). Важно: НЕ разбиваем на два , иначе + // при переключении строка переезжает между списками → её Switch + // размонтируется/монтируется заново, и анимация ползунка есть только при + // включении (mount с x:0→20), а при выключении нет. В одном keyed-списке + // компонент остаётся смонтированным → ползунок плавно ездит в обе стороны, + // а строка «переезжает» в свою группу через layout-анимацию. + const ordered = [...meals].sort((a, b) => + a.enabled === b.enabled ? 0 : a.enabled ? -1 : 1 + ) async function addPreset( preset: (typeof MEAL_PRESETS)[number] @@ -82,46 +90,32 @@ export default function Meals(): JSX.Element { ))} - {enabled.length > 0 && ( + {meals.length > 0 && ( <> - - - {enabled.map((m, i) => ( - { - setEditing(m) - setEditorOpen(true) - }} - /> - ))} - - - )} - - {disabled.length > 0 && ( - <> - + - {disabled.map((m, i) => ( - { - setEditing(m) - setEditorOpen(true) - }} - /> - ))} + + {ordered.map((m, i) => ( + + { + setEditing(m) + setEditorOpen(true) + }} + /> + + ))} + )} @@ -169,7 +163,7 @@ function MealRow({