@burdenoff/microfe-mybodyshield 2026.705.1 → 2026.706.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_virtual/__vite-optional-peer-dep_@emotion/is-prop-valid_framer-motion.js +10 -0
- package/dist/_virtual/__vite-optional-peer-dep_@emotion/is-prop-valid_framer-motion.js.map +1 -0
- package/dist/_virtual/_rolldown/runtime.js +5 -5
- package/dist/mybodyshield/components/DataTable.js +8 -4
- package/dist/mybodyshield/components/DataTable.js.map +1 -1
- package/dist/mybodyshield/components/EvidenceUpload.js +92 -4
- package/dist/mybodyshield/components/EvidenceUpload.js.map +1 -0
- package/dist/mybodyshield/components/FileLink.js +35 -2
- package/dist/mybodyshield/components/FileLink.js.map +1 -0
- package/dist/mybodyshield/components/MybDiscussion.js +107 -6
- package/dist/mybodyshield/components/MybDiscussion.js.map +1 -0
- package/dist/mybodyshield/components/MybTags.js +148 -4
- package/dist/mybodyshield/components/MybTags.js.map +1 -0
- package/dist/mybodyshield/components/Pagination.js.map +1 -1
- package/dist/mybodyshield/components/UserSearchSelect.js +148 -0
- package/dist/mybodyshield/components/UserSearchSelect.js.map +1 -0
- package/dist/mybodyshield/components/index.js +1 -0
- package/dist/mybodyshield/hooks/index.js +1 -0
- package/dist/mybodyshield/hooks/useMyBodyShieldApi.js +47 -27
- package/dist/mybodyshield/hooks/useMyBodyShieldApi.js.map +1 -1
- package/dist/mybodyshield/hooks/useMybComments.js +44 -2
- package/dist/mybodyshield/hooks/useMybComments.js.map +1 -0
- package/dist/mybodyshield/hooks/useMybFiles.js +80 -3
- package/dist/mybodyshield/hooks/useMybFiles.js.map +1 -0
- package/dist/mybodyshield/hooks/useMybTags.js +88 -2
- package/dist/mybodyshield/hooks/useMybTags.js.map +1 -0
- package/dist/mybodyshield/hooks/useMybUsers.js +36 -0
- package/dist/mybodyshield/hooks/useMybUsers.js.map +1 -0
- package/dist/mybodyshield/pages/DashboardPage.js +444 -340
- package/dist/mybodyshield/pages/DashboardPage.js.map +1 -1
- package/dist/mybodyshield/pages/_shared/visuals.js +29 -23
- package/dist/mybodyshield/pages/_shared/visuals.js.map +1 -1
- package/dist/mybodyshield/pages/coaching/CoachingPage.js +272 -179
- package/dist/mybodyshield/pages/coaching/CoachingPage.js.map +1 -1
- package/dist/mybodyshield/pages/goals/GoalsPage.js +304 -257
- package/dist/mybodyshield/pages/goals/GoalsPage.js.map +1 -1
- package/dist/mybodyshield/pages/nutrition/NutritionPage.js +745 -504
- package/dist/mybodyshield/pages/nutrition/NutritionPage.js.map +1 -1
- package/dist/mybodyshield/pages/programs/ProgramDetailPage.js +688 -320
- package/dist/mybodyshield/pages/programs/ProgramDetailPage.js.map +1 -1
- package/dist/mybodyshield/pages/programs/ProgramsPage.js +282 -234
- package/dist/mybodyshield/pages/programs/ProgramsPage.js.map +1 -1
- package/dist/mybodyshield/pages/progress/ProgressPage.js +447 -299
- package/dist/mybodyshield/pages/progress/ProgressPage.js.map +1 -1
- package/dist/mybodyshield/pages/recovery/RecoveryPage.js +335 -246
- package/dist/mybodyshield/pages/recovery/RecoveryPage.js.map +1 -1
- package/dist/mybodyshield/pages/train/SessionDetailPage.js +380 -267
- package/dist/mybodyshield/pages/train/SessionDetailPage.js.map +1 -1
- package/dist/mybodyshield/pages/train/SessionsPage.js +111 -78
- package/dist/mybodyshield/pages/train/SessionsPage.js.map +1 -1
- package/dist/node_modules/framer-motion/dist/es/components/AnimatePresence/PopChild.js +63 -0
- package/dist/node_modules/framer-motion/dist/es/components/AnimatePresence/PopChild.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/components/AnimatePresence/PresenceChild.js +55 -0
- package/dist/node_modules/framer-motion/dist/es/components/AnimatePresence/PresenceChild.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/components/AnimatePresence/index.js +62 -0
- package/dist/node_modules/framer-motion/dist/es/components/AnimatePresence/index.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/components/AnimatePresence/use-presence.js +22 -0
- package/dist/node_modules/framer-motion/dist/es/components/AnimatePresence/use-presence.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/components/AnimatePresence/utils.js +13 -0
- package/dist/node_modules/framer-motion/dist/es/components/AnimatePresence/utils.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/context/LayoutGroupContext.js +8 -0
- package/dist/node_modules/framer-motion/dist/es/context/LayoutGroupContext.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/context/LazyContext.js +8 -0
- package/dist/node_modules/framer-motion/dist/es/context/LazyContext.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/context/MotionConfigContext.js +12 -0
- package/dist/node_modules/framer-motion/dist/es/context/MotionConfigContext.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/context/MotionContext/create.js +19 -0
- package/dist/node_modules/framer-motion/dist/es/context/MotionContext/create.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/context/MotionContext/index.js +8 -0
- package/dist/node_modules/framer-motion/dist/es/context/MotionContext/index.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/context/MotionContext/utils.js +17 -0
- package/dist/node_modules/framer-motion/dist/es/context/MotionContext/utils.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/context/PresenceContext.js +8 -0
- package/dist/node_modules/framer-motion/dist/es/context/PresenceContext.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/context/SwitchLayoutGroupContext.js +8 -0
- package/dist/node_modules/framer-motion/dist/es/context/SwitchLayoutGroupContext.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/events/add-pointer-event.js +10 -0
- package/dist/node_modules/framer-motion/dist/es/events/add-pointer-event.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/events/event-info.js +13 -0
- package/dist/node_modules/framer-motion/dist/es/events/event-info.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/gestures/drag/VisualElementDragControls.js +260 -0
- package/dist/node_modules/framer-motion/dist/es/gestures/drag/VisualElementDragControls.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/gestures/drag/index.js +24 -0
- package/dist/node_modules/framer-motion/dist/es/gestures/drag/index.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/gestures/drag/utils/constraints.js +61 -0
- package/dist/node_modules/framer-motion/dist/es/gestures/drag/utils/constraints.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/gestures/focus.js +29 -0
- package/dist/node_modules/framer-motion/dist/es/gestures/focus.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/gestures/hover.js +22 -0
- package/dist/node_modules/framer-motion/dist/es/gestures/hover.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/gestures/pan/PanSession.js +140 -0
- package/dist/node_modules/framer-motion/dist/es/gestures/pan/PanSession.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/gestures/pan/index.js +44 -0
- package/dist/node_modules/framer-motion/dist/es/gestures/pan/index.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/gestures/press.js +28 -0
- package/dist/node_modules/framer-motion/dist/es/gestures/press.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/motion/features/animation/exit.js +41 -0
- package/dist/node_modules/framer-motion/dist/es/motion/features/animation/exit.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/motion/features/animation/index.js +27 -0
- package/dist/node_modules/framer-motion/dist/es/motion/features/animation/index.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/motion/features/animations.js +11 -0
- package/dist/node_modules/framer-motion/dist/es/motion/features/animations.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/motion/features/definitions.js +53 -0
- package/dist/node_modules/framer-motion/dist/es/motion/features/definitions.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/motion/features/drag.js +17 -0
- package/dist/node_modules/framer-motion/dist/es/motion/features/drag.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/motion/features/gestures.js +15 -0
- package/dist/node_modules/framer-motion/dist/es/motion/features/gestures.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/motion/features/layout/MeasureLayout.js +63 -0
- package/dist/node_modules/framer-motion/dist/es/motion/features/layout/MeasureLayout.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/motion/features/layout.js +11 -0
- package/dist/node_modules/framer-motion/dist/es/motion/features/layout.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/motion/features/load-features.js +15 -0
- package/dist/node_modules/framer-motion/dist/es/motion/features/load-features.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/motion/features/viewport/index.js +48 -0
- package/dist/node_modules/framer-motion/dist/es/motion/features/viewport/index.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/motion/features/viewport/observers.js +26 -0
- package/dist/node_modules/framer-motion/dist/es/motion/features/viewport/observers.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/motion/index.js +72 -0
- package/dist/node_modules/framer-motion/dist/es/motion/index.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/motion/utils/symbol.js +6 -0
- package/dist/node_modules/framer-motion/dist/es/motion/utils/symbol.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/motion/utils/use-motion-ref.js +23 -0
- package/dist/node_modules/framer-motion/dist/es/motion/utils/use-motion-ref.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/motion/utils/use-visual-element.js +60 -0
- package/dist/node_modules/framer-motion/dist/es/motion/utils/use-visual-element.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/motion/utils/use-visual-state.js +52 -0
- package/dist/node_modules/framer-motion/dist/es/motion/utils/use-visual-state.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/motion/utils/valid-prop.js +9 -0
- package/dist/node_modules/framer-motion/dist/es/motion/utils/valid-prop.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/render/components/create-proxy.js +12 -0
- package/dist/node_modules/framer-motion/dist/es/render/components/create-proxy.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/render/components/motion/feature-bundle.js +15 -0
- package/dist/node_modules/framer-motion/dist/es/render/components/motion/feature-bundle.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/render/components/motion/proxy.js +9 -0
- package/dist/node_modules/framer-motion/dist/es/render/components/motion/proxy.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/render/dom/create-visual-element.js +10 -0
- package/dist/node_modules/framer-motion/dist/es/render/dom/create-visual-element.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/render/dom/use-render.js +23 -0
- package/dist/node_modules/framer-motion/dist/es/render/dom/use-render.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/render/dom/utils/filter-props.js +21 -0
- package/dist/node_modules/framer-motion/dist/es/render/dom/utils/filter-props.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/render/dom/utils/is-svg-component.js +9 -0
- package/dist/node_modules/framer-motion/dist/es/render/dom/utils/is-svg-component.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/render/html/use-html-visual-state.js +13 -0
- package/dist/node_modules/framer-motion/dist/es/render/html/use-html-visual-state.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/render/html/use-props.js +28 -0
- package/dist/node_modules/framer-motion/dist/es/render/html/use-props.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/render/html/utils/create-render-state.js +11 -0
- package/dist/node_modules/framer-motion/dist/es/render/html/utils/create-render-state.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/render/svg/lowercase-elements.js +32 -0
- package/dist/node_modules/framer-motion/dist/es/render/svg/lowercase-elements.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/render/svg/use-props.js +28 -0
- package/dist/node_modules/framer-motion/dist/es/render/svg/use-props.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/render/svg/use-svg-visual-state.js +13 -0
- package/dist/node_modules/framer-motion/dist/es/render/svg/use-svg-visual-state.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/render/svg/utils/create-render-state.js +10 -0
- package/dist/node_modules/framer-motion/dist/es/render/svg/utils/create-render-state.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/utils/distance.js +10 -0
- package/dist/node_modules/framer-motion/dist/es/utils/distance.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/utils/get-context-window.js +6 -0
- package/dist/node_modules/framer-motion/dist/es/utils/get-context-window.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/utils/is-browser.js +6 -0
- package/dist/node_modules/framer-motion/dist/es/utils/is-browser.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/utils/is-ref-object.js +8 -0
- package/dist/node_modules/framer-motion/dist/es/utils/is-ref-object.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/utils/reduced-motion/use-reduced-motion.js +15 -0
- package/dist/node_modules/framer-motion/dist/es/utils/reduced-motion/use-reduced-motion.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/utils/use-composed-ref.js +27 -0
- package/dist/node_modules/framer-motion/dist/es/utils/use-composed-ref.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/utils/use-constant.js +11 -0
- package/dist/node_modules/framer-motion/dist/es/utils/use-constant.js.map +1 -0
- package/dist/node_modules/framer-motion/dist/es/utils/use-isomorphic-effect.js +9 -0
- package/dist/node_modules/framer-motion/dist/es/utils/use-isomorphic-effect.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/AsyncMotionValueAnimation.js +109 -0
- package/dist/node_modules/motion-dom/dist/es/animation/AsyncMotionValueAnimation.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/JSAnimation.js +131 -0
- package/dist/node_modules/motion-dom/dist/es/animation/JSAnimation.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/NativeAnimation.js +86 -0
- package/dist/node_modules/motion-dom/dist/es/animation/NativeAnimation.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/NativeAnimationExtended.js +30 -0
- package/dist/node_modules/motion-dom/dist/es/animation/NativeAnimationExtended.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/animate/single-value.js +12 -0
- package/dist/node_modules/motion-dom/dist/es/animation/animate/single-value.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/drivers/frame.js +15 -0
- package/dist/node_modules/motion-dom/dist/es/animation/drivers/frame.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/generators/inertia.js +34 -0
- package/dist/node_modules/motion-dom/dist/es/animation/generators/inertia.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/generators/keyframes.js +24 -0
- package/dist/node_modules/motion-dom/dist/es/animation/generators/keyframes.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/generators/spring.js +168 -0
- package/dist/node_modules/motion-dom/dist/es/animation/generators/spring.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/generators/utils/calc-duration.js +11 -0
- package/dist/node_modules/motion-dom/dist/es/animation/generators/utils/calc-duration.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/generators/utils/create-generator-easing.js +18 -0
- package/dist/node_modules/motion-dom/dist/es/animation/generators/utils/create-generator-easing.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/generators/utils/is-generator.js +8 -0
- package/dist/node_modules/motion-dom/dist/es/animation/generators/utils/is-generator.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/generators/utils/velocity.js +11 -0
- package/dist/node_modules/motion-dom/dist/es/animation/generators/utils/velocity.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/interfaces/motion-value.js +47 -0
- package/dist/node_modules/motion-dom/dist/es/animation/interfaces/motion-value.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/interfaces/visual-element-target.js +59 -0
- package/dist/node_modules/motion-dom/dist/es/animation/interfaces/visual-element-target.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/interfaces/visual-element-variant.js +28 -0
- package/dist/node_modules/motion-dom/dist/es/animation/interfaces/visual-element-variant.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/interfaces/visual-element.js +23 -0
- package/dist/node_modules/motion-dom/dist/es/animation/interfaces/visual-element.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/keyframes/DOMKeyframesResolver.js +63 -0
- package/dist/node_modules/motion-dom/dist/es/animation/keyframes/DOMKeyframesResolver.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/keyframes/KeyframesResolver.js +69 -0
- package/dist/node_modules/motion-dom/dist/es/animation/keyframes/KeyframesResolver.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/keyframes/get-final.js +10 -0
- package/dist/node_modules/motion-dom/dist/es/animation/keyframes/get-final.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/keyframes/offsets/default.js +10 -0
- package/dist/node_modules/motion-dom/dist/es/animation/keyframes/offsets/default.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/keyframes/offsets/fill.js +14 -0
- package/dist/node_modules/motion-dom/dist/es/animation/keyframes/offsets/fill.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/keyframes/offsets/time.js +8 -0
- package/dist/node_modules/motion-dom/dist/es/animation/keyframes/offsets/time.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/keyframes/utils/fill-wildcards.js +8 -0
- package/dist/node_modules/motion-dom/dist/es/animation/keyframes/utils/fill-wildcards.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/keyframes/utils/is-none.js +9 -0
- package/dist/node_modules/motion-dom/dist/es/animation/keyframes/utils/is-none.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/keyframes/utils/make-none-animatable.js +20 -0
- package/dist/node_modules/motion-dom/dist/es/animation/keyframes/utils/make-none-animatable.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/keyframes/utils/unit-conversion.js +38 -0
- package/dist/node_modules/motion-dom/dist/es/animation/keyframes/utils/unit-conversion.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/optimized-appear/data-id.js +6 -0
- package/dist/node_modules/motion-dom/dist/es/animation/optimized-appear/data-id.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/optimized-appear/get-appear-id.js +9 -0
- package/dist/node_modules/motion-dom/dist/es/animation/optimized-appear/get-appear-id.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/utils/WithPromise.js +24 -0
- package/dist/node_modules/motion-dom/dist/es/animation/utils/WithPromise.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/utils/calc-child-stagger.js +9 -0
- package/dist/node_modules/motion-dom/dist/es/animation/utils/calc-child-stagger.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/utils/can-animate.js +20 -0
- package/dist/node_modules/motion-dom/dist/es/animation/utils/can-animate.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/utils/css-variables-conversion.js +27 -0
- package/dist/node_modules/motion-dom/dist/es/animation/utils/css-variables-conversion.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/utils/default-transitions.js +29 -0
- package/dist/node_modules/motion-dom/dist/es/animation/utils/default-transitions.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/utils/get-value-transition.js +10 -0
- package/dist/node_modules/motion-dom/dist/es/animation/utils/get-value-transition.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/utils/is-animatable.js +7 -0
- package/dist/node_modules/motion-dom/dist/es/animation/utils/is-animatable.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/utils/is-css-variable.js +9 -0
- package/dist/node_modules/motion-dom/dist/es/animation/utils/is-css-variable.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/utils/is-transition-defined.js +21 -0
- package/dist/node_modules/motion-dom/dist/es/animation/utils/is-transition-defined.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/utils/make-animation-instant.js +8 -0
- package/dist/node_modules/motion-dom/dist/es/animation/utils/make-animation-instant.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/utils/replace-transition-type.js +18 -0
- package/dist/node_modules/motion-dom/dist/es/animation/utils/replace-transition-type.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/utils/resolve-transition.js +15 -0
- package/dist/node_modules/motion-dom/dist/es/animation/utils/resolve-transition.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/waapi/easing/cubic-bezier.js +6 -0
- package/dist/node_modules/motion-dom/dist/es/animation/waapi/easing/cubic-bezier.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/waapi/easing/map-easing.js +13 -0
- package/dist/node_modules/motion-dom/dist/es/animation/waapi/easing/map-easing.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/waapi/easing/supported.js +37 -0
- package/dist/node_modules/motion-dom/dist/es/animation/waapi/easing/supported.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/waapi/start-waapi-animation.js +21 -0
- package/dist/node_modules/motion-dom/dist/es/animation/waapi/start-waapi-animation.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/waapi/supports/waapi.js +26 -0
- package/dist/node_modules/motion-dom/dist/es/animation/waapi/supports/waapi.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/waapi/utils/accelerated-values.js +11 -0
- package/dist/node_modules/motion-dom/dist/es/animation/waapi/utils/accelerated-values.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/waapi/utils/apply-generator.js +10 -0
- package/dist/node_modules/motion-dom/dist/es/animation/waapi/utils/apply-generator.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/waapi/utils/is-browser-color.js +10 -0
- package/dist/node_modules/motion-dom/dist/es/animation/waapi/utils/is-browser-color.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/waapi/utils/linear.js +10 -0
- package/dist/node_modules/motion-dom/dist/es/animation/waapi/utils/linear.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/animation/waapi/utils/unsupported-easing.js +19 -0
- package/dist/node_modules/motion-dom/dist/es/animation/waapi/utils/unsupported-easing.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/events/add-dom-event.js +8 -0
- package/dist/node_modules/motion-dom/dist/es/events/add-dom-event.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/frameloop/batcher.js +32 -0
- package/dist/node_modules/motion-dom/dist/es/frameloop/batcher.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/frameloop/frame.js +8 -0
- package/dist/node_modules/motion-dom/dist/es/frameloop/frame.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/frameloop/microtask.js +7 -0
- package/dist/node_modules/motion-dom/dist/es/frameloop/microtask.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/frameloop/order.js +15 -0
- package/dist/node_modules/motion-dom/dist/es/frameloop/order.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/frameloop/render-step.js +34 -0
- package/dist/node_modules/motion-dom/dist/es/frameloop/render-step.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/frameloop/sync-time.js +17 -0
- package/dist/node_modules/motion-dom/dist/es/frameloop/sync-time.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/gestures/drag/state/is-active.js +12 -0
- package/dist/node_modules/motion-dom/dist/es/gestures/drag/state/is-active.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/gestures/drag/state/set-active.js +13 -0
- package/dist/node_modules/motion-dom/dist/es/gestures/drag/state/set-active.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/gestures/hover.js +38 -0
- package/dist/node_modules/motion-dom/dist/es/gestures/hover.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/gestures/press/index.js +38 -0
- package/dist/node_modules/motion-dom/dist/es/gestures/press/index.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/gestures/press/utils/is-keyboard-accessible.js +23 -0
- package/dist/node_modules/motion-dom/dist/es/gestures/press/utils/is-keyboard-accessible.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/gestures/press/utils/keyboard.js +30 -0
- package/dist/node_modules/motion-dom/dist/es/gestures/press/utils/keyboard.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/gestures/press/utils/state.js +6 -0
- package/dist/node_modules/motion-dom/dist/es/gestures/press/utils/state.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/gestures/utils/is-node-or-child.js +6 -0
- package/dist/node_modules/motion-dom/dist/es/gestures/utils/is-node-or-child.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/gestures/utils/is-primary-pointer.js +6 -0
- package/dist/node_modules/motion-dom/dist/es/gestures/utils/is-primary-pointer.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/gestures/utils/setup.js +18 -0
- package/dist/node_modules/motion-dom/dist/es/gestures/utils/setup.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/projection/animation/mix-values.js +27 -0
- package/dist/node_modules/motion-dom/dist/es/projection/animation/mix-values.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/projection/geometry/conversion.js +41 -0
- package/dist/node_modules/motion-dom/dist/es/projection/geometry/conversion.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/projection/geometry/copy.js +14 -0
- package/dist/node_modules/motion-dom/dist/es/projection/geometry/copy.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/projection/geometry/delta-apply.js +45 -0
- package/dist/node_modules/motion-dom/dist/es/projection/geometry/delta-apply.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/projection/geometry/delta-calc.js +32 -0
- package/dist/node_modules/motion-dom/dist/es/projection/geometry/delta-calc.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/projection/geometry/delta-remove.js +31 -0
- package/dist/node_modules/motion-dom/dist/es/projection/geometry/delta-remove.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/projection/geometry/models.js +20 -0
- package/dist/node_modules/motion-dom/dist/es/projection/geometry/models.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/projection/geometry/utils.js +30 -0
- package/dist/node_modules/motion-dom/dist/es/projection/geometry/utils.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/projection/node/DocumentProjectionNode.js +15 -0
- package/dist/node_modules/motion-dom/dist/es/projection/node/DocumentProjectionNode.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/projection/node/HTMLProjectionNode.js +24 -0
- package/dist/node_modules/motion-dom/dist/es/projection/node/HTMLProjectionNode.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/projection/node/create-projection-node.js +586 -0
- package/dist/node_modules/motion-dom/dist/es/projection/node/create-projection-node.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/projection/node/state.js +9 -0
- package/dist/node_modules/motion-dom/dist/es/projection/node/state.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/projection/shared/stack.js +53 -0
- package/dist/node_modules/motion-dom/dist/es/projection/shared/stack.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/projection/styles/scale-border-radius.js +15 -0
- package/dist/node_modules/motion-dom/dist/es/projection/styles/scale-border-radius.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/projection/styles/scale-box-shadow.js +15 -0
- package/dist/node_modules/motion-dom/dist/es/projection/styles/scale-box-shadow.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/projection/styles/scale-correction.js +19 -0
- package/dist/node_modules/motion-dom/dist/es/projection/styles/scale-correction.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/projection/styles/transform.js +14 -0
- package/dist/node_modules/motion-dom/dist/es/projection/styles/transform.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/projection/utils/compare-by-depth.js +6 -0
- package/dist/node_modules/motion-dom/dist/es/projection/utils/compare-by-depth.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/projection/utils/each-axis.js +8 -0
- package/dist/node_modules/motion-dom/dist/es/projection/utils/each-axis.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/projection/utils/flat-tree.js +21 -0
- package/dist/node_modules/motion-dom/dist/es/projection/utils/flat-tree.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/projection/utils/has-transform.js +20 -0
- package/dist/node_modules/motion-dom/dist/es/projection/utils/has-transform.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/projection/utils/measure.js +14 -0
- package/dist/node_modules/motion-dom/dist/es/projection/utils/measure.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/Feature.js +11 -0
- package/dist/node_modules/motion-dom/dist/es/render/Feature.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/VisualElement.js +206 -0
- package/dist/node_modules/motion-dom/dist/es/render/VisualElement.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/dom/DOMVisualElement.js +30 -0
- package/dist/node_modules/motion-dom/dist/es/render/dom/DOMVisualElement.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/dom/is-css-var.js +6 -0
- package/dist/node_modules/motion-dom/dist/es/render/dom/is-css-var.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/dom/parse-transform.js +58 -0
- package/dist/node_modules/motion-dom/dist/es/render/dom/parse-transform.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/dom/style-set.js +9 -0
- package/dist/node_modules/motion-dom/dist/es/render/dom/style-set.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/dom/utils/camel-to-dash.js +8 -0
- package/dist/node_modules/motion-dom/dist/es/render/dom/utils/camel-to-dash.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/html/HTMLVisualElement.js +37 -0
- package/dist/node_modules/motion-dom/dist/es/render/html/HTMLVisualElement.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/html/utils/build-styles.js +30 -0
- package/dist/node_modules/motion-dom/dist/es/render/html/utils/build-styles.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/html/utils/build-transform.js +38 -0
- package/dist/node_modules/motion-dom/dist/es/render/html/utils/build-transform.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/html/utils/render.js +10 -0
- package/dist/node_modules/motion-dom/dist/es/render/html/utils/render.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/html/utils/scrape-motion-values.js +13 -0
- package/dist/node_modules/motion-dom/dist/es/render/html/utils/scrape-motion-values.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/store.js +6 -0
- package/dist/node_modules/motion-dom/dist/es/render/store.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/svg/SVGVisualElement.js +42 -0
- package/dist/node_modules/motion-dom/dist/es/render/svg/SVGVisualElement.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/svg/utils/build-attrs.js +24 -0
- package/dist/node_modules/motion-dom/dist/es/render/svg/utils/build-attrs.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/svg/utils/camel-case-attrs.js +30 -0
- package/dist/node_modules/motion-dom/dist/es/render/svg/utils/camel-case-attrs.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/svg/utils/is-svg-tag.js +6 -0
- package/dist/node_modules/motion-dom/dist/es/render/svg/utils/is-svg-tag.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/svg/utils/path.js +17 -0
- package/dist/node_modules/motion-dom/dist/es/render/svg/utils/path.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/svg/utils/render.js +12 -0
- package/dist/node_modules/motion-dom/dist/es/render/svg/utils/render.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/svg/utils/scrape-motion-values.js +16 -0
- package/dist/node_modules/motion-dom/dist/es/render/svg/utils/scrape-motion-values.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/animation-state.js +137 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/animation-state.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/get-variant-context.js +21 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/get-variant-context.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/is-animation-controls.js +8 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/is-animation-controls.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/is-controlling-variants.js +14 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/is-controlling-variants.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/is-forced-motion-value.js +10 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/is-forced-motion-value.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/is-keyframes-target.js +6 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/is-keyframes-target.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/is-variant-label.js +8 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/is-variant-label.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/keys-position.js +15 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/keys-position.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/keys-transform.js +24 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/keys-transform.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/motion-values.js +23 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/motion-values.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/reduced-motion/index.js +13 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/reduced-motion/index.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/reduced-motion/state.js +6 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/reduced-motion/state.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/resolve-dynamic-variants.js +10 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/resolve-dynamic-variants.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/resolve-variants.js +22 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/resolve-variants.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/setters.js +22 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/setters.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/shallow-compare.js +12 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/shallow-compare.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/variant-props.js +14 -0
- package/dist/node_modules/motion-dom/dist/es/render/utils/variant-props.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/resize/handle-element.js +39 -0
- package/dist/node_modules/motion-dom/dist/es/resize/handle-element.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/resize/handle-window.js +24 -0
- package/dist/node_modules/motion-dom/dist/es/resize/handle-window.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/resize/index.js +10 -0
- package/dist/node_modules/motion-dom/dist/es/resize/index.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/stats/buffer.js +9 -0
- package/dist/node_modules/motion-dom/dist/es/stats/buffer.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/utils/border-radius.js +11 -0
- package/dist/node_modules/motion-dom/dist/es/utils/border-radius.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/utils/delay.js +14 -0
- package/dist/node_modules/motion-dom/dist/es/utils/delay.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/utils/interpolate.js +35 -0
- package/dist/node_modules/motion-dom/dist/es/utils/interpolate.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/utils/is-html-element.js +9 -0
- package/dist/node_modules/motion-dom/dist/es/utils/is-html-element.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/utils/is-svg-element.js +9 -0
- package/dist/node_modules/motion-dom/dist/es/utils/is-svg-element.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/utils/is-svg-svg-element.js +9 -0
- package/dist/node_modules/motion-dom/dist/es/utils/is-svg-svg-element.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/utils/mix/color.js +32 -0
- package/dist/node_modules/motion-dom/dist/es/utils/mix/color.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/utils/mix/complex.js +54 -0
- package/dist/node_modules/motion-dom/dist/es/utils/mix/complex.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/utils/mix/immediate.js +8 -0
- package/dist/node_modules/motion-dom/dist/es/utils/mix/immediate.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/utils/mix/index.js +10 -0
- package/dist/node_modules/motion-dom/dist/es/utils/mix/index.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/utils/mix/number.js +6 -0
- package/dist/node_modules/motion-dom/dist/es/utils/mix/number.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/utils/mix/visibility.js +9 -0
- package/dist/node_modules/motion-dom/dist/es/utils/mix/visibility.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/utils/resolve-elements.js +16 -0
- package/dist/node_modules/motion-dom/dist/es/utils/resolve-elements.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/utils/supports/flags.js +6 -0
- package/dist/node_modules/motion-dom/dist/es/utils/supports/flags.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/utils/supports/linear-easing.js +14 -0
- package/dist/node_modules/motion-dom/dist/es/utils/supports/linear-easing.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/utils/supports/memo.js +11 -0
- package/dist/node_modules/motion-dom/dist/es/utils/supports/memo.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/utils/supports/scroll-timeline.js +7 -0
- package/dist/node_modules/motion-dom/dist/es/utils/supports/scroll-timeline.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/index.js +94 -0
- package/dist/node_modules/motion-dom/dist/es/value/index.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/auto.js +9 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/auto.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/color/hex.js +21 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/color/hex.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/color/hsla-to-rgba.js +23 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/color/hsla-to-rgba.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/color/hsla.js +14 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/color/hsla.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/color/index.js +17 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/color/index.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/color/rgba.js +17 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/color/rgba.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/color/utils.js +18 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/color/utils.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/complex/filter.js +28 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/complex/filter.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/complex/index.js +54 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/complex/index.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/complex/mask.js +16 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/complex/mask.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/dimensions.js +18 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/dimensions.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/int.js +10 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/int.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/maps/defaults.js +26 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/maps/defaults.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/maps/number.js +66 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/maps/number.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/maps/transform.js +34 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/maps/transform.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/numbers/index.js +17 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/numbers/index.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/numbers/units.js +14 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/numbers/units.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/test.js +6 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/test.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/utils/animatable-none.js +14 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/utils/animatable-none.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/utils/color-regex.js +6 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/utils/color-regex.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/utils/find.js +14 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/utils/find.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/utils/float-regex.js +6 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/utils/float-regex.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/utils/get-as-type.js +6 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/utils/get-as-type.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/utils/is-nullish.js +8 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/utils/is-nullish.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/utils/sanitize.js +6 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/utils/sanitize.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/utils/single-color-regex.js +6 -0
- package/dist/node_modules/motion-dom/dist/es/value/types/utils/single-color-regex.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/utils/is-motion-value.js +6 -0
- package/dist/node_modules/motion-dom/dist/es/value/utils/is-motion-value.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/utils/resolve-motion-value.js +9 -0
- package/dist/node_modules/motion-dom/dist/es/value/utils/resolve-motion-value.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/will-change/add-will-change.js +15 -0
- package/dist/node_modules/motion-dom/dist/es/value/will-change/add-will-change.js.map +1 -0
- package/dist/node_modules/motion-dom/dist/es/value/will-change/is.js +9 -0
- package/dist/node_modules/motion-dom/dist/es/value/will-change/is.js.map +1 -0
- package/dist/node_modules/motion-utils/dist/es/array.js +12 -0
- package/dist/node_modules/motion-utils/dist/es/array.js.map +1 -0
- package/dist/node_modules/motion-utils/dist/es/clamp.js +6 -0
- package/dist/node_modules/motion-utils/dist/es/clamp.js.map +1 -0
- package/dist/node_modules/motion-utils/dist/es/easing/anticipate.js +7 -0
- package/dist/node_modules/motion-utils/dist/es/easing/anticipate.js.map +1 -0
- package/dist/node_modules/motion-utils/dist/es/easing/back.js +9 -0
- package/dist/node_modules/motion-utils/dist/es/easing/back.js.map +1 -0
- package/dist/node_modules/motion-utils/dist/es/easing/circ.js +8 -0
- package/dist/node_modules/motion-utils/dist/es/easing/circ.js.map +1 -0
- package/dist/node_modules/motion-utils/dist/es/easing/cubic-bezier.js +20 -0
- package/dist/node_modules/motion-utils/dist/es/easing/cubic-bezier.js.map +1 -0
- package/dist/node_modules/motion-utils/dist/es/easing/ease.js +7 -0
- package/dist/node_modules/motion-utils/dist/es/easing/ease.js.map +1 -0
- package/dist/node_modules/motion-utils/dist/es/easing/modifiers/mirror.js +6 -0
- package/dist/node_modules/motion-utils/dist/es/easing/modifiers/mirror.js.map +1 -0
- package/dist/node_modules/motion-utils/dist/es/easing/modifiers/reverse.js +6 -0
- package/dist/node_modules/motion-utils/dist/es/easing/modifiers/reverse.js.map +1 -0
- package/dist/node_modules/motion-utils/dist/es/easing/utils/is-bezier-definition.js +6 -0
- package/dist/node_modules/motion-utils/dist/es/easing/utils/is-bezier-definition.js.map +1 -0
- package/dist/node_modules/motion-utils/dist/es/easing/utils/is-easing-array.js +6 -0
- package/dist/node_modules/motion-utils/dist/es/easing/utils/is-easing-array.js.map +1 -0
- package/dist/node_modules/motion-utils/dist/es/easing/utils/map.js +33 -0
- package/dist/node_modules/motion-utils/dist/es/easing/utils/map.js.map +1 -0
- package/dist/node_modules/motion-utils/dist/es/errors.js +12 -0
- package/dist/node_modules/motion-utils/dist/es/errors.js.map +1 -0
- package/dist/node_modules/motion-utils/dist/es/format-error-message.js +8 -0
- package/dist/node_modules/motion-utils/dist/es/format-error-message.js.map +1 -0
- package/dist/node_modules/motion-utils/dist/es/global-config.js +6 -0
- package/dist/node_modules/motion-utils/dist/es/global-config.js.map +1 -0
- package/dist/node_modules/motion-utils/dist/es/is-numerical-string.js +6 -0
- package/dist/node_modules/motion-utils/dist/es/is-numerical-string.js.map +1 -0
- package/dist/node_modules/motion-utils/dist/es/is-object.js +6 -0
- package/dist/node_modules/motion-utils/dist/es/is-object.js.map +1 -0
- package/dist/node_modules/motion-utils/dist/es/is-zero-value-string.js +6 -0
- package/dist/node_modules/motion-utils/dist/es/is-zero-value-string.js.map +1 -0
- package/dist/node_modules/motion-utils/dist/es/memo.js +10 -0
- package/dist/node_modules/motion-utils/dist/es/memo.js.map +1 -0
- package/dist/node_modules/motion-utils/dist/es/noop.js +6 -0
- package/dist/node_modules/motion-utils/dist/es/noop.js.map +1 -0
- package/dist/node_modules/motion-utils/dist/es/pipe.js +6 -0
- package/dist/node_modules/motion-utils/dist/es/pipe.js.map +1 -0
- package/dist/node_modules/motion-utils/dist/es/progress.js +9 -0
- package/dist/node_modules/motion-utils/dist/es/progress.js.map +1 -0
- package/dist/node_modules/motion-utils/dist/es/subscription-manager.js +28 -0
- package/dist/node_modules/motion-utils/dist/es/subscription-manager.js.map +1 -0
- package/dist/node_modules/motion-utils/dist/es/time-conversion.js +6 -0
- package/dist/node_modules/motion-utils/dist/es/time-conversion.js.map +1 -0
- package/dist/node_modules/motion-utils/dist/es/velocity-per-second.js +6 -0
- package/dist/node_modules/motion-utils/dist/es/velocity-per-second.js.map +1 -0
- package/dist/node_modules/motion-utils/dist/es/warn-once.js +10 -0
- package/dist/node_modules/motion-utils/dist/es/warn-once.js.map +1 -0
- package/dist/node_modules/recharts/es6/cartesian/Area.js +435 -0
- package/dist/node_modules/recharts/es6/cartesian/Area.js.map +1 -0
- package/dist/node_modules/recharts/es6/chart/{LineChart.js → AreaChart.js} +5 -5
- package/dist/node_modules/recharts/es6/chart/{LineChart.js.map → AreaChart.js.map} +1 -1
- package/package.json +2 -2
- package/dist/node_modules/recharts/es6/cartesian/Line.js +0 -473
- package/dist/node_modules/recharts/es6/cartesian/Line.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SessionDetailPage.js","names":[],"sources":["../../../../src/mybodyshield/pages/train/SessionDetailPage.tsx"],"sourcesContent":["/**\n * Train — workout session detail & live logging.\n * @module mybodyshield/pages/train\n *\n * Renders a single workout session (real `mybSession`, including its `sets`).\n * While a session is IN_PROGRESS you can log sets and complete it; completed /\n * scheduled sessions render read-only. Sets are grouped by exercise. No mock\n * data — everything comes from the myb* hooks.\n */\n\nimport { useMemo, useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport {\n ArrowLeft,\n Plus,\n CheckCircle2,\n Dumbbell,\n Weight,\n Timer,\n Flame,\n Ruler,\n Gauge,\n} from 'lucide-react';\nimport {\n Button,\n GlassCard,\n Label,\n Input,\n Textarea,\n Switch,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport {\n PageLayout,\n MetricsCard,\n StatusBadge,\n EmptyState,\n LoadingView,\n ErrorView,\n} from '../../components';\nimport { IconChip } from '../_shared/visuals';\nimport { useMyBodyShield } from '../../context';\nimport { useMybSession, useMybLogSet, useMybCompleteSession } from '../../hooks';\nimport {\n formatDateTime,\n formatRelativeTime,\n formatNumber,\n formatWeight,\n formatKcal,\n formatDuration,\n} from '../../utils/formatters';\nimport type { MybSessionSet } from '../../types';\n\n/** Parse an optional numeric string into a number, or undefined when blank. */\nfunction numOrUndef(value: string): number | undefined {\n const trimmed = value.trim();\n if (!trimmed) return undefined;\n const n = Number(trimmed);\n return Number.isFinite(n) ? n : undefined;\n}\n\ninterface LogSetForm {\n exerciseName: string;\n setNumber: string;\n reps: string;\n weight: string;\n distanceM: string;\n durationSec: string;\n isPersonalRecord: boolean;\n}\n\nconst EMPTY_LOG_FORM: LogSetForm = {\n exerciseName: '',\n setNumber: '',\n reps: '',\n weight: '',\n distanceM: '',\n durationSec: '',\n isPersonalRecord: false,\n};\n\ninterface CompleteForm {\n caloriesBurned: string;\n perceivedExertion: string;\n notes: string;\n}\n\nconst EMPTY_COMPLETE_FORM: CompleteForm = { caloriesBurned: '', perceivedExertion: '', notes: '' };\n\nexport function SessionDetailPage() {\n const { navigateTo } = useMyBodyShield();\n const { id } = useParams<{ id: string }>();\n\n const session = useMybSession(id);\n const logSet = useMybLogSet();\n const completeSession = useMybCompleteSession();\n\n const [logOpen, setLogOpen] = useState(false);\n const [logForm, setLogForm] = useState<LogSetForm>(EMPTY_LOG_FORM);\n const [logError, setLogError] = useState<string | null>(null);\n\n const [completeOpen, setCompleteOpen] = useState(false);\n const [completeForm, setCompleteForm] = useState<CompleteForm>(EMPTY_COMPLETE_FORM);\n const [completeError, setCompleteError] = useState<string | null>(null);\n\n const data = session.data;\n const sets = useMemo<MybSessionSet[]>(() => data?.sets ?? [], [data?.sets]);\n\n const groups = useMemo(() => {\n const map = new Map<string, MybSessionSet[]>();\n for (const st of sets) {\n const arr = map.get(st.exerciseName) ?? [];\n arr.push(st);\n map.set(st.exerciseName, arr);\n }\n return Array.from(map.entries()).map(([name, list]) => ({\n name,\n sets: list.slice().sort((a, b) => a.setNumber - b.setNumber),\n }));\n }, [sets]);\n\n const totalVolume = useMemo(() => sets.reduce((acc, st) => acc + st.reps * st.weight, 0), [sets]);\n\n const startedAt = data?.startedAt;\n const completedAt = data?.completedAt;\n const durationSec = useMemo(() => {\n if (!startedAt || !completedAt) return undefined;\n const start = new Date(startedAt).getTime();\n const end = new Date(completedAt).getTime();\n if (!Number.isFinite(start) || !Number.isFinite(end) || end < start) return undefined;\n return (end - start) / 1000;\n }, [startedAt, completedAt]);\n\n if (!id) {\n return (\n <PageLayout title=\"Workout session\">\n <ErrorView message=\"No session was specified.\" onRetry={() => navigateTo('train')} />\n </PageLayout>\n );\n }\n\n if (session.isLoading) {\n return (\n <PageLayout title=\"Workout session\">\n <LoadingView label=\"Loading session…\" />\n </PageLayout>\n );\n }\n\n if (session.isError || !data) {\n return (\n <PageLayout title=\"Workout session\">\n <ErrorView\n title=\"Session not found\"\n message=\"This workout session may have been removed, or you don't have access to it.\"\n onRetry={() => session.refetch()}\n />\n </PageLayout>\n );\n }\n\n const isLive = data.status === 'IN_PROGRESS';\n\n const summary = data.completedAt\n ? `Completed ${formatRelativeTime(data.completedAt)}`\n : data.startedAt\n ? `Started ${formatRelativeTime(data.startedAt)}`\n : data.scheduledFor\n ? `Scheduled ${formatRelativeTime(data.scheduledFor)}`\n : `Created ${formatRelativeTime(data.createdAt)}`;\n\n const openLog = () => {\n setLogForm(EMPTY_LOG_FORM);\n setLogError(null);\n setLogOpen(true);\n };\n\n const submitLog = async () => {\n setLogError(null);\n const exerciseName = logForm.exerciseName.trim();\n if (!exerciseName) {\n setLogError('Exercise name is required.');\n return;\n }\n try {\n const created = await logSet.mutateAsync({\n sessionId: id,\n exerciseName,\n setNumber: numOrUndef(logForm.setNumber),\n reps: numOrUndef(logForm.reps),\n weight: numOrUndef(logForm.weight),\n distanceM: numOrUndef(logForm.distanceM),\n durationSec: numOrUndef(logForm.durationSec),\n isPersonalRecord: logForm.isPersonalRecord,\n });\n // Keep the dialog open for rapid multi-set entry: preserve the exercise and\n // pre-fill the next set number, clearing the per-set measurements.\n setLogForm({\n ...EMPTY_LOG_FORM,\n exerciseName,\n setNumber: String(created.setNumber + 1),\n });\n } catch (e) {\n setLogError(e instanceof Error ? e.message : 'Failed to log the set.');\n }\n };\n\n const openComplete = () => {\n setCompleteForm(EMPTY_COMPLETE_FORM);\n setCompleteError(null);\n setCompleteOpen(true);\n };\n\n const submitComplete = async () => {\n setCompleteError(null);\n try {\n await completeSession.mutateAsync({\n id,\n input: {\n caloriesBurned: numOrUndef(completeForm.caloriesBurned),\n perceivedExertion: numOrUndef(completeForm.perceivedExertion),\n notes: completeForm.notes.trim() ? completeForm.notes.trim() : undefined,\n },\n });\n setCompleteOpen(false);\n } catch (e) {\n setCompleteError(e instanceof Error ? e.message : 'Failed to complete the session.');\n }\n };\n\n const actions = isLive ? (\n <>\n <Button variant=\"outline\" onClick={openLog}>\n <Plus className=\"h-4 w-4\" /> Log set\n </Button>\n <Button onClick={openComplete}>\n <CheckCircle2 className=\"h-4 w-4\" /> Complete\n </Button>\n </>\n ) : undefined;\n\n return (\n <PageLayout title=\"Workout session\" description={summary} actions={actions}>\n <button\n type=\"button\"\n onClick={() => navigateTo('train')}\n className=\"mb-4 inline-flex items-center gap-1.5 text-sm font-medium text-text-secondary hover:text-text-primary\"\n >\n <ArrowLeft className=\"h-4 w-4\" /> Back to sessions\n </button>\n\n {/* Header card */}\n <GlassCard treatment=\"glass\" className=\"p-6\">\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div className=\"flex items-center gap-3\">\n <IconChip\n icon={isLive ? <Flame className=\"h-5 w-5\" /> : <Dumbbell className=\"h-5 w-5\" />}\n tint={isLive ? 'var(--color-accent-teal)' : 'var(--color-accent-primary)'}\n />\n <div>\n <div className=\"flex items-center gap-2\">\n <StatusBadge status={data.status} />\n </div>\n <p className=\"mt-1 text-sm text-text-secondary\">{summary}</p>\n </div>\n </div>\n </div>\n\n <div className=\"mt-5 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {data.scheduledFor && (\n <div>\n <p className=\"text-xs text-text-tertiary\">Scheduled for</p>\n <p className=\"mt-0.5 text-sm font-medium text-text-primary\">\n {formatDateTime(data.scheduledFor)}\n </p>\n </div>\n )}\n {data.startedAt && (\n <div>\n <p className=\"text-xs text-text-tertiary\">Started</p>\n <p className=\"mt-0.5 text-sm font-medium text-text-primary\">\n {formatDateTime(data.startedAt)}\n </p>\n </div>\n )}\n {data.completedAt && (\n <div>\n <p className=\"text-xs text-text-tertiary\">Completed</p>\n <p className=\"mt-0.5 text-sm font-medium text-text-primary\">\n {formatDateTime(data.completedAt)}\n </p>\n </div>\n )}\n {data.perceivedExertion != null && (\n <div>\n <p className=\"text-xs text-text-tertiary\">Perceived exertion</p>\n <p className=\"mt-0.5 text-sm font-medium tabular-nums text-text-primary\">\n {data.perceivedExertion}/10 RPE\n </p>\n </div>\n )}\n {data.caloriesBurned > 0 && (\n <div>\n <p className=\"text-xs text-text-tertiary\">Calories burned</p>\n <p className=\"mt-0.5 text-sm font-medium tabular-nums text-text-primary\">\n {formatKcal(data.caloriesBurned)}\n </p>\n </div>\n )}\n </div>\n\n {data.notes && (\n <div className=\"mt-5 rounded-xl bg-bg-sunken/60 p-4\">\n <p className=\"text-xs text-text-tertiary\">Notes</p>\n <p className=\"mt-1 whitespace-pre-wrap text-sm text-text-secondary\">{data.notes}</p>\n </div>\n )}\n </GlassCard>\n\n {/* Stat cards */}\n <div className=\"mt-6 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <MetricsCard\n icon={<Dumbbell className=\"h-5 w-5\" />}\n value={formatNumber(sets.length)}\n label=\"Total sets\"\n />\n <MetricsCard\n icon={<Weight className=\"h-5 w-5\" />}\n value={`${formatNumber(totalVolume)} kg`}\n label=\"Total volume\"\n />\n <MetricsCard\n icon={<Timer className=\"h-5 w-5\" />}\n value={durationSec != null ? formatDuration(durationSec) : '—'}\n label=\"Duration\"\n />\n <MetricsCard\n icon={<Flame className=\"h-5 w-5\" />}\n value={data.caloriesBurned > 0 ? formatKcal(data.caloriesBurned) : '—'}\n label=\"Calories burned\"\n />\n </div>\n\n {/* Logged sets */}\n <div className=\"mt-8\">\n <div className=\"mb-3 flex items-end justify-between gap-3\">\n <div>\n <h2 className=\"text-base font-semibold text-text-primary\">Logged sets</h2>\n <p className=\"mt-0.5 text-sm text-text-secondary\">\n Every set recorded during this session, grouped by exercise.\n </p>\n </div>\n {isLive && (\n <Button variant=\"outline\" size=\"sm\" onClick={openLog} className=\"shrink-0\">\n <Plus className=\"h-4 w-4\" /> Log set\n </Button>\n )}\n </div>\n\n {groups.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Dumbbell className=\"h-10 w-10\" />}\n title=\"No sets logged yet\"\n description={\n isLive\n ? 'Log your first set to start tracking this workout.'\n : 'No sets were recorded for this session.'\n }\n action={\n isLive ? (\n <Button onClick={openLog}>\n <Plus className=\"h-4 w-4\" /> Log set\n </Button>\n ) : undefined\n }\n />\n ) : (\n <div className=\"space-y-4\">\n {groups.map((group) => (\n <GlassCard key={group.name} treatment=\"plain\" className=\"p-4\">\n <div className=\"mb-3 flex items-center justify-between gap-2\">\n <h3 className=\"text-sm font-semibold text-text-primary\">{group.name}</h3>\n <span className=\"text-xs tabular-nums text-text-tertiary\">\n {formatNumber(group.sets.length)} {group.sets.length === 1 ? 'set' : 'sets'}\n </span>\n </div>\n <ul className=\"divide-y divide-border-seam\">\n {group.sets.map((st) => {\n const isCardio = st.durationSec > 0 || st.distanceM > 0;\n return (\n <li\n key={st.id}\n className=\"flex flex-wrap items-center justify-between gap-2 py-2\"\n >\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium text-text-primary tabular-nums\">\n Set {st.setNumber}: {formatNumber(st.reps)} × {formatWeight(st.weight)}\n </span>\n {st.isPersonalRecord && <StatusBadge status=\"PR\" />}\n </div>\n <div className=\"flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-text-secondary\">\n {isCardio && st.durationSec > 0 && (\n <span className=\"inline-flex items-center gap-1 tabular-nums\">\n <Timer className=\"h-3.5 w-3.5 text-accent\" />\n {formatDuration(st.durationSec)}\n </span>\n )}\n {isCardio && st.distanceM > 0 && (\n <span className=\"inline-flex items-center gap-1 tabular-nums\">\n <Ruler className=\"h-3.5 w-3.5 text-accent\" />\n {formatNumber(st.distanceM)} m\n </span>\n )}\n </div>\n </li>\n );\n })}\n </ul>\n </GlassCard>\n ))}\n </div>\n )}\n </div>\n\n {/* Log set dialog */}\n <ResponsiveDialog open={logOpen} onOpenChange={setLogOpen}>\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Log a set</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Record reps and load for strength work, or duration and distance for cardio. The\n dialog stays open so you can log sets back-to-back.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n <div className=\"space-y-4 px-1\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-set-exercise\">Exercise</Label>\n <Input\n id=\"myb-set-exercise\"\n value={logForm.exerciseName}\n onChange={(e) => setLogForm((f) => ({ ...f, exerciseName: e.target.value }))}\n placeholder=\"e.g. Back Squat\"\n />\n </div>\n\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-set-number\">Set number</Label>\n <Input\n id=\"myb-set-number\"\n type=\"number\"\n inputMode=\"numeric\"\n min={1}\n value={logForm.setNumber}\n onChange={(e) => setLogForm((f) => ({ ...f, setNumber: e.target.value }))}\n placeholder=\"1\"\n />\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-set-reps\">Reps</Label>\n <Input\n id=\"myb-set-reps\"\n type=\"number\"\n inputMode=\"numeric\"\n min={0}\n value={logForm.reps}\n onChange={(e) => setLogForm((f) => ({ ...f, reps: e.target.value }))}\n placeholder=\"8\"\n />\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-set-weight\">Weight (kg)</Label>\n <Input\n id=\"myb-set-weight\"\n type=\"number\"\n inputMode=\"decimal\"\n min={0}\n step=\"0.5\"\n value={logForm.weight}\n onChange={(e) => setLogForm((f) => ({ ...f, weight: e.target.value }))}\n placeholder=\"60\"\n />\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-set-distance\">Distance (m)</Label>\n <Input\n id=\"myb-set-distance\"\n type=\"number\"\n inputMode=\"numeric\"\n min={0}\n value={logForm.distanceM}\n onChange={(e) => setLogForm((f) => ({ ...f, distanceM: e.target.value }))}\n placeholder=\"Optional\"\n />\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-set-duration\">Duration (sec)</Label>\n <Input\n id=\"myb-set-duration\"\n type=\"number\"\n inputMode=\"numeric\"\n min={0}\n value={logForm.durationSec}\n onChange={(e) => setLogForm((f) => ({ ...f, durationSec: e.target.value }))}\n placeholder=\"Optional\"\n />\n </div>\n </div>\n\n <div className=\"flex items-center justify-between gap-3 rounded-xl bg-bg-sunken/60 p-3\">\n <div className=\"flex items-center gap-2\">\n <Gauge className=\"h-4 w-4 text-accent\" />\n <div>\n <Label htmlFor=\"myb-set-pr\" className=\"cursor-pointer\">\n Personal record\n </Label>\n <p className=\"text-xs text-text-tertiary\">Flag this set as a new PR.</p>\n </div>\n </div>\n <Switch\n id=\"myb-set-pr\"\n checked={logForm.isPersonalRecord}\n onCheckedChange={(v) => setLogForm((f) => ({ ...f, isPersonalRecord: v }))}\n />\n </div>\n\n {logError && <p className=\"text-sm text-status-error-text\">{logError}</p>}\n </div>\n\n <ResponsiveDialogFooter>\n <Button variant=\"outline\" onClick={() => setLogOpen(false)}>\n Done\n </Button>\n <Button onClick={submitLog} disabled={logSet.isPending}>\n {logSet.isPending ? 'Logging…' : 'Log set'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n\n {/* Complete session dialog */}\n <ResponsiveDialog open={completeOpen} onOpenChange={setCompleteOpen}>\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Complete session</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Wrap up this workout and record how it went.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n <div className=\"space-y-4 px-1\">\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-complete-calories\">Calories burned</Label>\n <Input\n id=\"myb-complete-calories\"\n type=\"number\"\n inputMode=\"numeric\"\n min={0}\n value={completeForm.caloriesBurned}\n onChange={(e) =>\n setCompleteForm((f) => ({ ...f, caloriesBurned: e.target.value }))\n }\n placeholder=\"Optional\"\n />\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-complete-rpe\">Perceived exertion (1–10)</Label>\n <Input\n id=\"myb-complete-rpe\"\n type=\"number\"\n inputMode=\"numeric\"\n min={1}\n max={10}\n value={completeForm.perceivedExertion}\n onChange={(e) =>\n setCompleteForm((f) => ({ ...f, perceivedExertion: e.target.value }))\n }\n placeholder=\"Optional\"\n />\n </div>\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-complete-notes\">Notes</Label>\n <Textarea\n id=\"myb-complete-notes\"\n rows={3}\n value={completeForm.notes}\n onChange={(e) => setCompleteForm((f) => ({ ...f, notes: e.target.value }))}\n placeholder=\"How did the session feel?\"\n />\n </div>\n\n {completeError && <p className=\"text-sm text-status-error-text\">{completeError}</p>}\n </div>\n\n <ResponsiveDialogFooter>\n <Button variant=\"outline\" onClick={() => setCompleteOpen(false)}>\n Cancel\n </Button>\n <Button onClick={submitComplete} disabled={completeSession.isPending}>\n {completeSession.isPending ? 'Completing…' : 'Complete session'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SessionDetailPage.js","names":[],"sources":["../../../../src/mybodyshield/pages/train/SessionDetailPage.tsx"],"sourcesContent":["/**\n * Train — workout session detail & live logging.\n * @module mybodyshield/pages/train\n *\n * Renders a single workout session (real `mybSession`, including its `sets`).\n * While a session is IN_PROGRESS you can log sets and complete it; completed /\n * scheduled sessions render read-only. Sets are grouped by exercise. No mock\n * data — everything comes from the myb* hooks.\n */\n\nimport { useMemo, useState } from 'react';\nimport { motion, useReducedMotion } from 'framer-motion';\nimport { useParams } from 'react-router-dom';\nimport {\n ArrowLeft,\n Plus,\n CheckCircle2,\n Dumbbell,\n Weight,\n Timer,\n Flame,\n Ruler,\n Gauge,\n AlertTriangle,\n} from 'lucide-react';\nimport {\n Button,\n GlassCard,\n Label,\n Input,\n Textarea,\n Switch,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport {\n PageLayout,\n MetricsCard,\n StatusBadge,\n EmptyState,\n LoadingView,\n ErrorView,\n MybDiscussion,\n} from '../../components';\nimport { IconChip } from '../_shared/visuals';\nimport { useMyBodyShield } from '../../context';\nimport { useMybSession, useMybLogSet, useMybCompleteSession } from '../../hooks';\nimport {\n formatDateTime,\n formatRelativeTime,\n formatNumber,\n formatWeight,\n formatKcal,\n formatDuration,\n} from '../../utils/formatters';\nimport type { MybSessionSet } from '../../types';\n\n/** Shared entrance easing — a soft, decelerating cubic-bezier. */\nconst MOTION_EASE: [number, number, number, number] = [0.16, 1, 0.3, 1];\n\n/** Stagger container + rise-in child variants for grouped card entrances. */\nconst STAGGER_CONTAINER = {\n hidden: {},\n show: { transition: { staggerChildren: 0.06 } },\n};\nconst RISE_ITEM = {\n hidden: { opacity: 0, y: 12 },\n show: { opacity: 1, y: 0, transition: { duration: 0.35, ease: MOTION_EASE } },\n};\n\n/** Parse an optional numeric string into a number, or undefined when blank. */\nfunction numOrUndef(value: string): number | undefined {\n const trimmed = value.trim();\n if (!trimmed) return undefined;\n const n = Number(trimmed);\n return Number.isFinite(n) ? n : undefined;\n}\n\ninterface LogSetForm {\n exerciseName: string;\n setNumber: string;\n reps: string;\n weight: string;\n distanceM: string;\n durationSec: string;\n isPersonalRecord: boolean;\n}\n\nconst EMPTY_LOG_FORM: LogSetForm = {\n exerciseName: '',\n setNumber: '',\n reps: '',\n weight: '',\n distanceM: '',\n durationSec: '',\n isPersonalRecord: false,\n};\n\ninterface CompleteForm {\n caloriesBurned: string;\n perceivedExertion: string;\n notes: string;\n}\n\nconst EMPTY_COMPLETE_FORM: CompleteForm = { caloriesBurned: '', perceivedExertion: '', notes: '' };\n\nexport function SessionDetailPage() {\n const { navigateTo } = useMyBodyShield();\n const reduce = useReducedMotion();\n const { id } = useParams<{ id: string }>();\n\n const session = useMybSession(id);\n const logSet = useMybLogSet();\n const completeSession = useMybCompleteSession();\n\n const [logOpen, setLogOpen] = useState(false);\n const [logForm, setLogForm] = useState<LogSetForm>(EMPTY_LOG_FORM);\n const [logError, setLogError] = useState<string | null>(null);\n\n const [completeOpen, setCompleteOpen] = useState(false);\n const [completeForm, setCompleteForm] = useState<CompleteForm>(EMPTY_COMPLETE_FORM);\n const [completeError, setCompleteError] = useState<string | null>(null);\n\n const data = session.data;\n const sets = useMemo<MybSessionSet[]>(() => data?.sets ?? [], [data?.sets]);\n\n const groups = useMemo(() => {\n const map = new Map<string, MybSessionSet[]>();\n for (const st of sets) {\n const arr = map.get(st.exerciseName) ?? [];\n arr.push(st);\n map.set(st.exerciseName, arr);\n }\n return Array.from(map.entries()).map(([name, list]) => ({\n name,\n sets: list.slice().sort((a, b) => a.setNumber - b.setNumber),\n }));\n }, [sets]);\n\n const totalVolume = useMemo(() => sets.reduce((acc, st) => acc + st.reps * st.weight, 0), [sets]);\n\n const startedAt = data?.startedAt;\n const completedAt = data?.completedAt;\n const durationSec = useMemo(() => {\n if (!startedAt || !completedAt) return undefined;\n const start = new Date(startedAt).getTime();\n const end = new Date(completedAt).getTime();\n if (!Number.isFinite(start) || !Number.isFinite(end) || end < start) return undefined;\n return (end - start) / 1000;\n }, [startedAt, completedAt]);\n\n if (!id) {\n return (\n <PageLayout title=\"Workout session\">\n <ErrorView message=\"No session was specified.\" onRetry={() => navigateTo('train')} />\n </PageLayout>\n );\n }\n\n if (session.isLoading) {\n return (\n <PageLayout title=\"Workout session\">\n <LoadingView label=\"Loading session…\" />\n </PageLayout>\n );\n }\n\n if (session.isError || !data) {\n return (\n <PageLayout title=\"Workout session\">\n <ErrorView\n title=\"Session not found\"\n message=\"This workout session may have been removed, or you don't have access to it.\"\n onRetry={() => session.refetch()}\n />\n </PageLayout>\n );\n }\n\n const isLive = data.status === 'IN_PROGRESS';\n\n const summary = data.completedAt\n ? `Completed ${formatRelativeTime(data.completedAt)}`\n : data.startedAt\n ? `Started ${formatRelativeTime(data.startedAt)}`\n : data.scheduledFor\n ? `Scheduled ${formatRelativeTime(data.scheduledFor)}`\n : `Created ${formatRelativeTime(data.createdAt)}`;\n\n const openLog = () => {\n setLogForm(EMPTY_LOG_FORM);\n setLogError(null);\n setLogOpen(true);\n };\n\n const submitLog = async () => {\n setLogError(null);\n const exerciseName = logForm.exerciseName.trim();\n if (!exerciseName) {\n setLogError('Exercise name is required.');\n return;\n }\n try {\n const created = await logSet.mutateAsync({\n sessionId: id,\n exerciseName,\n setNumber: numOrUndef(logForm.setNumber),\n reps: numOrUndef(logForm.reps),\n weight: numOrUndef(logForm.weight),\n distanceM: numOrUndef(logForm.distanceM),\n durationSec: numOrUndef(logForm.durationSec),\n isPersonalRecord: logForm.isPersonalRecord,\n });\n // Keep the dialog open for rapid multi-set entry: preserve the exercise and\n // pre-fill the next set number, clearing the per-set measurements.\n setLogForm({\n ...EMPTY_LOG_FORM,\n exerciseName,\n setNumber: String(created.setNumber + 1),\n });\n } catch (e) {\n setLogError(e instanceof Error ? e.message : 'Failed to log the set.');\n }\n };\n\n const openComplete = () => {\n setCompleteForm(EMPTY_COMPLETE_FORM);\n setCompleteError(null);\n setCompleteOpen(true);\n };\n\n const submitComplete = async () => {\n setCompleteError(null);\n try {\n await completeSession.mutateAsync({\n id,\n input: {\n caloriesBurned: numOrUndef(completeForm.caloriesBurned),\n perceivedExertion: numOrUndef(completeForm.perceivedExertion),\n notes: completeForm.notes.trim() ? completeForm.notes.trim() : undefined,\n },\n });\n setCompleteOpen(false);\n } catch (e) {\n setCompleteError(e instanceof Error ? e.message : 'Failed to complete the session.');\n }\n };\n\n const actions = isLive ? (\n <>\n <Button variant=\"outline\" onClick={openLog}>\n <Plus className=\"h-4 w-4\" /> Log set\n </Button>\n <Button onClick={openComplete}>\n <CheckCircle2 className=\"h-4 w-4\" /> Complete\n </Button>\n </>\n ) : undefined;\n\n return (\n <PageLayout title=\"Workout session\" description={summary} actions={actions}>\n <button\n type=\"button\"\n onClick={() => navigateTo('train')}\n className=\"mb-4 inline-flex items-center gap-1.5 text-sm font-medium text-text-secondary hover:text-text-primary\"\n >\n <ArrowLeft className=\"h-4 w-4\" /> Back to sessions\n </button>\n\n {/* Header card */}\n <motion.div\n initial={reduce ? false : { opacity: 0, y: 10 }}\n animate={{ opacity: 1, y: 0 }}\n transition={reduce ? { duration: 0 } : { duration: 0.35, ease: MOTION_EASE }}\n >\n <GlassCard treatment=\"glass\" glow={isLive} className=\"p-6\">\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div className=\"flex items-center gap-3\">\n <IconChip\n icon={isLive ? <Flame className=\"h-5 w-5\" /> : <Dumbbell className=\"h-5 w-5\" />}\n tint={isLive ? 'var(--color-accent-teal)' : 'var(--color-accent-primary)'}\n />\n <div>\n <div className=\"flex items-center gap-2\">\n <StatusBadge status={data.status} />\n </div>\n <p className=\"mt-1 text-sm text-text-secondary\">{summary}</p>\n </div>\n </div>\n </div>\n\n <div className=\"mt-5 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {data.scheduledFor && (\n <div>\n <p className=\"text-xs text-text-tertiary\">Scheduled for</p>\n <p className=\"mt-0.5 text-sm font-medium text-text-primary\">\n {formatDateTime(data.scheduledFor)}\n </p>\n </div>\n )}\n {data.startedAt && (\n <div>\n <p className=\"text-xs text-text-tertiary\">Started</p>\n <p className=\"mt-0.5 text-sm font-medium text-text-primary\">\n {formatDateTime(data.startedAt)}\n </p>\n </div>\n )}\n {data.completedAt && (\n <div>\n <p className=\"text-xs text-text-tertiary\">Completed</p>\n <p className=\"mt-0.5 text-sm font-medium text-text-primary\">\n {formatDateTime(data.completedAt)}\n </p>\n </div>\n )}\n {data.perceivedExertion != null && (\n <div>\n <p className=\"text-xs text-text-tertiary\">Perceived exertion</p>\n <p className=\"mt-0.5 text-sm font-medium tabular-nums text-text-primary\">\n {data.perceivedExertion}/10 RPE\n </p>\n </div>\n )}\n {data.caloriesBurned > 0 && (\n <div>\n <p className=\"text-xs text-text-tertiary\">Calories burned</p>\n <p className=\"mt-0.5 text-sm font-medium tabular-nums text-text-primary\">\n {formatKcal(data.caloriesBurned)}\n </p>\n </div>\n )}\n </div>\n\n {data.notes && (\n <div className=\"mt-5 rounded-xl bg-bg-sunken/60 p-4\">\n <p className=\"text-xs text-text-tertiary\">Notes</p>\n <p className=\"mt-1 whitespace-pre-wrap text-sm text-text-secondary\">{data.notes}</p>\n </div>\n )}\n </GlassCard>\n </motion.div>\n\n {/* Stat cards */}\n <motion.div\n className=\"mt-6 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\"\n variants={reduce ? undefined : STAGGER_CONTAINER}\n initial={reduce ? false : 'hidden'}\n animate=\"show\"\n >\n <motion.div variants={reduce ? undefined : RISE_ITEM}>\n <MetricsCard\n icon={\n <span className=\"text-action-primary-bg\">\n <Dumbbell className=\"h-5 w-5\" />\n </span>\n }\n value={formatNumber(sets.length)}\n label=\"Total sets\"\n />\n </motion.div>\n <motion.div variants={reduce ? undefined : RISE_ITEM}>\n <MetricsCard\n icon={\n <span className=\"text-action-primary-bg\">\n <Weight className=\"h-5 w-5\" />\n </span>\n }\n value={`${formatNumber(totalVolume)} kg`}\n label=\"Total volume\"\n />\n </motion.div>\n <motion.div variants={reduce ? undefined : RISE_ITEM}>\n <MetricsCard\n icon={\n <span className=\"text-action-primary-bg\">\n <Timer className=\"h-5 w-5\" />\n </span>\n }\n value={durationSec != null ? formatDuration(durationSec) : '—'}\n label=\"Duration\"\n />\n </motion.div>\n <motion.div variants={reduce ? undefined : RISE_ITEM}>\n <MetricsCard\n icon={\n <span className=\"text-action-primary-bg\">\n <Flame className=\"h-5 w-5\" />\n </span>\n }\n value={data.caloriesBurned > 0 ? formatKcal(data.caloriesBurned) : '—'}\n label=\"Calories burned\"\n />\n </motion.div>\n </motion.div>\n\n {/* Logged sets */}\n <div className=\"mt-8\">\n <div className=\"mb-3 flex items-end justify-between gap-3\">\n <div>\n <h2 className=\"text-base font-semibold text-text-primary\">Logged sets</h2>\n <p className=\"mt-0.5 text-sm text-text-secondary\">\n Every set recorded during this session, grouped by exercise.\n </p>\n </div>\n {isLive && (\n <Button variant=\"outline\" size=\"sm\" onClick={openLog} className=\"shrink-0\">\n <Plus className=\"h-4 w-4\" /> Log set\n </Button>\n )}\n </div>\n\n {groups.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Dumbbell className=\"h-10 w-10\" />}\n title=\"No sets logged yet\"\n description={\n isLive\n ? 'Log your first set to start tracking this workout.'\n : 'No sets were recorded for this session.'\n }\n action={\n isLive ? (\n <Button onClick={openLog}>\n <Plus className=\"h-4 w-4\" /> Log set\n </Button>\n ) : undefined\n }\n />\n ) : (\n <motion.div\n className=\"space-y-4\"\n variants={reduce ? undefined : STAGGER_CONTAINER}\n initial={reduce ? false : 'hidden'}\n animate=\"show\"\n >\n {groups.map((group) => {\n const prCount = group.sets.filter((st) => st.isPersonalRecord).length;\n return (\n <motion.div key={group.name} variants={reduce ? undefined : RISE_ITEM}>\n <GlassCard treatment=\"plain\" className=\"p-4 transition-shadow hover:shadow-float\">\n <div className=\"mb-3 flex items-center justify-between gap-2\">\n <div className=\"flex min-w-0 items-center gap-2.5\">\n <IconChip icon={<Dumbbell className=\"h-4 w-4\" />} />\n <h3 className=\"truncate text-sm font-semibold text-text-primary\">\n {group.name}\n </h3>\n {prCount > 0 && (\n <span className=\"inline-flex items-center rounded-full bg-status-success-bg-subtle px-2 py-0.5 text-[11px] font-semibold text-status-success-text shadow-[0_0_0_3px_color-mix(in_oklab,var(--color-status-success-text)_14%,transparent)]\">\n {prCount} PR{prCount === 1 ? '' : 's'}\n </span>\n )}\n </div>\n <span className=\"shrink-0 text-xs tabular-nums text-text-tertiary\">\n {formatNumber(group.sets.length)} {group.sets.length === 1 ? 'set' : 'sets'}\n </span>\n </div>\n <ul className=\"divide-y divide-border-seam\">\n {group.sets.map((st) => {\n const isCardio = st.durationSec > 0 || st.distanceM > 0;\n return (\n <li\n key={st.id}\n className={\n 'flex flex-wrap items-center justify-between gap-2 rounded-lg px-2 py-2 transition-colors' +\n (st.isPersonalRecord\n ? ' bg-[color-mix(in_oklab,var(--color-status-success-text)_9%,transparent)]'\n : ' hover:bg-bg-sunken/40')\n }\n >\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium text-text-primary tabular-nums\">\n Set {st.setNumber}: {formatNumber(st.reps)} ×{' '}\n {formatWeight(st.weight)}\n </span>\n {st.isPersonalRecord && (\n <span className=\"inline-flex rounded-full shadow-[0_0_0_3px_color-mix(in_oklab,var(--color-status-success-text)_16%,transparent)]\">\n <StatusBadge status=\"PR\" />\n </span>\n )}\n </div>\n <div className=\"flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-text-secondary\">\n {isCardio && st.durationSec > 0 && (\n <span className=\"inline-flex items-center gap-1 tabular-nums\">\n <Timer className=\"h-3.5 w-3.5 text-accent\" />\n {formatDuration(st.durationSec)}\n </span>\n )}\n {isCardio && st.distanceM > 0 && (\n <span className=\"inline-flex items-center gap-1 tabular-nums\">\n <Ruler className=\"h-3.5 w-3.5 text-accent\" />\n {formatNumber(st.distanceM)} m\n </span>\n )}\n </div>\n </li>\n );\n })}\n </ul>\n </GlassCard>\n </motion.div>\n );\n })}\n </motion.div>\n )}\n </div>\n\n {/* Coach feedback / discussion — available for any session */}\n <div className=\"mt-8\">\n <MybDiscussion\n entityType=\"mybodyshield-session\"\n entityId={data.id}\n title=\"Coach feedback\"\n description=\"Discuss form, cues and this session's results with your coach and team.\"\n />\n </div>\n\n {/* Log set dialog */}\n <ResponsiveDialog open={logOpen} onOpenChange={setLogOpen}>\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Log a set</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Record reps and load for strength work, or duration and distance for cardio. The\n dialog stays open so you can log sets back-to-back.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n <div className=\"space-y-4 px-1\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-set-exercise\">Exercise</Label>\n <Input\n id=\"myb-set-exercise\"\n value={logForm.exerciseName}\n onChange={(e) => setLogForm((f) => ({ ...f, exerciseName: e.target.value }))}\n placeholder=\"e.g. Back Squat\"\n />\n </div>\n\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-set-number\">Set number</Label>\n <Input\n id=\"myb-set-number\"\n type=\"number\"\n inputMode=\"numeric\"\n min={1}\n value={logForm.setNumber}\n onChange={(e) => setLogForm((f) => ({ ...f, setNumber: e.target.value }))}\n placeholder=\"1\"\n />\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-set-reps\">Reps</Label>\n <Input\n id=\"myb-set-reps\"\n type=\"number\"\n inputMode=\"numeric\"\n min={0}\n value={logForm.reps}\n onChange={(e) => setLogForm((f) => ({ ...f, reps: e.target.value }))}\n placeholder=\"8\"\n />\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-set-weight\">Weight (kg)</Label>\n <Input\n id=\"myb-set-weight\"\n type=\"number\"\n inputMode=\"decimal\"\n min={0}\n step=\"0.5\"\n value={logForm.weight}\n onChange={(e) => setLogForm((f) => ({ ...f, weight: e.target.value }))}\n placeholder=\"60\"\n />\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-set-distance\">Distance (m)</Label>\n <Input\n id=\"myb-set-distance\"\n type=\"number\"\n inputMode=\"numeric\"\n min={0}\n value={logForm.distanceM}\n onChange={(e) => setLogForm((f) => ({ ...f, distanceM: e.target.value }))}\n placeholder=\"Optional\"\n />\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-set-duration\">Duration (sec)</Label>\n <Input\n id=\"myb-set-duration\"\n type=\"number\"\n inputMode=\"numeric\"\n min={0}\n value={logForm.durationSec}\n onChange={(e) => setLogForm((f) => ({ ...f, durationSec: e.target.value }))}\n placeholder=\"Optional\"\n />\n </div>\n </div>\n\n <div className=\"flex items-center justify-between gap-3 rounded-xl bg-bg-sunken/60 p-3\">\n <div className=\"flex items-center gap-2\">\n <Gauge className=\"h-4 w-4 text-accent\" />\n <div>\n <Label htmlFor=\"myb-set-pr\" className=\"cursor-pointer\">\n Personal record\n </Label>\n <p className=\"text-xs text-text-tertiary\">Flag this set as a new PR.</p>\n </div>\n </div>\n <Switch\n id=\"myb-set-pr\"\n checked={logForm.isPersonalRecord}\n onCheckedChange={(v) => setLogForm((f) => ({ ...f, isPersonalRecord: v }))}\n />\n </div>\n\n {logError && <p className=\"text-sm text-status-error-text\">{logError}</p>}\n </div>\n\n <ResponsiveDialogFooter>\n <Button variant=\"outline\" onClick={() => setLogOpen(false)}>\n Done\n </Button>\n <Button onClick={submitLog} disabled={logSet.isPending}>\n {logSet.isPending ? 'Logging…' : 'Log set'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n\n {/* Complete session dialog */}\n <ResponsiveDialog open={completeOpen} onOpenChange={setCompleteOpen}>\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Complete session</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Wrap up this workout and record how it went.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n <div className=\"space-y-4 px-1\">\n {sets.length === 0 && (\n <div className=\"flex items-start gap-2.5 rounded-xl border border-status-warning-text/40 bg-status-warning-bg-subtle p-3\">\n <AlertTriangle className=\"mt-0.5 h-4 w-4 shrink-0 text-status-warning-text\" />\n <p className=\"text-sm text-text-secondary\">\n <span className=\"font-medium text-text-primary\">No sets logged.</span> You can\n still complete this session, but nothing was recorded for it.\n </p>\n </div>\n )}\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-complete-calories\">Calories burned</Label>\n <Input\n id=\"myb-complete-calories\"\n type=\"number\"\n inputMode=\"numeric\"\n min={0}\n value={completeForm.caloriesBurned}\n onChange={(e) =>\n setCompleteForm((f) => ({ ...f, caloriesBurned: e.target.value }))\n }\n placeholder=\"Optional\"\n />\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-complete-rpe\">Perceived exertion (1–10)</Label>\n <Input\n id=\"myb-complete-rpe\"\n type=\"number\"\n inputMode=\"numeric\"\n min={1}\n max={10}\n value={completeForm.perceivedExertion}\n onChange={(e) =>\n setCompleteForm((f) => ({ ...f, perceivedExertion: e.target.value }))\n }\n placeholder=\"Optional\"\n />\n </div>\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-complete-notes\">Notes</Label>\n <Textarea\n id=\"myb-complete-notes\"\n rows={3}\n value={completeForm.notes}\n onChange={(e) => setCompleteForm((f) => ({ ...f, notes: e.target.value }))}\n placeholder=\"How did the session feel?\"\n />\n </div>\n\n {completeError && <p className=\"text-sm text-status-error-text\">{completeError}</p>}\n </div>\n\n <ResponsiveDialogFooter>\n <Button variant=\"outline\" onClick={() => setCompleteOpen(false)}>\n Cancel\n </Button>\n <Button onClick={submitComplete} disabled={completeSession.isPending}>\n {completeSession.isPending ? 'Completing…' : 'Complete session'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
import { useMyBodyShield as e } from "../../context/MyBodyShieldContext.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { motion as t } from "../../../node_modules/framer-motion/dist/es/render/components/motion/proxy.js";
|
|
3
|
+
import { useReducedMotion as n } from "../../../node_modules/framer-motion/dist/es/utils/reduced-motion/use-reduced-motion.js";
|
|
4
|
+
import { PageLayout as r } from "../../components/PageLayout.js";
|
|
5
|
+
import { formatKcal as i, formatNumber as a, formatRelativeTime as ee } from "../../utils/formatters.js";
|
|
4
6
|
import { StatusBadge as te } from "../../components/StatusBadge.js";
|
|
5
|
-
import { ErrorView as
|
|
6
|
-
import { EmptyState as
|
|
7
|
-
import { IconChip as
|
|
7
|
+
import { ErrorView as o, LoadingView as s } from "../../components/StateViews.js";
|
|
8
|
+
import { EmptyState as c } from "../../components/EmptyState.js";
|
|
9
|
+
import { IconChip as l, Meter as ne } from "../_shared/visuals.js";
|
|
8
10
|
import "../../context/index.js";
|
|
9
|
-
import { useMybPrograms as
|
|
10
|
-
import { useOffsetPager as
|
|
11
|
+
import { useMybPrograms as u, useMybSessions as re, useMybStartSession as d } from "../../hooks/useMyBodyShieldApi.js";
|
|
12
|
+
import { useOffsetPager as f } from "../../hooks/usePager.js";
|
|
11
13
|
import "../../hooks/index.js";
|
|
12
|
-
import { FilterTabs as
|
|
13
|
-
import { Pagination as
|
|
14
|
+
import { FilterTabs as p } from "../../components/FilterTabs.js";
|
|
15
|
+
import { Pagination as ie } from "../../components/Pagination.js";
|
|
14
16
|
import "../../components/index.js";
|
|
15
|
-
import { useState as
|
|
16
|
-
import { CalendarClock as
|
|
17
|
+
import { useState as m } from "react";
|
|
18
|
+
import { CalendarClock as h, CheckCircle2 as g, Flame as _, Gauge as ae, ListChecks as oe, PlayCircle as v, Plus as y, SkipForward as b } from "lucide-react";
|
|
17
19
|
import { Fragment as x, jsx as S, jsxs as C } from "react/jsx-runtime";
|
|
18
|
-
import { Button as w, GlassCard as
|
|
20
|
+
import { Button as w, GlassCard as se, Input as ce, Label as T, ResponsiveDialog as E, ResponsiveDialogContent as D, ResponsiveDialogDescription as O, ResponsiveDialogFooter as k, ResponsiveDialogHeader as A, ResponsiveDialogTitle as j, Select as M, SelectContent as N, SelectItem as P, SelectTrigger as F, SelectValue as I, Textarea as L } from "@burdenoff/fe-libs/ui";
|
|
19
21
|
//#region src/mybodyshield/pages/train/SessionsPage.tsx
|
|
20
22
|
var R = [
|
|
21
23
|
{
|
|
@@ -33,17 +35,18 @@ var R = [
|
|
|
33
35
|
{
|
|
34
36
|
value: "COMPLETED",
|
|
35
37
|
label: "Completed"
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
value: "SKIPPED",
|
|
39
|
-
label: "Skipped"
|
|
40
38
|
}
|
|
41
|
-
], z = 24, B =
|
|
42
|
-
|
|
39
|
+
], z = 24, B = [
|
|
40
|
+
.16,
|
|
41
|
+
1,
|
|
42
|
+
.3,
|
|
43
|
+
1
|
|
44
|
+
], V = "__none__", H = {
|
|
45
|
+
programId: V,
|
|
43
46
|
scheduledFor: "",
|
|
44
47
|
notes: ""
|
|
45
48
|
};
|
|
46
|
-
function
|
|
49
|
+
function U(e) {
|
|
47
50
|
switch (e.status) {
|
|
48
51
|
case "IN_PROGRESS": return {
|
|
49
52
|
icon: v,
|
|
@@ -53,9 +56,9 @@ function H(e) {
|
|
|
53
56
|
stamp: e.startedAt ?? e.createdAt
|
|
54
57
|
};
|
|
55
58
|
case "COMPLETED": return {
|
|
56
|
-
icon:
|
|
59
|
+
icon: g,
|
|
57
60
|
tint: "var(--color-status-success-text)",
|
|
58
|
-
title: e.caloriesBurned > 0 ? `${
|
|
61
|
+
title: e.caloriesBurned > 0 ? `${i(e.caloriesBurned)} burned` : "Workout completed",
|
|
59
62
|
stampLabel: "Completed",
|
|
60
63
|
stamp: e.completedAt ?? e.startedAt ?? e.createdAt
|
|
61
64
|
};
|
|
@@ -67,7 +70,7 @@ function H(e) {
|
|
|
67
70
|
stamp: e.scheduledFor ?? e.createdAt
|
|
68
71
|
};
|
|
69
72
|
default: return {
|
|
70
|
-
icon:
|
|
73
|
+
icon: h,
|
|
71
74
|
tint: "var(--color-accent-primary)",
|
|
72
75
|
title: "Scheduled session",
|
|
73
76
|
stampLabel: "Scheduled",
|
|
@@ -75,22 +78,22 @@ function H(e) {
|
|
|
75
78
|
};
|
|
76
79
|
}
|
|
77
80
|
}
|
|
78
|
-
function
|
|
79
|
-
let { navigateTo:
|
|
80
|
-
status:
|
|
81
|
+
function W() {
|
|
82
|
+
let { navigateTo: h } = e(), g = n(), [v, b] = m("ALL"), W = f(z), G = re({
|
|
83
|
+
status: v === "ALL" ? void 0 : v,
|
|
81
84
|
pagination: {
|
|
82
85
|
limit: z,
|
|
83
|
-
offset:
|
|
86
|
+
offset: W.offset
|
|
84
87
|
}
|
|
85
|
-
}),
|
|
88
|
+
}), le = u({
|
|
86
89
|
status: "ACTIVE",
|
|
87
90
|
pagination: { limit: 50 }
|
|
88
|
-
}).data?.items ?? [],
|
|
89
|
-
|
|
91
|
+
}).data?.items ?? [], K = d(), [ue, q] = m(!1), [J, Y] = m(H), [X, Z] = m(null), Q = G.data?.items ?? [], de = G.data?.pageInfo?.hasMore ?? !1, fe = (e) => {
|
|
92
|
+
b(e), W.reset();
|
|
90
93
|
}, $ = () => {
|
|
91
|
-
Y(
|
|
94
|
+
Y(H), Z(null), q(!0);
|
|
92
95
|
};
|
|
93
|
-
return /* @__PURE__ */ C(
|
|
96
|
+
return /* @__PURE__ */ C(r, {
|
|
94
97
|
title: "Train",
|
|
95
98
|
description: "Live workout sessions — start, log sets, and complete.",
|
|
96
99
|
actions: /* @__PURE__ */ C(w, {
|
|
@@ -100,53 +103,69 @@ function U() {
|
|
|
100
103
|
children: [
|
|
101
104
|
/* @__PURE__ */ S("div", {
|
|
102
105
|
className: "mb-6",
|
|
103
|
-
children: /* @__PURE__ */ S(
|
|
106
|
+
children: /* @__PURE__ */ S(p, {
|
|
104
107
|
options: R,
|
|
105
|
-
value:
|
|
106
|
-
onChange:
|
|
108
|
+
value: v,
|
|
109
|
+
onChange: fe
|
|
107
110
|
})
|
|
108
111
|
}),
|
|
109
|
-
|
|
112
|
+
G.isLoading ? /* @__PURE__ */ S(s, { label: "Loading your sessions…" }) : G.isError ? /* @__PURE__ */ S(o, {
|
|
110
113
|
message: "We couldn't load your workout sessions.",
|
|
111
|
-
onRetry: () =>
|
|
112
|
-
}) : Q.length === 0 ? /* @__PURE__ */ S(
|
|
114
|
+
onRetry: () => G.refetch()
|
|
115
|
+
}) : Q.length === 0 ? /* @__PURE__ */ S(c, {
|
|
113
116
|
illustration: "empty-data",
|
|
114
|
-
icon: /* @__PURE__ */ S(
|
|
115
|
-
title:
|
|
116
|
-
description:
|
|
117
|
+
icon: /* @__PURE__ */ S(_, { className: "h-10 w-10" }),
|
|
118
|
+
title: v === "ALL" ? "No sessions yet" : "No sessions in this state",
|
|
119
|
+
description: v === "ALL" ? "Start a workout session to begin logging sets and tracking your training." : "Try a different filter, or start a new workout session.",
|
|
117
120
|
action: /* @__PURE__ */ C(w, {
|
|
118
121
|
onClick: $,
|
|
119
122
|
children: [/* @__PURE__ */ S(y, { className: "h-4 w-4" }), " Start session"]
|
|
120
123
|
})
|
|
121
124
|
}) : /* @__PURE__ */ C(x, { children: [/* @__PURE__ */ S("div", {
|
|
122
125
|
className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
|
|
123
|
-
children: Q.map((e) => {
|
|
124
|
-
let
|
|
125
|
-
return /* @__PURE__ */ S(
|
|
126
|
+
children: Q.map((e, n) => {
|
|
127
|
+
let r = U(e), o = r.icon, s = e.status === "IN_PROGRESS", c = e.sets?.length, u = e.perceivedExertion;
|
|
128
|
+
return /* @__PURE__ */ S(t.button, {
|
|
126
129
|
type: "button",
|
|
127
|
-
onClick: () =>
|
|
128
|
-
className: "text-left",
|
|
129
|
-
|
|
130
|
+
onClick: () => h(`train/${e.id}`),
|
|
131
|
+
className: "block w-full text-left",
|
|
132
|
+
initial: g ? !1 : {
|
|
133
|
+
opacity: 0,
|
|
134
|
+
y: 12
|
|
135
|
+
},
|
|
136
|
+
animate: {
|
|
137
|
+
opacity: 1,
|
|
138
|
+
y: 0
|
|
139
|
+
},
|
|
140
|
+
transition: g ? { duration: 0 } : {
|
|
141
|
+
duration: .35,
|
|
142
|
+
delay: Math.min(n, 8) * .05,
|
|
143
|
+
ease: B
|
|
144
|
+
},
|
|
145
|
+
whileHover: g ? void 0 : { y: -3 },
|
|
146
|
+
whileTap: g ? void 0 : { scale: .995 },
|
|
147
|
+
children: /* @__PURE__ */ C(se, {
|
|
130
148
|
treatment: "plain",
|
|
131
|
-
|
|
149
|
+
glow: s,
|
|
150
|
+
className: "h-full p-4 transition-shadow hover:shadow-float" + (s ? " ring-1 ring-inset ring-[color-mix(in_oklab,var(--color-action-primary-bg)_45%,transparent)]" : ""),
|
|
132
151
|
children: [
|
|
133
152
|
/* @__PURE__ */ C("div", {
|
|
134
153
|
className: "flex items-center justify-between gap-2",
|
|
135
|
-
children: [/* @__PURE__ */ S(
|
|
136
|
-
icon: /* @__PURE__ */ S(
|
|
137
|
-
tint:
|
|
154
|
+
children: [/* @__PURE__ */ S(l, {
|
|
155
|
+
icon: /* @__PURE__ */ S(o, { className: "h-4 w-4" }),
|
|
156
|
+
tint: r.tint
|
|
138
157
|
}), /* @__PURE__ */ S(te, { status: e.status })]
|
|
139
158
|
}),
|
|
140
159
|
/* @__PURE__ */ S("p", {
|
|
141
|
-
className: "mt-3 text-
|
|
142
|
-
children:
|
|
160
|
+
className: "mt-3 text-base font-semibold text-text-primary",
|
|
161
|
+
children: r.title
|
|
143
162
|
}),
|
|
144
163
|
/* @__PURE__ */ C("p", {
|
|
145
164
|
className: "mt-0.5 text-xs text-text-tertiary",
|
|
146
165
|
children: [
|
|
147
|
-
|
|
166
|
+
r.stampLabel,
|
|
148
167
|
" ",
|
|
149
|
-
r
|
|
168
|
+
ee(r.stamp)
|
|
150
169
|
]
|
|
151
170
|
}),
|
|
152
171
|
/* @__PURE__ */ C("div", {
|
|
@@ -154,44 +173,57 @@ function U() {
|
|
|
154
173
|
children: [
|
|
155
174
|
e.caloriesBurned > 0 && /* @__PURE__ */ C("span", {
|
|
156
175
|
className: "inline-flex items-center gap-1 tabular-nums",
|
|
157
|
-
children: [/* @__PURE__ */ S(
|
|
176
|
+
children: [/* @__PURE__ */ S(_, { className: "h-3.5 w-3.5 text-status-warning-text" }), i(e.caloriesBurned)]
|
|
158
177
|
}),
|
|
159
|
-
|
|
178
|
+
u != null && /* @__PURE__ */ C("span", {
|
|
160
179
|
className: "inline-flex items-center gap-1 tabular-nums",
|
|
161
180
|
children: [
|
|
162
|
-
/* @__PURE__ */ S(
|
|
181
|
+
/* @__PURE__ */ S(ae, { className: "h-3.5 w-3.5 text-accent" }),
|
|
163
182
|
"RPE ",
|
|
164
|
-
|
|
183
|
+
u,
|
|
165
184
|
"/10"
|
|
166
185
|
]
|
|
167
186
|
}),
|
|
168
|
-
|
|
187
|
+
c != null && c > 0 && /* @__PURE__ */ C("span", {
|
|
169
188
|
className: "inline-flex items-center gap-1 tabular-nums",
|
|
170
189
|
children: [
|
|
171
|
-
/* @__PURE__ */ S(
|
|
172
|
-
|
|
190
|
+
/* @__PURE__ */ S(oe, { className: "h-3.5 w-3.5 text-accent" }),
|
|
191
|
+
a(c),
|
|
173
192
|
" sets"
|
|
174
193
|
]
|
|
175
194
|
})
|
|
176
195
|
]
|
|
177
196
|
}),
|
|
178
|
-
|
|
179
|
-
className: "mt-3
|
|
180
|
-
children:
|
|
197
|
+
u != null && /* @__PURE__ */ C("div", {
|
|
198
|
+
className: "mt-3",
|
|
199
|
+
children: [/* @__PURE__ */ C("div", {
|
|
200
|
+
className: "mb-1 flex items-center justify-between text-[11px] text-text-tertiary",
|
|
201
|
+
children: [/* @__PURE__ */ S("span", { children: "RPE intensity" }), /* @__PURE__ */ C("span", {
|
|
202
|
+
className: "tabular-nums",
|
|
203
|
+
children: [u, "/10"]
|
|
204
|
+
})]
|
|
205
|
+
}), /* @__PURE__ */ S(ne, {
|
|
206
|
+
value: u * 10,
|
|
207
|
+
height: 6
|
|
208
|
+
})]
|
|
209
|
+
}),
|
|
210
|
+
s && /* @__PURE__ */ S("p", {
|
|
211
|
+
className: "mt-3 inline-flex items-center gap-1 text-xs font-semibold text-action-primary-bg",
|
|
212
|
+
children: "In progress — Resume →"
|
|
181
213
|
})
|
|
182
214
|
]
|
|
183
215
|
})
|
|
184
216
|
}, e.id);
|
|
185
217
|
})
|
|
186
|
-
}), /* @__PURE__ */ S(
|
|
187
|
-
page:
|
|
218
|
+
}), /* @__PURE__ */ S(ie, {
|
|
219
|
+
page: W.page,
|
|
188
220
|
pageSize: z,
|
|
189
221
|
itemCount: Q.length,
|
|
190
|
-
hasMore:
|
|
191
|
-
onPageChange: (e) =>
|
|
222
|
+
hasMore: de,
|
|
223
|
+
onPageChange: (e) => W.onPageChange(e)
|
|
192
224
|
})] }),
|
|
193
225
|
/* @__PURE__ */ S(E, {
|
|
194
|
-
open:
|
|
226
|
+
open: ue,
|
|
195
227
|
onOpenChange: q,
|
|
196
228
|
children: /* @__PURE__ */ C(D, { children: [
|
|
197
229
|
/* @__PURE__ */ C(A, { children: [/* @__PURE__ */ S(j, { children: "Start a workout session" }), /* @__PURE__ */ S(O, { children: "Begin a live session now, or schedule one for later. Attach an active program to keep your training organised." })] }),
|
|
@@ -213,9 +245,9 @@ function U() {
|
|
|
213
245
|
id: "myb-start-program",
|
|
214
246
|
children: /* @__PURE__ */ S(I, { placeholder: "No program" })
|
|
215
247
|
}), /* @__PURE__ */ C(N, { children: [/* @__PURE__ */ S(P, {
|
|
216
|
-
value:
|
|
248
|
+
value: V,
|
|
217
249
|
children: "No program"
|
|
218
|
-
}),
|
|
250
|
+
}), le.map((e) => /* @__PURE__ */ S(P, {
|
|
219
251
|
value: e.id,
|
|
220
252
|
children: e.name
|
|
221
253
|
}, e.id))] })]
|
|
@@ -228,7 +260,7 @@ function U() {
|
|
|
228
260
|
htmlFor: "myb-start-scheduled",
|
|
229
261
|
children: "Scheduled for (optional)"
|
|
230
262
|
}),
|
|
231
|
-
/* @__PURE__ */ S(
|
|
263
|
+
/* @__PURE__ */ S(ce, {
|
|
232
264
|
id: "myb-start-scheduled",
|
|
233
265
|
type: "datetime-local",
|
|
234
266
|
value: J.scheduledFor,
|
|
@@ -268,23 +300,24 @@ function U() {
|
|
|
268
300
|
/* @__PURE__ */ C(k, { children: [/* @__PURE__ */ S(w, {
|
|
269
301
|
variant: "outline",
|
|
270
302
|
onClick: () => q(!1),
|
|
303
|
+
disabled: K.isPending,
|
|
271
304
|
children: "Cancel"
|
|
272
305
|
}), /* @__PURE__ */ S(w, {
|
|
273
306
|
onClick: async () => {
|
|
274
307
|
Z(null);
|
|
275
308
|
try {
|
|
276
|
-
let e = await
|
|
277
|
-
programId: J.programId ===
|
|
309
|
+
let e = await K.mutateAsync({
|
|
310
|
+
programId: J.programId === V ? void 0 : J.programId,
|
|
278
311
|
scheduledFor: J.scheduledFor ? new Date(J.scheduledFor).toISOString() : void 0,
|
|
279
312
|
notes: J.notes.trim() ? J.notes.trim() : void 0
|
|
280
313
|
});
|
|
281
|
-
q(!1),
|
|
314
|
+
q(!1), h(`train/${e.id}`);
|
|
282
315
|
} catch (e) {
|
|
283
316
|
Z(e instanceof Error ? e.message : "Failed to start the session.");
|
|
284
317
|
}
|
|
285
318
|
},
|
|
286
|
-
disabled:
|
|
287
|
-
children:
|
|
319
|
+
disabled: K.isPending,
|
|
320
|
+
children: K.isPending ? "Starting…" : "Start session"
|
|
288
321
|
})] })
|
|
289
322
|
] })
|
|
290
323
|
})
|
|
@@ -292,6 +325,6 @@ function U() {
|
|
|
292
325
|
});
|
|
293
326
|
}
|
|
294
327
|
//#endregion
|
|
295
|
-
export {
|
|
328
|
+
export { W as SessionsPage };
|
|
296
329
|
|
|
297
330
|
//# sourceMappingURL=SessionsPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SessionsPage.js","names":[],"sources":["../../../../src/mybodyshield/pages/train/SessionsPage.tsx"],"sourcesContent":["/**\n * Train — live workout sessions.\n * @module mybodyshield/pages/train\n *\n * Lists the member's workout sessions (real `mybListSessions`) filtered by\n * status, and lets you start a new live session (optionally attached to an\n * active program). In-progress sessions are highlighted with an accent ring and\n * a \"Resume\" affordance. No mock data — everything comes from the myb* hooks.\n */\n\nimport { useState } from 'react';\nimport {\n Plus,\n Flame,\n CheckCircle2,\n CalendarClock,\n PlayCircle,\n SkipForward,\n Gauge,\n ListChecks,\n} from 'lucide-react';\nimport {\n Button,\n GlassCard,\n Label,\n Textarea,\n Input,\n Select,\n SelectTrigger,\n SelectContent,\n SelectItem,\n SelectValue,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport {\n PageLayout,\n StatusBadge,\n FilterTabs,\n Pagination,\n LoadingView,\n ErrorView,\n EmptyState,\n type FilterOption,\n} from '../../components';\nimport { IconChip } from '../_shared/visuals';\nimport { useMyBodyShield } from '../../context';\nimport { useMybSessions, useMybStartSession, useMybPrograms, useOffsetPager } from '../../hooks';\nimport { formatRelativeTime, formatKcal, formatNumber } from '../../utils/formatters';\nimport type { MybSessionStatus, MybWorkoutSession } from '../../types';\n\ntype SessionFilterValue = MybSessionStatus | 'ALL';\n\nconst STATUS_TABS: FilterOption<SessionFilterValue>[] = [\n { value: 'ALL', label: 'All' },\n { value: 'SCHEDULED', label: 'Scheduled' },\n { value: 'IN_PROGRESS', label: 'Live' },\n { value: 'COMPLETED', label: 'Completed' },\n { value: 'SKIPPED', label: 'Skipped' },\n];\n\nconst PAGE_SIZE = 24;\n\n/** Sentinel for the optional program picker (Radix Select forbids an empty value). */\nconst NO_PROGRAM = '__none__';\n\ninterface StartForm {\n programId: string;\n scheduledFor: string;\n notes: string;\n}\n\nconst EMPTY_START_FORM: StartForm = { programId: NO_PROGRAM, scheduledFor: '', notes: '' };\n\ninterface SessionMeta {\n icon: typeof Flame;\n tint: string;\n title: string;\n stampLabel: string;\n stamp?: string | null;\n}\n\nfunction sessionMeta(s: MybWorkoutSession): SessionMeta {\n switch (s.status) {\n case 'IN_PROGRESS':\n return {\n icon: PlayCircle,\n tint: 'var(--color-accent-teal)',\n title: 'Live workout in progress',\n stampLabel: 'Started',\n stamp: s.startedAt ?? s.createdAt,\n };\n case 'COMPLETED':\n return {\n icon: CheckCircle2,\n tint: 'var(--color-status-success-text)',\n title:\n s.caloriesBurned > 0 ? `${formatKcal(s.caloriesBurned)} burned` : 'Workout completed',\n stampLabel: 'Completed',\n stamp: s.completedAt ?? s.startedAt ?? s.createdAt,\n };\n case 'SKIPPED':\n return {\n icon: SkipForward,\n tint: 'var(--color-text-secondary)',\n title: 'Skipped session',\n stampLabel: 'Scheduled',\n stamp: s.scheduledFor ?? s.createdAt,\n };\n case 'SCHEDULED':\n default:\n return {\n icon: CalendarClock,\n tint: 'var(--color-accent-primary)',\n title: 'Scheduled session',\n stampLabel: 'Scheduled',\n stamp: s.scheduledFor ?? s.createdAt,\n };\n }\n}\n\nexport function SessionsPage() {\n const { navigateTo } = useMyBodyShield();\n\n const [filter, setFilter] = useState<SessionFilterValue>('ALL');\n const pager = useOffsetPager(PAGE_SIZE);\n\n const sessions = useMybSessions({\n status: filter === 'ALL' ? undefined : filter,\n pagination: { limit: PAGE_SIZE, offset: pager.offset },\n });\n\n const programs = useMybPrograms({ status: 'ACTIVE', pagination: { limit: 50 } });\n const activePrograms = programs.data?.items ?? [];\n\n const startSession = useMybStartSession();\n\n const [startOpen, setStartOpen] = useState(false);\n const [form, setForm] = useState<StartForm>(EMPTY_START_FORM);\n const [formError, setFormError] = useState<string | null>(null);\n\n const rows = sessions.data?.items ?? [];\n const hasMore = sessions.data?.pageInfo?.hasMore ?? false;\n\n const onFilterChange = (value: SessionFilterValue) => {\n setFilter(value);\n pager.reset();\n };\n\n const openStart = () => {\n setForm(EMPTY_START_FORM);\n setFormError(null);\n setStartOpen(true);\n };\n\n const submitStart = async () => {\n setFormError(null);\n try {\n const created = await startSession.mutateAsync({\n programId: form.programId === NO_PROGRAM ? undefined : form.programId,\n scheduledFor: form.scheduledFor ? new Date(form.scheduledFor).toISOString() : undefined,\n notes: form.notes.trim() ? form.notes.trim() : undefined,\n });\n setStartOpen(false);\n navigateTo(`train/${created.id}`);\n } catch (e) {\n setFormError(e instanceof Error ? e.message : 'Failed to start the session.');\n }\n };\n\n return (\n <PageLayout\n title=\"Train\"\n description=\"Live workout sessions — start, log sets, and complete.\"\n actions={\n <Button onClick={openStart}>\n <Plus className=\"h-4 w-4\" /> Start session\n </Button>\n }\n >\n <div className=\"mb-6\">\n <FilterTabs options={STATUS_TABS} value={filter} onChange={onFilterChange} />\n </div>\n\n {sessions.isLoading ? (\n <LoadingView label=\"Loading your sessions…\" />\n ) : sessions.isError ? (\n <ErrorView\n message=\"We couldn't load your workout sessions.\"\n onRetry={() => sessions.refetch()}\n />\n ) : rows.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Flame className=\"h-10 w-10\" />}\n title={filter === 'ALL' ? 'No sessions yet' : 'No sessions in this state'}\n description={\n filter === 'ALL'\n ? 'Start a workout session to begin logging sets and tracking your training.'\n : 'Try a different filter, or start a new workout session.'\n }\n action={\n <Button onClick={openStart}>\n <Plus className=\"h-4 w-4\" /> Start session\n </Button>\n }\n />\n ) : (\n <>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {rows.map((s) => {\n const meta = sessionMeta(s);\n const Icon = meta.icon;\n const isLive = s.status === 'IN_PROGRESS';\n const setCount = s.sets?.length;\n return (\n <button\n key={s.id}\n type=\"button\"\n onClick={() => navigateTo(`train/${s.id}`)}\n className=\"text-left\"\n >\n <GlassCard\n treatment=\"plain\"\n className={\n 'h-full p-4 transition-shadow hover:shadow-float' +\n (isLive ? ' ring-2 ring-inset ring-accent-teal' : '')\n }\n >\n <div className=\"flex items-center justify-between gap-2\">\n <IconChip icon={<Icon className=\"h-4 w-4\" />} tint={meta.tint} />\n <StatusBadge status={s.status} />\n </div>\n <p className=\"mt-3 text-sm font-medium text-text-primary\">{meta.title}</p>\n <p className=\"mt-0.5 text-xs text-text-tertiary\">\n {meta.stampLabel} {formatRelativeTime(meta.stamp)}\n </p>\n\n <div className=\"mt-3 flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-text-secondary\">\n {s.caloriesBurned > 0 && (\n <span className=\"inline-flex items-center gap-1 tabular-nums\">\n <Flame className=\"h-3.5 w-3.5 text-status-warning-text\" />\n {formatKcal(s.caloriesBurned)}\n </span>\n )}\n {s.perceivedExertion != null && (\n <span className=\"inline-flex items-center gap-1 tabular-nums\">\n <Gauge className=\"h-3.5 w-3.5 text-accent\" />\n RPE {s.perceivedExertion}/10\n </span>\n )}\n {setCount != null && setCount > 0 && (\n <span className=\"inline-flex items-center gap-1 tabular-nums\">\n <ListChecks className=\"h-3.5 w-3.5 text-accent\" />\n {formatNumber(setCount)} sets\n </span>\n )}\n </div>\n\n {isLive && (\n <p className=\"mt-3 inline-flex items-center gap-1 text-xs font-medium text-accent\">\n Resume session →\n </p>\n )}\n </GlassCard>\n </button>\n );\n })}\n </div>\n\n <Pagination\n page={pager.page}\n pageSize={PAGE_SIZE}\n itemCount={rows.length}\n hasMore={hasMore}\n onPageChange={(t) => pager.onPageChange(t)}\n />\n </>\n )}\n\n {/* Start session dialog */}\n <ResponsiveDialog open={startOpen} onOpenChange={setStartOpen}>\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Start a workout session</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Begin a live session now, or schedule one for later. Attach an active program to keep\n your training organised.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n <div className=\"space-y-4 px-1\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-start-program\">Program (optional)</Label>\n <Select\n value={form.programId}\n onValueChange={(v) => setForm((f) => ({ ...f, programId: v }))}\n >\n <SelectTrigger id=\"myb-start-program\">\n <SelectValue placeholder=\"No program\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={NO_PROGRAM}>No program</SelectItem>\n {activePrograms.map((p) => (\n <SelectItem key={p.id} value={p.id}>\n {p.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-start-scheduled\">Scheduled for (optional)</Label>\n <Input\n id=\"myb-start-scheduled\"\n type=\"datetime-local\"\n value={form.scheduledFor}\n onChange={(e) => setForm((f) => ({ ...f, scheduledFor: e.target.value }))}\n />\n <p className=\"text-xs text-text-tertiary\">\n Leave empty to start a live session right now.\n </p>\n </div>\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-start-notes\">Notes (optional)</Label>\n <Textarea\n id=\"myb-start-notes\"\n rows={3}\n value={form.notes}\n onChange={(e) => setForm((f) => ({ ...f, notes: e.target.value }))}\n placeholder=\"Focus, target lifts, how you're feeling…\"\n />\n </div>\n\n {formError && <p className=\"text-sm text-status-error-text\">{formError}</p>}\n </div>\n\n <ResponsiveDialogFooter>\n <Button variant=\"outline\" onClick={() => setStartOpen(false)}>\n Cancel\n </Button>\n <Button onClick={submitStart} disabled={startSession.isPending}>\n {startSession.isPending ? 'Starting…' : 'Start session'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SessionsPage.js","names":[],"sources":["../../../../src/mybodyshield/pages/train/SessionsPage.tsx"],"sourcesContent":["/**\n * Train — live workout sessions.\n * @module mybodyshield/pages/train\n *\n * Lists the member's workout sessions (real `mybListSessions`) filtered by\n * status, and lets you start a new live session (optionally attached to an\n * active program). In-progress sessions are highlighted with an accent ring and\n * a \"Resume\" affordance. No mock data — everything comes from the myb* hooks.\n */\n\nimport { useState } from 'react';\nimport { motion, useReducedMotion } from 'framer-motion';\nimport {\n Plus,\n Flame,\n CheckCircle2,\n CalendarClock,\n PlayCircle,\n SkipForward,\n Gauge,\n ListChecks,\n} from 'lucide-react';\nimport {\n Button,\n GlassCard,\n Label,\n Textarea,\n Input,\n Select,\n SelectTrigger,\n SelectContent,\n SelectItem,\n SelectValue,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport {\n PageLayout,\n StatusBadge,\n FilterTabs,\n Pagination,\n LoadingView,\n ErrorView,\n EmptyState,\n type FilterOption,\n} from '../../components';\nimport { IconChip, Meter } from '../_shared/visuals';\nimport { useMyBodyShield } from '../../context';\nimport { useMybSessions, useMybStartSession, useMybPrograms, useOffsetPager } from '../../hooks';\nimport { formatRelativeTime, formatKcal, formatNumber } from '../../utils/formatters';\nimport type { MybSessionStatus, MybWorkoutSession } from '../../types';\n\ntype SessionFilterValue = MybSessionStatus | 'ALL';\n\n// Only statuses a control can actually reach are offered as filters: start →\n// IN_PROGRESS / SCHEDULED, complete → COMPLETED. Nothing moves a session to\n// SKIPPED, so that tab would always be empty. sessionMeta still handles the\n// SKIPPED case for display safety.\nconst STATUS_TABS: FilterOption<SessionFilterValue>[] = [\n { value: 'ALL', label: 'All' },\n { value: 'SCHEDULED', label: 'Scheduled' },\n { value: 'IN_PROGRESS', label: 'Live' },\n { value: 'COMPLETED', label: 'Completed' },\n];\n\nconst PAGE_SIZE = 24;\n\n/** Shared entrance easing — a soft, decelerating cubic-bezier. */\nconst MOTION_EASE: [number, number, number, number] = [0.16, 1, 0.3, 1];\n\n/** Sentinel for the optional program picker (Radix Select forbids an empty value). */\nconst NO_PROGRAM = '__none__';\n\ninterface StartForm {\n programId: string;\n scheduledFor: string;\n notes: string;\n}\n\nconst EMPTY_START_FORM: StartForm = { programId: NO_PROGRAM, scheduledFor: '', notes: '' };\n\ninterface SessionMeta {\n icon: typeof Flame;\n tint: string;\n title: string;\n stampLabel: string;\n stamp?: string | null;\n}\n\nfunction sessionMeta(s: MybWorkoutSession): SessionMeta {\n switch (s.status) {\n case 'IN_PROGRESS':\n return {\n icon: PlayCircle,\n tint: 'var(--color-accent-teal)',\n title: 'Live workout in progress',\n stampLabel: 'Started',\n stamp: s.startedAt ?? s.createdAt,\n };\n case 'COMPLETED':\n return {\n icon: CheckCircle2,\n tint: 'var(--color-status-success-text)',\n title:\n s.caloriesBurned > 0 ? `${formatKcal(s.caloriesBurned)} burned` : 'Workout completed',\n stampLabel: 'Completed',\n stamp: s.completedAt ?? s.startedAt ?? s.createdAt,\n };\n case 'SKIPPED':\n return {\n icon: SkipForward,\n tint: 'var(--color-text-secondary)',\n title: 'Skipped session',\n stampLabel: 'Scheduled',\n stamp: s.scheduledFor ?? s.createdAt,\n };\n case 'SCHEDULED':\n default:\n return {\n icon: CalendarClock,\n tint: 'var(--color-accent-primary)',\n title: 'Scheduled session',\n stampLabel: 'Scheduled',\n stamp: s.scheduledFor ?? s.createdAt,\n };\n }\n}\n\nexport function SessionsPage() {\n const { navigateTo } = useMyBodyShield();\n const reduce = useReducedMotion();\n\n const [filter, setFilter] = useState<SessionFilterValue>('ALL');\n const pager = useOffsetPager(PAGE_SIZE);\n\n const sessions = useMybSessions({\n status: filter === 'ALL' ? undefined : filter,\n pagination: { limit: PAGE_SIZE, offset: pager.offset },\n });\n\n const programs = useMybPrograms({ status: 'ACTIVE', pagination: { limit: 50 } });\n const activePrograms = programs.data?.items ?? [];\n\n const startSession = useMybStartSession();\n\n const [startOpen, setStartOpen] = useState(false);\n const [form, setForm] = useState<StartForm>(EMPTY_START_FORM);\n const [formError, setFormError] = useState<string | null>(null);\n\n const rows = sessions.data?.items ?? [];\n const hasMore = sessions.data?.pageInfo?.hasMore ?? false;\n\n const onFilterChange = (value: SessionFilterValue) => {\n setFilter(value);\n pager.reset();\n };\n\n const openStart = () => {\n setForm(EMPTY_START_FORM);\n setFormError(null);\n setStartOpen(true);\n };\n\n const submitStart = async () => {\n setFormError(null);\n try {\n const created = await startSession.mutateAsync({\n programId: form.programId === NO_PROGRAM ? undefined : form.programId,\n scheduledFor: form.scheduledFor ? new Date(form.scheduledFor).toISOString() : undefined,\n notes: form.notes.trim() ? form.notes.trim() : undefined,\n });\n setStartOpen(false);\n navigateTo(`train/${created.id}`);\n } catch (e) {\n setFormError(e instanceof Error ? e.message : 'Failed to start the session.');\n }\n };\n\n return (\n <PageLayout\n title=\"Train\"\n description=\"Live workout sessions — start, log sets, and complete.\"\n actions={\n <Button onClick={openStart}>\n <Plus className=\"h-4 w-4\" /> Start session\n </Button>\n }\n >\n <div className=\"mb-6\">\n <FilterTabs options={STATUS_TABS} value={filter} onChange={onFilterChange} />\n </div>\n\n {sessions.isLoading ? (\n <LoadingView label=\"Loading your sessions…\" />\n ) : sessions.isError ? (\n <ErrorView\n message=\"We couldn't load your workout sessions.\"\n onRetry={() => sessions.refetch()}\n />\n ) : rows.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Flame className=\"h-10 w-10\" />}\n title={filter === 'ALL' ? 'No sessions yet' : 'No sessions in this state'}\n description={\n filter === 'ALL'\n ? 'Start a workout session to begin logging sets and tracking your training.'\n : 'Try a different filter, or start a new workout session.'\n }\n action={\n <Button onClick={openStart}>\n <Plus className=\"h-4 w-4\" /> Start session\n </Button>\n }\n />\n ) : (\n <>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {rows.map((s, i) => {\n const meta = sessionMeta(s);\n const Icon = meta.icon;\n const isLive = s.status === 'IN_PROGRESS';\n const setCount = s.sets?.length;\n const rpe = s.perceivedExertion;\n return (\n <motion.button\n key={s.id}\n type=\"button\"\n onClick={() => navigateTo(`train/${s.id}`)}\n className=\"block w-full text-left\"\n initial={reduce ? false : { opacity: 0, y: 12 }}\n animate={{ opacity: 1, y: 0 }}\n transition={\n reduce\n ? { duration: 0 }\n : { duration: 0.35, delay: Math.min(i, 8) * 0.05, ease: MOTION_EASE }\n }\n whileHover={reduce ? undefined : { y: -3 }}\n whileTap={reduce ? undefined : { scale: 0.995 }}\n >\n <GlassCard\n treatment=\"plain\"\n glow={isLive}\n className={\n 'h-full p-4 transition-shadow hover:shadow-float' +\n (isLive\n ? ' ring-1 ring-inset ring-[color-mix(in_oklab,var(--color-action-primary-bg)_45%,transparent)]'\n : '')\n }\n >\n <div className=\"flex items-center justify-between gap-2\">\n <IconChip icon={<Icon className=\"h-4 w-4\" />} tint={meta.tint} />\n <StatusBadge status={s.status} />\n </div>\n <p className=\"mt-3 text-base font-semibold text-text-primary\">{meta.title}</p>\n <p className=\"mt-0.5 text-xs text-text-tertiary\">\n {meta.stampLabel} {formatRelativeTime(meta.stamp)}\n </p>\n\n <div className=\"mt-3 flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-text-secondary\">\n {s.caloriesBurned > 0 && (\n <span className=\"inline-flex items-center gap-1 tabular-nums\">\n <Flame className=\"h-3.5 w-3.5 text-status-warning-text\" />\n {formatKcal(s.caloriesBurned)}\n </span>\n )}\n {rpe != null && (\n <span className=\"inline-flex items-center gap-1 tabular-nums\">\n <Gauge className=\"h-3.5 w-3.5 text-accent\" />\n RPE {rpe}/10\n </span>\n )}\n {setCount != null && setCount > 0 && (\n <span className=\"inline-flex items-center gap-1 tabular-nums\">\n <ListChecks className=\"h-3.5 w-3.5 text-accent\" />\n {formatNumber(setCount)} sets\n </span>\n )}\n </div>\n\n {rpe != null && (\n <div className=\"mt-3\">\n <div className=\"mb-1 flex items-center justify-between text-[11px] text-text-tertiary\">\n <span>RPE intensity</span>\n <span className=\"tabular-nums\">{rpe}/10</span>\n </div>\n <Meter value={rpe * 10} height={6} />\n </div>\n )}\n\n {isLive && (\n <p className=\"mt-3 inline-flex items-center gap-1 text-xs font-semibold text-action-primary-bg\">\n In progress — Resume →\n </p>\n )}\n </GlassCard>\n </motion.button>\n );\n })}\n </div>\n\n <Pagination\n page={pager.page}\n pageSize={PAGE_SIZE}\n itemCount={rows.length}\n hasMore={hasMore}\n onPageChange={(t) => pager.onPageChange(t)}\n />\n </>\n )}\n\n {/* Start session dialog */}\n <ResponsiveDialog open={startOpen} onOpenChange={setStartOpen}>\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Start a workout session</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Begin a live session now, or schedule one for later. Attach an active program to keep\n your training organised.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n <div className=\"space-y-4 px-1\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-start-program\">Program (optional)</Label>\n <Select\n value={form.programId}\n onValueChange={(v) => setForm((f) => ({ ...f, programId: v }))}\n >\n <SelectTrigger id=\"myb-start-program\">\n <SelectValue placeholder=\"No program\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={NO_PROGRAM}>No program</SelectItem>\n {activePrograms.map((p) => (\n <SelectItem key={p.id} value={p.id}>\n {p.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-start-scheduled\">Scheduled for (optional)</Label>\n <Input\n id=\"myb-start-scheduled\"\n type=\"datetime-local\"\n value={form.scheduledFor}\n onChange={(e) => setForm((f) => ({ ...f, scheduledFor: e.target.value }))}\n />\n <p className=\"text-xs text-text-tertiary\">\n Leave empty to start a live session right now.\n </p>\n </div>\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-start-notes\">Notes (optional)</Label>\n <Textarea\n id=\"myb-start-notes\"\n rows={3}\n value={form.notes}\n onChange={(e) => setForm((f) => ({ ...f, notes: e.target.value }))}\n placeholder=\"Focus, target lifts, how you're feeling…\"\n />\n </div>\n\n {formError && <p className=\"text-sm text-status-error-text\">{formError}</p>}\n </div>\n\n <ResponsiveDialogFooter>\n <Button\n variant=\"outline\"\n onClick={() => setStartOpen(false)}\n disabled={startSession.isPending}\n >\n Cancel\n </Button>\n <Button onClick={submitStart} disabled={startSession.isPending}>\n {startSession.isPending ? 'Starting…' : 'Start session'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|