@wger-project/react-components 25.10.16

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.
Files changed (531) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +58 -0
  3. package/build/OpenSans-Bold.woff +0 -0
  4. package/build/OpenSans-Light.woff +0 -0
  5. package/build/assets/index.css +1 -0
  6. package/build/chunks/browser-ponyfill-DL_vVusK.js +3 -0
  7. package/build/chunks/browser-ponyfill-DL_vVusK.js.map +1 -0
  8. package/build/favicon.ico +0 -0
  9. package/build/index.html +60 -0
  10. package/build/locales/README.md +10 -0
  11. package/build/locales/ar/translation.json +240 -0
  12. package/build/locales/ca/translation.json +35 -0
  13. package/build/locales/cs/translation.json +257 -0
  14. package/build/locales/de/translation.json +338 -0
  15. package/build/locales/el/translation.json +97 -0
  16. package/build/locales/en/translation.json +332 -0
  17. package/build/locales/es/translation.json +335 -0
  18. package/build/locales/fa/translation.json +127 -0
  19. package/build/locales/fr/translation.json +341 -0
  20. package/build/locales/he/translation.json +146 -0
  21. package/build/locales/hr/translation.json +249 -0
  22. package/build/locales/it/translation.json +338 -0
  23. package/build/locales/ko/translation.json +331 -0
  24. package/build/locales/nb_NO/translation.json +50 -0
  25. package/build/locales/nl/translation.json +242 -0
  26. package/build/locales/pl/translation.json +261 -0
  27. package/build/locales/pt/translation.json +342 -0
  28. package/build/locales/pt_BR/translation.json +259 -0
  29. package/build/locales/pt_PT/translation.json +334 -0
  30. package/build/locales/ru/translation.json +116 -0
  31. package/build/locales/sk/translation.json +10 -0
  32. package/build/locales/sl/translation.json +326 -0
  33. package/build/locales/sr/translation.json +240 -0
  34. package/build/locales/sv/translation.json +165 -0
  35. package/build/locales/ta/translation.json +331 -0
  36. package/build/locales/th/translation.json +27 -0
  37. package/build/locales/tr/translation.json +238 -0
  38. package/build/locales/uk/translation.json +339 -0
  39. package/build/locales/uz/translation.json +56 -0
  40. package/build/locales/vi/translation.json +70 -0
  41. package/build/locales/zh_Hans/translation.json +336 -0
  42. package/build/locales/zh_Hant/translation.json +246 -0
  43. package/build/logo192.png +0 -0
  44. package/build/logo512.png +0 -0
  45. package/build/main.js +542 -0
  46. package/build/main.js.map +1 -0
  47. package/build/manifest.json +25 -0
  48. package/build/muscles/SOURCES +2 -0
  49. package/build/muscles/main/muscle-1.svg +72 -0
  50. package/build/muscles/main/muscle-10.svg +73 -0
  51. package/build/muscles/main/muscle-11.svg +72 -0
  52. package/build/muscles/main/muscle-12.svg +72 -0
  53. package/build/muscles/main/muscle-13.svg +92 -0
  54. package/build/muscles/main/muscle-14.svg +73 -0
  55. package/build/muscles/main/muscle-15.svg +72 -0
  56. package/build/muscles/main/muscle-16.svg +73 -0
  57. package/build/muscles/main/muscle-2.svg +72 -0
  58. package/build/muscles/main/muscle-3.svg +72 -0
  59. package/build/muscles/main/muscle-4.svg +72 -0
  60. package/build/muscles/main/muscle-5.svg +72 -0
  61. package/build/muscles/main/muscle-6.svg +73 -0
  62. package/build/muscles/main/muscle-7.svg +72 -0
  63. package/build/muscles/main/muscle-8.svg +72 -0
  64. package/build/muscles/main/muscle-9.svg +72 -0
  65. package/build/muscles/muscular_system_back.svg +118 -0
  66. package/build/muscles/muscular_system_front.svg +99 -0
  67. package/build/muscles/secondary/muscle-1.svg +72 -0
  68. package/build/muscles/secondary/muscle-10.svg +73 -0
  69. package/build/muscles/secondary/muscle-11.svg +72 -0
  70. package/build/muscles/secondary/muscle-12.svg +72 -0
  71. package/build/muscles/secondary/muscle-13.svg +92 -0
  72. package/build/muscles/secondary/muscle-14.svg +73 -0
  73. package/build/muscles/secondary/muscle-15.svg +72 -0
  74. package/build/muscles/secondary/muscle-16.svg +73 -0
  75. package/build/muscles/secondary/muscle-2.svg +72 -0
  76. package/build/muscles/secondary/muscle-3.svg +72 -0
  77. package/build/muscles/secondary/muscle-4.svg +72 -0
  78. package/build/muscles/secondary/muscle-5.svg +72 -0
  79. package/build/muscles/secondary/muscle-6.svg +73 -0
  80. package/build/muscles/secondary/muscle-7.svg +72 -0
  81. package/build/muscles/secondary/muscle-8.svg +72 -0
  82. package/build/muscles/secondary/muscle-9.svg +72 -0
  83. package/build/robots.txt +3 -0
  84. package/index.html +59 -0
  85. package/package.json +125 -0
  86. package/src/.sass-cache/166f82406a0edab65b7f8fd8256819ee2f34bebf/App.module.scssc +0 -0
  87. package/src/@types/i18next.d.ts +13 -0
  88. package/src/App.tsx +25 -0
  89. package/src/assets/images/discord-logo.svg +1 -0
  90. package/src/assets/images/get-it-on-google-play.svg +1 -0
  91. package/src/assets/images/logo.png +0 -0
  92. package/src/assets/images/twitter-logo-50.png +0 -0
  93. package/src/assets/images/twitter.svg +5 -0
  94. package/src/components/BodyWeight/Form/WeightForm.test.tsx +100 -0
  95. package/src/components/BodyWeight/Form/WeightForm.tsx +102 -0
  96. package/src/components/BodyWeight/Table/ActionButton/ActionButton.test.tsx +65 -0
  97. package/src/components/BodyWeight/Table/ActionButton/ActionButton.tsx +67 -0
  98. package/src/components/BodyWeight/Table/Fab/Fab.tsx +35 -0
  99. package/src/components/BodyWeight/Table/index.test.tsx +33 -0
  100. package/src/components/BodyWeight/Table/index.tsx +98 -0
  101. package/src/components/BodyWeight/Table/table.module.css +5 -0
  102. package/src/components/BodyWeight/Table/table.module.css.map +1 -0
  103. package/src/components/BodyWeight/Table/table.module.scss +0 -0
  104. package/src/components/BodyWeight/Table/table.mosule.css +2 -0
  105. package/src/components/BodyWeight/Table/table.mosule.css.map +1 -0
  106. package/src/components/BodyWeight/TableDashboard/TableDashboard.test.tsx +24 -0
  107. package/src/components/BodyWeight/TableDashboard/TableDashboard.tsx +62 -0
  108. package/src/components/BodyWeight/WeightChart/index.test.tsx +66 -0
  109. package/src/components/BodyWeight/WeightChart/index.tsx +105 -0
  110. package/src/components/BodyWeight/body_weight.module.css +8 -0
  111. package/src/components/BodyWeight/body_weight.module.css.map +1 -0
  112. package/src/components/BodyWeight/body_weight.module.scss +8 -0
  113. package/src/components/BodyWeight/index.test.tsx +92 -0
  114. package/src/components/BodyWeight/index.tsx +40 -0
  115. package/src/components/BodyWeight/model.ts +40 -0
  116. package/src/components/BodyWeight/queries/index.ts +49 -0
  117. package/src/components/BodyWeight/utils.test.ts +44 -0
  118. package/src/components/BodyWeight/utils.ts +22 -0
  119. package/src/components/BodyWeight/widgets/FilterButtons.test.tsx +57 -0
  120. package/src/components/BodyWeight/widgets/FilterButtons.tsx +69 -0
  121. package/src/components/BodyWeight/widgets/fab.tsx +33 -0
  122. package/src/components/Calendar/Components/CalendarComponent.test.tsx +141 -0
  123. package/src/components/Calendar/Components/CalendarComponent.tsx +250 -0
  124. package/src/components/Calendar/Components/CalendarDay.tsx +105 -0
  125. package/src/components/Calendar/Components/CalendarDayGrid.tsx +53 -0
  126. package/src/components/Calendar/Components/CalendarHeader.tsx +39 -0
  127. package/src/components/Calendar/Components/Entries.test.tsx +81 -0
  128. package/src/components/Calendar/Components/Entries.tsx +163 -0
  129. package/src/components/Calendar/Helpers/CalendarMeasurement.tsx +10 -0
  130. package/src/components/Carousel/carousel.module.css +43 -0
  131. package/src/components/Carousel/carousel.module.css.map +1 -0
  132. package/src/components/Carousel/carousel.module.scss +46 -0
  133. package/src/components/Carousel/index.tsx +66 -0
  134. package/src/components/Common/forms/LicenseAuthor.tsx +19 -0
  135. package/src/components/Common/forms/LicenseAuthorUrl.tsx +20 -0
  136. package/src/components/Common/forms/LicenseDerivativeSourceUrl.tsx +20 -0
  137. package/src/components/Common/forms/LicenseObjectUrl.tsx +20 -0
  138. package/src/components/Common/forms/LicenseTitle.tsx +19 -0
  139. package/src/components/Common/forms/WgerTextField.tsx +27 -0
  140. package/src/components/Core/LoadingWidget/LoadingWidget.tsx +22 -0
  141. package/src/components/Core/Modals/DeleteConfirmationModal.test.tsx +57 -0
  142. package/src/components/Core/Modals/DeleteConfirmationModal.tsx +74 -0
  143. package/src/components/Core/Modals/WgerModal.test.tsx +45 -0
  144. package/src/components/Core/Modals/WgerModal.tsx +46 -0
  145. package/src/components/Core/Notifications/index.tsx +57 -0
  146. package/src/components/Core/Notifications/notifications.module.css +8 -0
  147. package/src/components/Core/Notifications/notifications.module.css.map +1 -0
  148. package/src/components/Core/Notifications/notifications.module.scss +6 -0
  149. package/src/components/Core/Tooltips/LightToolTip.tsx +14 -0
  150. package/src/components/Core/Widgets/Container.tsx +98 -0
  151. package/src/components/Core/Widgets/FormError.tsx +64 -0
  152. package/src/components/Core/Widgets/OverviewEmpty.tsx +26 -0
  153. package/src/components/Core/Widgets/RenderLoadingQuery.tsx +28 -0
  154. package/src/components/Core/queries/index.ts +2 -0
  155. package/src/components/Core/queries/languageCheck.ts +31 -0
  156. package/src/components/Dashboard/Dashboard.tsx +22 -0
  157. package/src/components/Dashboard/EmptyCard.tsx +56 -0
  158. package/src/components/Dashboard/NutritionCard.test.tsx +89 -0
  159. package/src/components/Dashboard/NutritionCard.tsx +178 -0
  160. package/src/components/Dashboard/RoutineCard.test.tsx +66 -0
  161. package/src/components/Dashboard/RoutineCard.tsx +107 -0
  162. package/src/components/Dashboard/WeightCard.test.tsx +81 -0
  163. package/src/components/Dashboard/WeightCard.tsx +72 -0
  164. package/src/components/Exercises/Add/AddExerciseStepper.test.tsx +26 -0
  165. package/src/components/Exercises/Add/AddExerciseStepper.tsx +97 -0
  166. package/src/components/Exercises/Add/NotEnoughRights.tsx +37 -0
  167. package/src/components/Exercises/Add/Step1Basics.test.tsx +133 -0
  168. package/src/components/Exercises/Add/Step1Basics.tsx +179 -0
  169. package/src/components/Exercises/Add/Step2Variations.test.tsx +149 -0
  170. package/src/components/Exercises/Add/Step2Variations.tsx +237 -0
  171. package/src/components/Exercises/Add/Step3Description.test.tsx +66 -0
  172. package/src/components/Exercises/Add/Step3Description.tsx +96 -0
  173. package/src/components/Exercises/Add/Step4Translation.test.tsx +119 -0
  174. package/src/components/Exercises/Add/Step4Translations.tsx +183 -0
  175. package/src/components/Exercises/Add/Step5Images.test.tsx +28 -0
  176. package/src/components/Exercises/Add/Step5Images.tsx +269 -0
  177. package/src/components/Exercises/Add/Step6Overview.test.tsx +128 -0
  178. package/src/components/Exercises/Add/Step6Overview.tsx +262 -0
  179. package/src/components/Exercises/Detail/ExerciseDetailEdit.test.tsx +248 -0
  180. package/src/components/Exercises/Detail/ExerciseDetailEdit.tsx +340 -0
  181. package/src/components/Exercises/Detail/ExerciseDetailView.test.tsx +96 -0
  182. package/src/components/Exercises/Detail/ExerciseDetailView.tsx +242 -0
  183. package/src/components/Exercises/Detail/ExerciseDetails.test.tsx +88 -0
  184. package/src/components/Exercises/Detail/ExerciseDetails.tsx +119 -0
  185. package/src/components/Exercises/Detail/ExerciseImageAvatar.tsx +20 -0
  186. package/src/components/Exercises/Detail/ExerciseImagePlaceholder.tsx +21 -0
  187. package/src/components/Exercises/Detail/Head/ExerciseDeleteDialog.test.tsx +125 -0
  188. package/src/components/Exercises/Detail/Head/ExerciseDeleteDialog.tsx +185 -0
  189. package/src/components/Exercises/Detail/Head/head.module.css +73 -0
  190. package/src/components/Exercises/Detail/Head/head.module.css.map +7 -0
  191. package/src/components/Exercises/Detail/Head/head.module.scss +111 -0
  192. package/src/components/Exercises/Detail/Head/index.tsx +175 -0
  193. package/src/components/Exercises/Detail/OverviewCard.test.tsx +98 -0
  194. package/src/components/Exercises/Detail/OverviewCard.tsx +68 -0
  195. package/src/components/Exercises/Detail/SideGallery/index.tsx +65 -0
  196. package/src/components/Exercises/Detail/SideGallery/side_gallery.module.css +26 -0
  197. package/src/components/Exercises/Detail/SideGallery/side_gallery.module.css.map +7 -0
  198. package/src/components/Exercises/Detail/SideGallery/side_gallery.module.scss +34 -0
  199. package/src/components/Exercises/ExerciseOverview.test.tsx +183 -0
  200. package/src/components/Exercises/ExerciseOverview.tsx +293 -0
  201. package/src/components/Exercises/Filter/CategoryFilter.test.tsx +57 -0
  202. package/src/components/Exercises/Filter/CategoryFilter.tsx +105 -0
  203. package/src/components/Exercises/Filter/EquipmentFilter.test.tsx +55 -0
  204. package/src/components/Exercises/Filter/EquipmentFilter.tsx +105 -0
  205. package/src/components/Exercises/Filter/ExerciseFiltersContext.tsx +16 -0
  206. package/src/components/Exercises/Filter/FilterDrawer.tsx +38 -0
  207. package/src/components/Exercises/Filter/MuscleFilter.test.tsx +50 -0
  208. package/src/components/Exercises/Filter/MuscleFilter.tsx +130 -0
  209. package/src/components/Exercises/Filter/NameAutcompleter.tsx +146 -0
  210. package/src/components/Exercises/Filter/NameAutocompleter.test.tsx +76 -0
  211. package/src/components/Exercises/Overview/ExerciseGrid.tsx +44 -0
  212. package/src/components/Exercises/Overview/ExerciseGridLoadingSkeleton.test.tsx +10 -0
  213. package/src/components/Exercises/Overview/ExerciseGridLoadingSkeleton.tsx +26 -0
  214. package/src/components/Exercises/forms/Category.test.tsx +49 -0
  215. package/src/components/Exercises/forms/Category.tsx +41 -0
  216. package/src/components/Exercises/forms/Equipment.test.tsx +84 -0
  217. package/src/components/Exercises/forms/Equipment.tsx +38 -0
  218. package/src/components/Exercises/forms/ExerciseAliases.tsx +37 -0
  219. package/src/components/Exercises/forms/ExerciseDescription.tsx +57 -0
  220. package/src/components/Exercises/forms/ExerciseEquipmentSelect.tsx +29 -0
  221. package/src/components/Exercises/forms/ExerciseName.tsx +19 -0
  222. package/src/components/Exercises/forms/ExerciseNotes.tsx +72 -0
  223. package/src/components/Exercises/forms/ExerciseSelect.tsx +28 -0
  224. package/src/components/Exercises/forms/ImageCard.tsx +101 -0
  225. package/src/components/Exercises/forms/ImageStyle.tsx +74 -0
  226. package/src/components/Exercises/forms/Muscle.test.tsx +74 -0
  227. package/src/components/Exercises/forms/Muscle.tsx +41 -0
  228. package/src/components/Exercises/forms/VideoCard.tsx +109 -0
  229. package/src/components/Exercises/forms/yupValidators.ts +46 -0
  230. package/src/components/Exercises/models/alias.ts +29 -0
  231. package/src/components/Exercises/models/category.ts +35 -0
  232. package/src/components/Exercises/models/equipment.ts +33 -0
  233. package/src/components/Exercises/models/exercise.test.ts +74 -0
  234. package/src/components/Exercises/models/exercise.ts +159 -0
  235. package/src/components/Exercises/models/image.ts +41 -0
  236. package/src/components/Exercises/models/language.ts +23 -0
  237. package/src/components/Exercises/models/muscle.test.ts +17 -0
  238. package/src/components/Exercises/models/muscle.ts +39 -0
  239. package/src/components/Exercises/models/note.ts +29 -0
  240. package/src/components/Exercises/models/translation.test.ts +68 -0
  241. package/src/components/Exercises/models/translation.ts +83 -0
  242. package/src/components/Exercises/models/video.ts +30 -0
  243. package/src/components/Exercises/queries/exercises.ts +29 -0
  244. package/src/components/Exercises/queries/index.ts +133 -0
  245. package/src/components/Exercises/queries/variations.ts +15 -0
  246. package/src/components/Header/SubMenus/BodyWeightSubMenu.tsx +27 -0
  247. package/src/components/Header/SubMenus/MeasurementsSubMenu.tsx +28 -0
  248. package/src/components/Header/SubMenus/NutritionSubMenu.tsx +28 -0
  249. package/src/components/Header/SubMenus/TrainingSubMenu.tsx +43 -0
  250. package/src/components/Header/SubMenus/WorkoutSubMenu.tsx +28 -0
  251. package/src/components/Header/index.tsx +27 -0
  252. package/src/components/Measurements/Screens/MeasurementCategoryDetail.test.tsx +67 -0
  253. package/src/components/Measurements/Screens/MeasurementCategoryDetail.tsx +37 -0
  254. package/src/components/Measurements/Screens/MeasurementCategoryOverview.test.tsx +59 -0
  255. package/src/components/Measurements/Screens/MeasurementCategoryOverview.tsx +64 -0
  256. package/src/components/Measurements/models/Category.ts +38 -0
  257. package/src/components/Measurements/models/Entry.ts +37 -0
  258. package/src/components/Measurements/queries/index.ts +121 -0
  259. package/src/components/Measurements/widgets/CategoryDetailDataGrid.tsx +209 -0
  260. package/src/components/Measurements/widgets/CategoryDetailDropdown.tsx +83 -0
  261. package/src/components/Measurements/widgets/CategoryForm.test.tsx +96 -0
  262. package/src/components/Measurements/widgets/CategoryForm.tsx +88 -0
  263. package/src/components/Measurements/widgets/EntryForm.test.tsx +120 -0
  264. package/src/components/Measurements/widgets/EntryForm.tsx +139 -0
  265. package/src/components/Measurements/widgets/MeasurementChart.tsx +52 -0
  266. package/src/components/Measurements/widgets/fab.tsx +65 -0
  267. package/src/components/Muscles/MuscleOverview.tsx +37 -0
  268. package/src/components/Nutrition/components/BmiCalculator.test.tsx +55 -0
  269. package/src/components/Nutrition/components/BmiCalculator.tsx +203 -0
  270. package/src/components/Nutrition/components/IngredientSearch.tsx +24 -0
  271. package/src/components/Nutrition/components/NutritionDiaryOverview.test.tsx +51 -0
  272. package/src/components/Nutrition/components/NutritionDiaryOverview.tsx +47 -0
  273. package/src/components/Nutrition/components/PlanDetail.test.tsx +58 -0
  274. package/src/components/Nutrition/components/PlanDetail.tsx +100 -0
  275. package/src/components/Nutrition/components/PlanOverview.test.tsx +37 -0
  276. package/src/components/Nutrition/components/PlansOverview.tsx +62 -0
  277. package/src/components/Nutrition/helpers/nutritionalValues.test.ts +108 -0
  278. package/src/components/Nutrition/helpers/nutritionalValues.ts +128 -0
  279. package/src/components/Nutrition/models/Ingredient.ts +84 -0
  280. package/src/components/Nutrition/models/IngredientImage.ts +57 -0
  281. package/src/components/Nutrition/models/IngredientImageThumbnails.ts +59 -0
  282. package/src/components/Nutrition/models/diaryEntry.ts +129 -0
  283. package/src/components/Nutrition/models/ingredient.test.ts +37 -0
  284. package/src/components/Nutrition/models/meal.test.ts +54 -0
  285. package/src/components/Nutrition/models/meal.ts +128 -0
  286. package/src/components/Nutrition/models/mealItem.test.ts +23 -0
  287. package/src/components/Nutrition/models/mealItem.ts +134 -0
  288. package/src/components/Nutrition/models/nutritionalPlan.test.ts +169 -0
  289. package/src/components/Nutrition/models/nutritionalPlan.ts +268 -0
  290. package/src/components/Nutrition/models/weightUnit.ts +24 -0
  291. package/src/components/Nutrition/queries/diary.ts +59 -0
  292. package/src/components/Nutrition/queries/index.ts +20 -0
  293. package/src/components/Nutrition/queries/ingredient.ts +12 -0
  294. package/src/components/Nutrition/queries/meal.ts +41 -0
  295. package/src/components/Nutrition/queries/mealItem.ts +43 -0
  296. package/src/components/Nutrition/queries/plan.ts +93 -0
  297. package/src/components/Nutrition/widgets/DiaryDetail.tsx +39 -0
  298. package/src/components/Nutrition/widgets/DiaryOverview.tsx +51 -0
  299. package/src/components/Nutrition/widgets/Fab.tsx +65 -0
  300. package/src/components/Nutrition/widgets/IngredientAutcompleter.tsx +140 -0
  301. package/src/components/Nutrition/widgets/IngredientAutocompleter.test.tsx +60 -0
  302. package/src/components/Nutrition/widgets/IngredientDetailTable.tsx +91 -0
  303. package/src/components/Nutrition/widgets/LoggedPlannedNutritionalValuesTable.tsx +138 -0
  304. package/src/components/Nutrition/widgets/MealDetail.tsx +170 -0
  305. package/src/components/Nutrition/widgets/MealDetailDropdown.tsx +117 -0
  306. package/src/components/Nutrition/widgets/NutritionalValuesTable.tsx +103 -0
  307. package/src/components/Nutrition/widgets/PlanDetailDropdown.tsx +82 -0
  308. package/src/components/Nutrition/widgets/PlanSidebar.tsx +44 -0
  309. package/src/components/Nutrition/widgets/charts/LinearPlannedLoggedChart.tsx +27 -0
  310. package/src/components/Nutrition/widgets/charts/MacrosPieChart.tsx +66 -0
  311. package/src/components/Nutrition/widgets/charts/NutritionDiaryChart.tsx +95 -0
  312. package/src/components/Nutrition/widgets/charts/NutritionalValuesDashboardChart.tsx +84 -0
  313. package/src/components/Nutrition/widgets/charts/NutritionalValuesPlannedLoggedChart.tsx +54 -0
  314. package/src/components/Nutrition/widgets/forms/MealForm.test.tsx +85 -0
  315. package/src/components/Nutrition/widgets/forms/MealForm.tsx +105 -0
  316. package/src/components/Nutrition/widgets/forms/MealItemForm.test.tsx +106 -0
  317. package/src/components/Nutrition/widgets/forms/MealItemForm.tsx +118 -0
  318. package/src/components/Nutrition/widgets/forms/NutritionDiaryEntryForm.test.tsx +165 -0
  319. package/src/components/Nutrition/widgets/forms/NutritionDiaryEntryForm.tsx +161 -0
  320. package/src/components/Nutrition/widgets/forms/PlanForm.test.tsx +101 -0
  321. package/src/components/Nutrition/widgets/forms/PlanForm.tsx +361 -0
  322. package/src/components/User/models/profile.ts +81 -0
  323. package/src/components/User/queries/contribute.test.ts +132 -0
  324. package/src/components/User/queries/contribute.ts +33 -0
  325. package/src/components/User/queries/permission.ts +11 -0
  326. package/src/components/User/queries/profile.ts +22 -0
  327. package/src/components/WorkoutRoutines/Detail/RoutineAdd.tsx +12 -0
  328. package/src/components/WorkoutRoutines/Detail/RoutineDetail.test.tsx +71 -0
  329. package/src/components/WorkoutRoutines/Detail/RoutineDetail.tsx +87 -0
  330. package/src/components/WorkoutRoutines/Detail/RoutineDetailsTable.test.tsx +83 -0
  331. package/src/components/WorkoutRoutines/Detail/RoutineDetailsTable.tsx +371 -0
  332. package/src/components/WorkoutRoutines/Detail/RoutineEdit.test.tsx +51 -0
  333. package/src/components/WorkoutRoutines/Detail/RoutineEdit.tsx +95 -0
  334. package/src/components/WorkoutRoutines/Detail/SessionAdd.test.tsx +43 -0
  335. package/src/components/WorkoutRoutines/Detail/SessionAdd.tsx +50 -0
  336. package/src/components/WorkoutRoutines/Detail/SlotProgressionEdit.test.tsx +41 -0
  337. package/src/components/WorkoutRoutines/Detail/SlotProgressionEdit.tsx +145 -0
  338. package/src/components/WorkoutRoutines/Detail/TemplateDetail.test.tsx +44 -0
  339. package/src/components/WorkoutRoutines/Detail/TemplateDetail.tsx +84 -0
  340. package/src/components/WorkoutRoutines/Detail/WorkoutLogs.test.tsx +64 -0
  341. package/src/components/WorkoutRoutines/Detail/WorkoutLogs.tsx +98 -0
  342. package/src/components/WorkoutRoutines/Detail/WorkoutStats.test.tsx +65 -0
  343. package/src/components/WorkoutRoutines/Detail/WorkoutStats.tsx +244 -0
  344. package/src/components/WorkoutRoutines/Overview/Fab.tsx +91 -0
  345. package/src/components/WorkoutRoutines/Overview/PrivateTemplateOverview.test.tsx +36 -0
  346. package/src/components/WorkoutRoutines/Overview/PrivateTemplateOverview.tsx +41 -0
  347. package/src/components/WorkoutRoutines/Overview/PublicTemplateOverview.test.tsx +36 -0
  348. package/src/components/WorkoutRoutines/Overview/PublicTemplateOverview.tsx +40 -0
  349. package/src/components/WorkoutRoutines/Overview/RoutineOverview.test.tsx +38 -0
  350. package/src/components/WorkoutRoutines/Overview/RoutineOverview.tsx +76 -0
  351. package/src/components/WorkoutRoutines/models/BaseConfig.ts +118 -0
  352. package/src/components/WorkoutRoutines/models/Day.test.ts +15 -0
  353. package/src/components/WorkoutRoutines/models/Day.ts +117 -0
  354. package/src/components/WorkoutRoutines/models/LogStats.test.ts +44 -0
  355. package/src/components/WorkoutRoutines/models/LogStats.ts +110 -0
  356. package/src/components/WorkoutRoutines/models/RepetitionUnit.ts +22 -0
  357. package/src/components/WorkoutRoutines/models/Routine.test.ts +113 -0
  358. package/src/components/WorkoutRoutines/models/Routine.ts +218 -0
  359. package/src/components/WorkoutRoutines/models/RoutineDayData.ts +38 -0
  360. package/src/components/WorkoutRoutines/models/RoutineLogData.ts +22 -0
  361. package/src/components/WorkoutRoutines/models/SetConfigData.ts +121 -0
  362. package/src/components/WorkoutRoutines/models/Slot.test.ts +19 -0
  363. package/src/components/WorkoutRoutines/models/Slot.ts +83 -0
  364. package/src/components/WorkoutRoutines/models/SlotData.ts +30 -0
  365. package/src/components/WorkoutRoutines/models/SlotEntry.test.ts +31 -0
  366. package/src/components/WorkoutRoutines/models/SlotEntry.ts +245 -0
  367. package/src/components/WorkoutRoutines/models/WeightUnit.ts +22 -0
  368. package/src/components/WorkoutRoutines/models/WorkoutLog.ts +159 -0
  369. package/src/components/WorkoutRoutines/models/WorkoutSession.ts +124 -0
  370. package/src/components/WorkoutRoutines/queries/configs.ts +393 -0
  371. package/src/components/WorkoutRoutines/queries/days.ts +42 -0
  372. package/src/components/WorkoutRoutines/queries/index.ts +64 -0
  373. package/src/components/WorkoutRoutines/queries/logs.ts +49 -0
  374. package/src/components/WorkoutRoutines/queries/routines.ts +121 -0
  375. package/src/components/WorkoutRoutines/queries/sessions.ts +41 -0
  376. package/src/components/WorkoutRoutines/queries/slot_entries.ts +33 -0
  377. package/src/components/WorkoutRoutines/queries/slots.ts +40 -0
  378. package/src/components/WorkoutRoutines/queries/units.ts +15 -0
  379. package/src/components/WorkoutRoutines/widgets/DayDetails.test.tsx +69 -0
  380. package/src/components/WorkoutRoutines/widgets/DayDetails.tsx +441 -0
  381. package/src/components/WorkoutRoutines/widgets/LogWidgets.test.tsx +91 -0
  382. package/src/components/WorkoutRoutines/widgets/LogWidgets.tsx +334 -0
  383. package/src/components/WorkoutRoutines/widgets/RoutineDetailDropdown.test.tsx +36 -0
  384. package/src/components/WorkoutRoutines/widgets/RoutineDetailDropdown.tsx +184 -0
  385. package/src/components/WorkoutRoutines/widgets/RoutineDetailsCard.test.tsx +42 -0
  386. package/src/components/WorkoutRoutines/widgets/RoutineDetailsCard.tsx +202 -0
  387. package/src/components/WorkoutRoutines/widgets/RoutineStatistics.test.tsx +364 -0
  388. package/src/components/WorkoutRoutines/widgets/RoutineStatistics.tsx +249 -0
  389. package/src/components/WorkoutRoutines/widgets/SlotDetails.test.tsx +72 -0
  390. package/src/components/WorkoutRoutines/widgets/SlotDetails.tsx +233 -0
  391. package/src/components/WorkoutRoutines/widgets/forms/BaseConfigForm.test.tsx +161 -0
  392. package/src/components/WorkoutRoutines/widgets/forms/BaseConfigForm.tsx +508 -0
  393. package/src/components/WorkoutRoutines/widgets/forms/DayForm.test.tsx +86 -0
  394. package/src/components/WorkoutRoutines/widgets/forms/DayForm.tsx +202 -0
  395. package/src/components/WorkoutRoutines/widgets/forms/ProgressionForm.test.tsx +176 -0
  396. package/src/components/WorkoutRoutines/widgets/forms/ProgressionForm.tsx +494 -0
  397. package/src/components/WorkoutRoutines/widgets/forms/RoutineForm.test.tsx +94 -0
  398. package/src/components/WorkoutRoutines/widgets/forms/RoutineForm.tsx +309 -0
  399. package/src/components/WorkoutRoutines/widgets/forms/RoutineTemplateForm.test.tsx +70 -0
  400. package/src/components/WorkoutRoutines/widgets/forms/RoutineTemplateForm.tsx +68 -0
  401. package/src/components/WorkoutRoutines/widgets/forms/SessionForm.test.tsx +164 -0
  402. package/src/components/WorkoutRoutines/widgets/forms/SessionForm.tsx +263 -0
  403. package/src/components/WorkoutRoutines/widgets/forms/SessionLogsForm.test.tsx +126 -0
  404. package/src/components/WorkoutRoutines/widgets/forms/SessionLogsForm.tsx +330 -0
  405. package/src/components/WorkoutRoutines/widgets/forms/SlotEntryForm.test.tsx +227 -0
  406. package/src/components/WorkoutRoutines/widgets/forms/SlotEntryForm.tsx +206 -0
  407. package/src/components/WorkoutRoutines/widgets/forms/SlotForm.test.tsx +44 -0
  408. package/src/components/WorkoutRoutines/widgets/forms/SlotForm.tsx +36 -0
  409. package/src/components/index.ts +3 -0
  410. package/src/config.ts +12 -0
  411. package/src/i18n.ts +63 -0
  412. package/src/i18n.tsx +52 -0
  413. package/src/index.css +13 -0
  414. package/src/index.tsx +184 -0
  415. package/src/locales/README.md +7 -0
  416. package/src/pages/About/index.tsx +9 -0
  417. package/src/pages/AddExercise/index.tsx +15 -0
  418. package/src/pages/AddWeight/index.tsx +9 -0
  419. package/src/pages/ApiPage/index.tsx +9 -0
  420. package/src/pages/Calendar/index.tsx +10 -0
  421. package/src/pages/CaloriesCalculator/index.tsx +9 -0
  422. package/src/pages/Equipments/index.tsx +9 -0
  423. package/src/pages/ExerciseDetails/index.tsx +6 -0
  424. package/src/pages/Ingrdedients/index.tsx +9 -0
  425. package/src/pages/Login/index.tsx +9 -0
  426. package/src/pages/Preferences/index.tsx +9 -0
  427. package/src/pages/PublicTemplate/index.tsx +9 -0
  428. package/src/pages/TemplatePage/index.tsx +9 -0
  429. package/src/pages/WeightOverview/index.tsx +6 -0
  430. package/src/pages/index.ts +14 -0
  431. package/src/permissions/index.ts +13 -0
  432. package/src/reportWebVitals.ts +15 -0
  433. package/src/routes.tsx +137 -0
  434. package/src/services/alias.test.ts +47 -0
  435. package/src/services/alias.ts +34 -0
  436. package/src/services/base_config.test.ts +48 -0
  437. package/src/services/base_config.ts +86 -0
  438. package/src/services/category.test.ts +44 -0
  439. package/src/services/category.ts +21 -0
  440. package/src/services/config.test.ts +213 -0
  441. package/src/services/config.ts +50 -0
  442. package/src/services/day.test.ts +118 -0
  443. package/src/services/day.ts +44 -0
  444. package/src/services/equipment.test.ts +46 -0
  445. package/src/services/equipment.ts +20 -0
  446. package/src/services/exercise.test.ts +98 -0
  447. package/src/services/exercise.ts +182 -0
  448. package/src/services/exerciseTranslation.test.ts +98 -0
  449. package/src/services/exerciseTranslation.ts +112 -0
  450. package/src/services/image.test.ts +77 -0
  451. package/src/services/image.ts +54 -0
  452. package/src/services/index.ts +104 -0
  453. package/src/services/ingredient.test.ts +81 -0
  454. package/src/services/ingredient.ts +70 -0
  455. package/src/services/ingredientweightunit.ts +29 -0
  456. package/src/services/language.test.ts +86 -0
  457. package/src/services/language.ts +35 -0
  458. package/src/services/languageCheck.ts +33 -0
  459. package/src/services/meal.ts +67 -0
  460. package/src/services/mealItem.ts +32 -0
  461. package/src/services/measurements.test.ts +106 -0
  462. package/src/services/measurements.ts +173 -0
  463. package/src/services/muscles.test.ts +46 -0
  464. package/src/services/muscles.ts +20 -0
  465. package/src/services/note.ts +39 -0
  466. package/src/services/nutritionalDiary.test.ts +35 -0
  467. package/src/services/nutritionalDiary.ts +70 -0
  468. package/src/services/nutritionalPlan.test.ts +74 -0
  469. package/src/services/nutritionalPlan.ts +104 -0
  470. package/src/services/permission.ts +26 -0
  471. package/src/services/permissions.test.ts +34 -0
  472. package/src/services/profile.test.ts +40 -0
  473. package/src/services/profile.ts +49 -0
  474. package/src/services/responseType.ts +35 -0
  475. package/src/services/routine.test.ts +195 -0
  476. package/src/services/routine.ts +250 -0
  477. package/src/services/session.test.ts +157 -0
  478. package/src/services/session.ts +99 -0
  479. package/src/services/slot.test.ts +68 -0
  480. package/src/services/slot.ts +43 -0
  481. package/src/services/slot_entry.ts +43 -0
  482. package/src/services/variation.test.ts +24 -0
  483. package/src/services/variation.ts +18 -0
  484. package/src/services/video.test.ts +65 -0
  485. package/src/services/video.ts +47 -0
  486. package/src/services/weight.test.ts +75 -0
  487. package/src/services/weight.ts +58 -0
  488. package/src/services/workoutLogs.test.ts +148 -0
  489. package/src/services/workoutLogs.ts +89 -0
  490. package/src/services/workoutUnits.ts +29 -0
  491. package/src/setupTests.ts +40 -0
  492. package/src/state/exerciseSubmissionReducer.ts +170 -0
  493. package/src/state/exerciseSubmissionState.tsx +75 -0
  494. package/src/state/index.ts +15 -0
  495. package/src/state/notificationReducer.ts +29 -0
  496. package/src/state/notificationState.tsx +32 -0
  497. package/src/state/stateTypes.ts +24 -0
  498. package/src/tests/api/ingredientInfoEndpoint.ts +72 -0
  499. package/src/tests/exerciseTestdata.ts +159 -0
  500. package/src/tests/exercises/searchResponse.ts +23 -0
  501. package/src/tests/ingredientTestdata.ts +76 -0
  502. package/src/tests/measurementsTestData.ts +40 -0
  503. package/src/tests/nutritionDiaryTestdata.ts +167 -0
  504. package/src/tests/nutritionTestdata.ts +200 -0
  505. package/src/tests/queryClient/index.ts +7 -0
  506. package/src/tests/responseApi.ts +197 -0
  507. package/src/tests/setup.ts +10 -0
  508. package/src/tests/slotEntryApiResponse.ts +144 -0
  509. package/src/tests/userTestdata.ts +43 -0
  510. package/src/tests/weight/testData.ts +7 -0
  511. package/src/tests/workoutLogsRoutinesTestData.ts +90 -0
  512. package/src/tests/workoutRoutinesTestData.ts +451 -0
  513. package/src/tests/workoutStatisticsTestData.ts +219 -0
  514. package/src/theme.ts +73 -0
  515. package/src/types.ts +144 -0
  516. package/src/utils/Adapter.ts +10 -0
  517. package/src/utils/colors.test.ts +38 -0
  518. package/src/utils/colors.ts +17 -0
  519. package/src/utils/consts.ts +160 -0
  520. package/src/utils/date.test.ts +56 -0
  521. package/src/utils/date.ts +145 -0
  522. package/src/utils/forms.test.ts +41 -0
  523. package/src/utils/forms.ts +54 -0
  524. package/src/utils/numbers.test.ts +55 -0
  525. package/src/utils/numbers.ts +42 -0
  526. package/src/utils/requests.test.ts +61 -0
  527. package/src/utils/requests.ts +22 -0
  528. package/src/utils/strings.test.ts +62 -0
  529. package/src/utils/strings.ts +28 -0
  530. package/src/utils/url.test.ts +127 -0
  531. package/src/utils/url.ts +237 -0
package/package.json ADDED
@@ -0,0 +1,125 @@
1
+ {
2
+ "name": "@wger-project/react-components",
3
+ "files": [
4
+ "README.md",
5
+ "LICENSE",
6
+ "index.html",
7
+ "src/",
8
+ "build/"
9
+ ],
10
+ "main": "build/main.js",
11
+ "exports": {
12
+ ".": "./build/index.js"
13
+ },
14
+ "version": "25.10.16",
15
+ "repository": "https://github.com/wger-project/react",
16
+ "type": "module",
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "dependencies": {
21
+ "@emotion/babel-plugin": "^11.13.5",
22
+ "@emotion/react": "^11.14.0",
23
+ "@emotion/styled": "^11.14.1",
24
+ "@hello-pangea/dnd": "^18.0.1",
25
+ "@mui/icons-material": "^7.3.4",
26
+ "@mui/lab": "^7.0.1-beta.18",
27
+ "@mui/material": "^7.3.4",
28
+ "@mui/system": "^7.3.3",
29
+ "@mui/x-data-grid": "^8.14.0",
30
+ "@mui/x-date-pickers": "^8.14.0",
31
+ "@tanstack/react-query": "^5.90.2",
32
+ "@vitejs/plugin-react": "^5.0.4",
33
+ "axios": "^1.12.2",
34
+ "formik": "^2.4.6",
35
+ "history": "^5.3.0",
36
+ "i18next": "^25.6.0",
37
+ "i18next-browser-languagedetector": "^8.2.0",
38
+ "i18next-http-backend": "^3.0.2",
39
+ "luxon": "^3.7.2",
40
+ "react": "^19.2.0",
41
+ "react-dom": "^19.2.0",
42
+ "react-i18next": "^16.0.0",
43
+ "react-is": "^19.2.0",
44
+ "react-responsive": "^10.0.1",
45
+ "react-router-dom": "^7.9.4",
46
+ "react-simple-wysiwyg": "^3.4.1",
47
+ "recharts": "^3.2.1",
48
+ "slug": "^9.1.0",
49
+ "typescript": "^5.9.3",
50
+ "vite-tsconfig-paths": "^5.1.4",
51
+ "web-vitals": "^5.1.0",
52
+ "yup": "^1.7.1"
53
+ },
54
+ "devDependencies": {
55
+ "@eslint/js": "^9.37.0",
56
+ "@tanstack/react-query-devtools": "^5.90.2",
57
+ "@testing-library/dom": "^10.4.1",
58
+ "@testing-library/jest-dom": "^6.9.1",
59
+ "@testing-library/react": "^16.3.0",
60
+ "@testing-library/user-event": "^14.6.1",
61
+ "@types/jest": "^30.0.0",
62
+ "@types/lodash": "^4.17.20",
63
+ "@types/luxon": "^3.7.1",
64
+ "@types/node": "^22.18.9",
65
+ "@types/react": "^19.2.2",
66
+ "@types/react-dom": "^19.2.1",
67
+ "@types/react-is": "^19.2.0",
68
+ "@types/slug": "^5.0.9",
69
+ "@typescript-eslint/eslint-plugin": "^8.46.0",
70
+ "@typescript-eslint/parser": "^8.46.0",
71
+ "eslint": "^9.37.0",
72
+ "eslint-plugin-import": "^2.32.0",
73
+ "eslint-plugin-jsx-a11y": "^6.10.2",
74
+ "eslint-plugin-react": "^7.37.5",
75
+ "eslint-plugin-react-hooks": "^7.0.0",
76
+ "i18next-parser": "^9.3.0",
77
+ "jest": "^30.2.0",
78
+ "jest-environment-jsdom": "^30.2.0",
79
+ "jsdom": "^27.0.0",
80
+ "ts-jest": "^29.4.5",
81
+ "typescript-eslint": "^8.46.0",
82
+ "vite": "^7.1.9",
83
+ "vite-plugin-eslint": "^1.8.1",
84
+ "vitest": "^3.2.4"
85
+ },
86
+ "scripts": {
87
+ "start": "vite",
88
+ "build": "vite build",
89
+ "serve": "vite preview",
90
+ "test": "LANG=de_de jest",
91
+ "test:coverage": "LANG=de_de jest --coverage --collectCoverageFrom='!src/pages/**/*.tsx'",
92
+ "i18n": "i18next",
93
+ "lint": "eslint src",
94
+ "lint:quiet": "eslint --quiet src",
95
+ "lint:fix": "eslint --fix src"
96
+ },
97
+ "browserslist": {
98
+ "production": [
99
+ ">0.2%",
100
+ "not dead",
101
+ "not op_mini all"
102
+ ],
103
+ "development": [
104
+ "last 1 chrome version",
105
+ "last 1 firefox version",
106
+ "last 1 safari version"
107
+ ]
108
+ },
109
+ "jest": {
110
+ "moduleNameMapper": {
111
+ "^axios$": "<rootDir>/node_modules/axios/dist/node/axios.cjs",
112
+ "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
113
+ "\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js"
114
+ },
115
+ "preset": "ts-jest",
116
+ "testEnvironment": "jest-environment-jsdom",
117
+ "modulePaths": [
118
+ "<rootDir>/src"
119
+ ],
120
+ "setupFilesAfterEnv": [
121
+ "./src/setupTests.ts"
122
+ ]
123
+ },
124
+ "packageManager": "npm@10.5.0"
125
+ }
@@ -0,0 +1,13 @@
1
+ import "i18next";
2
+ import { resources } from "i18n";
3
+
4
+ declare module "i18next" {
5
+
6
+ // Extend CustomTypeOptions
7
+ interface CustomTypeOptions {
8
+ defaultNS: "common";
9
+ resources: {
10
+ common: typeof resources.en.common;
11
+ };
12
+ }
13
+ }
package/src/App.tsx ADDED
@@ -0,0 +1,25 @@
1
+ import Grid from '@mui/material/Grid';
2
+ import { Header, } from 'components';
3
+ import { Notifications } from 'components/Core/Notifications';
4
+ import React from 'react';
5
+ import { WgerRoutes } from "routes";
6
+
7
+
8
+ function App() {
9
+
10
+ return (
11
+ (<Grid container>
12
+ <Grid size={12}>
13
+ <Header />
14
+ </Grid>
15
+ <Grid size={12}>
16
+ <Notifications />
17
+ </Grid>
18
+ <Grid size={12}>
19
+ <WgerRoutes />
20
+ </Grid>
21
+ </Grid>)
22
+ );
23
+ }
24
+
25
+ export default App;
@@ -0,0 +1 @@
1
+ <svg fill="#fff" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="50px" height="50px"><path d="M 18.90625 7 C 18.90625 7 12.539063 7.4375 8.375 10.78125 C 8.355469 10.789063 8.332031 10.800781 8.3125 10.8125 C 7.589844 11.480469 7.046875 12.515625 6.375 14 C 5.703125 15.484375 4.992188 17.394531 4.34375 19.53125 C 3.050781 23.808594 2 29.058594 2 34 C 1.996094 34.175781 2.039063 34.347656 2.125 34.5 C 3.585938 37.066406 6.273438 38.617188 8.78125 39.59375 C 11.289063 40.570313 13.605469 40.960938 14.78125 41 C 15.113281 41.011719 15.429688 40.859375 15.625 40.59375 L 18.0625 37.21875 C 20.027344 37.683594 22.332031 38 25 38 C 27.667969 38 29.972656 37.683594 31.9375 37.21875 L 34.375 40.59375 C 34.570313 40.859375 34.886719 41.011719 35.21875 41 C 36.394531 40.960938 38.710938 40.570313 41.21875 39.59375 C 43.726563 38.617188 46.414063 37.066406 47.875 34.5 C 47.960938 34.347656 48.003906 34.175781 48 34 C 48 29.058594 46.949219 23.808594 45.65625 19.53125 C 45.007813 17.394531 44.296875 15.484375 43.625 14 C 42.953125 12.515625 42.410156 11.480469 41.6875 10.8125 C 41.667969 10.800781 41.644531 10.789063 41.625 10.78125 C 37.460938 7.4375 31.09375 7 31.09375 7 C 31.019531 6.992188 30.949219 6.992188 30.875 7 C 30.527344 7.046875 30.234375 7.273438 30.09375 7.59375 C 30.09375 7.59375 29.753906 8.339844 29.53125 9.40625 C 27.582031 9.09375 25.941406 9 25 9 C 24.058594 9 22.417969 9.09375 20.46875 9.40625 C 20.246094 8.339844 19.90625 7.59375 19.90625 7.59375 C 19.734375 7.203125 19.332031 6.964844 18.90625 7 Z M 18.28125 9.15625 C 18.355469 9.359375 18.40625 9.550781 18.46875 9.78125 C 16.214844 10.304688 13.746094 11.160156 11.4375 12.59375 C 11.074219 12.746094 10.835938 13.097656 10.824219 13.492188 C 10.816406 13.882813 11.039063 14.246094 11.390625 14.417969 C 11.746094 14.585938 12.167969 14.535156 12.46875 14.28125 C 17.101563 11.410156 22.996094 11 25 11 C 27.003906 11 32.898438 11.410156 37.53125 14.28125 C 37.832031 14.535156 38.253906 14.585938 38.609375 14.417969 C 38.960938 14.246094 39.183594 13.882813 39.175781 13.492188 C 39.164063 13.097656 38.925781 12.746094 38.5625 12.59375 C 36.253906 11.160156 33.785156 10.304688 31.53125 9.78125 C 31.59375 9.550781 31.644531 9.359375 31.71875 9.15625 C 32.859375 9.296875 37.292969 9.894531 40.3125 12.28125 C 40.507813 12.460938 41.1875 13.460938 41.8125 14.84375 C 42.4375 16.226563 43.09375 18.027344 43.71875 20.09375 C 44.9375 24.125 45.921875 29.097656 45.96875 33.65625 C 44.832031 35.496094 42.699219 36.863281 40.5 37.71875 C 38.5 38.496094 36.632813 38.84375 35.65625 38.9375 L 33.96875 36.65625 C 34.828125 36.378906 35.601563 36.078125 36.28125 35.78125 C 38.804688 34.671875 40.15625 33.5 40.15625 33.5 C 40.570313 33.128906 40.605469 32.492188 40.234375 32.078125 C 39.863281 31.664063 39.226563 31.628906 38.8125 32 C 38.8125 32 37.765625 32.957031 35.46875 33.96875 C 34.625 34.339844 33.601563 34.707031 32.4375 35.03125 C 32.167969 35 31.898438 35.078125 31.6875 35.25 C 29.824219 35.703125 27.609375 36 25 36 C 22.371094 36 20.152344 35.675781 18.28125 35.21875 C 18.070313 35.078125 17.8125 35.019531 17.5625 35.0625 C 16.394531 34.738281 15.378906 34.339844 14.53125 33.96875 C 12.234375 32.957031 11.1875 32 11.1875 32 C 10.960938 31.789063 10.648438 31.699219 10.34375 31.75 C 9.957031 31.808594 9.636719 32.085938 9.53125 32.464844 C 9.421875 32.839844 9.546875 33.246094 9.84375 33.5 C 9.84375 33.5 11.195313 34.671875 13.71875 35.78125 C 14.398438 36.078125 15.171875 36.378906 16.03125 36.65625 L 14.34375 38.9375 C 13.367188 38.84375 11.5 38.496094 9.5 37.71875 C 7.300781 36.863281 5.167969 35.496094 4.03125 33.65625 C 4.078125 29.097656 5.0625 24.125 6.28125 20.09375 C 6.90625 18.027344 7.5625 16.226563 8.1875 14.84375 C 8.8125 13.460938 9.492188 12.460938 9.6875 12.28125 C 12.707031 9.894531 17.140625 9.296875 18.28125 9.15625 Z M 18.5 21 C 15.949219 21 14 23.316406 14 26 C 14 28.683594 15.949219 31 18.5 31 C 21.050781 31 23 28.683594 23 26 C 23 23.316406 21.050781 21 18.5 21 Z M 31.5 21 C 28.949219 21 27 23.316406 27 26 C 27 28.683594 28.949219 31 31.5 31 C 34.050781 31 36 28.683594 36 26 C 36 23.316406 34.050781 21 31.5 21 Z M 18.5 23 C 19.816406 23 21 24.265625 21 26 C 21 27.734375 19.816406 29 18.5 29 C 17.183594 29 16 27.734375 16 26 C 16 24.265625 17.183594 23 18.5 23 Z M 31.5 23 C 32.816406 23 34 24.265625 34 26 C 34 27.734375 32.816406 29 31.5 29 C 30.183594 29 29 27.734375 29 26 C 29 24.265625 30.183594 23 31.5 23 Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1477 500" enable-background="new 0 0 1477 500" width="2500" height="846"><style>.st0{fill:#fff}.st1{fill:url(#orange_1_)}.st2{fill:url(#path-3_2_)}.st3{filter:url(#Adobe_OpacityMaskFilter)}.st4{mask:url(#mask-4);fill:none}.st5{filter:url(#Adobe_OpacityMaskFilter_1_)}.st6{mask:url(#mask-6);fill:url(#Fill-7_3_)}.st7{fill:url(#path-9_2_)}.st8{filter:url(#Adobe_OpacityMaskFilter_2_)}.st9{mask:url(#mask-10);fill:none}</style><title>Google</title><g id="Page-1"><g id="Artboard-1" transform="translate(-461 -270)"><g id="Play-Store" transform="translate(461 270)"><path id="background" class="st0" d="M60 0h1357c33.1 0 60 26.9 60 60v380c0 33.1-26.9 60-60 60H60c-33.1 0-60-26.9-60-60V60C0 26.9 26.9 0 60 0z"/><g id="icon" transform="translate(60 179)"><linearGradient id="orange_1_" gradientUnits="userSpaceOnUse" x1="-70.717" y1="570.714" x2="-70.398" y2="570.201" gradientTransform="matrix(234.0913 0 0 -256.5288 16609.81 146485.188)"><stop offset="0" stop-color="#ff177b"/><stop offset="1" stop-color="#ffec73"/></linearGradient><path id="orange" class="st1" d="M120.2 61S18.3 4.5 12.3 1.2C6.3-2.1.3-.1.3 6.8v243.5c0 5.2 4.3 7.4 9.5 4.6 5.2-2.9 110.4-61.2 110.4-61.2s14.3-7.9 21.4-11.9c11.5-6.4 34.5-19.1 34.5-19.1s47.5-26.3 53.8-29.8c6.3-3.5 5.7-8.3.4-11-5.3-2.7-54.1-30-54.1-30l-56-30.9z"/><g id="blue"><g id="Clip-2"><linearGradient id="path-3_2_" gradientUnits="userSpaceOnUse" x1="-70.261" y1="571.394" x2="-70.632" y2="569.943" gradientTransform="matrix(139 0 0 -256 9858 146183)"><stop offset="0" stop-color="#064aa2"/><stop offset="1" stop-color="#63ffd4"/></linearGradient><path id="path-3_1_" class="st2" d="M139 127L5 0C1.9.7 0 3.1 0 7v243c0 3.3 1.3 5.3 3 6l136-129z"/></g><defs><filter id="Adobe_OpacityMaskFilter" filterUnits="userSpaceOnUse" x="0" y=".1" width="234" height="257"><feColorMatrix values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/></filter></defs><mask maskUnits="userSpaceOnUse" x="0" y=".1" width="234" height="257" id="mask-4"><g class="st3"><path id="path-3" class="st0" d="M139 127L5 0C1.9.7 0 3.1 0 7v243c0 3.3 1.3 5.3 3 6l136-129z"/></g></mask><path id="Fill-1" class="st4" d="M176 92l-56-31c-.2.5-102.1-56.1-108-59C6-1.8 0 .3 0 7v244c0 5.4 4.3 7.6 9 5 5.7-3.2 110.8-61.5 111-62l56-31c-.3.4 47.1-25.9 53-29 6.8-3.9 6.1-8.7 1-11-5.5-3.2-54.3-30.5-54-31"/></g><g id="red" transform="translate(2.983 127.504)"><defs><filter id="Adobe_OpacityMaskFilter_1_" filterUnits="userSpaceOnUse" x="-3" y="-127.4" width="234" height="257"><feColorMatrix values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/></filter></defs><mask maskUnits="userSpaceOnUse" x="-3" y="-127.4" width="234" height="257" id="mask-6"><g class="st5"><path id="path-5" class="st0" d="M5.5 127.8L83 85.2c19.1-10.6 34.2-19 34.2-19l56.3-30.3L136-.5 0 128.5c1.5.5 4.2.2 6.3-.8"/></g></mask><linearGradient id="Fill-7_3_" gradientUnits="userSpaceOnUse" x1="-73.347" y1="443.327" x2="-74.108" y2="442.827" gradientTransform="matrix(233.965 0 0 -256.9642 17295.543 113843.219)"><stop offset="0" stop-color="#ff4521"/><stop offset="1" stop-color="#8a33db"/></linearGradient><path id="Fill-7" class="st6" d="M117-66.5c-.2.5-102.1-56.1-108-59-6-3.8-12-1.7-12 5v244c0 5.4 4.3 7.6 9 5 5.7-3.2 110.8-61.5 111-62l56-31c-.3.4 47.1-25.9 53-29 6.8-3.9 6.1-8.7 1-11-5.5-3.2-54.3-30.5-54-31l-56-31z"/></g><g id="green" transform="translate(4.98)"><g id="Clip-5"><linearGradient id="path-9_2_" gradientUnits="userSpaceOnUse" x1="-75.767" y1="570.364" x2="-75.125" y2="569.122" gradientTransform="matrix(171.2139 0 0 -127.4293 12997.62 72640.227)"><stop offset="0" stop-color="#00a3b5"/><stop offset="1" stop-color="#d6ffa1"/></linearGradient><path id="path-9_1_" class="st7" d="M7.1 1.1C4.5-.2 2-.6-.1-.1L134 127.1 171.1 92l-55.9-31S62.5 31.8 30.7 14.2L7.1 1.1z"/></g><defs><filter id="Adobe_OpacityMaskFilter_2_" filterUnits="userSpaceOnUse" x="-5" y=".1" width="234" height="257"><feColorMatrix values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/></filter></defs><mask maskUnits="userSpaceOnUse" x="-5" y=".1" width="234" height="257" id="mask-10"><g class="st8"><path id="path-9" class="st0" d="M7.1 1.1C4.5-.2 2-.6-.1-.1L134 127.1 171.1 92l-55.9-31S62.5 31.8 30.7 14.2L7.1 1.1z"/></g></mask><path id="Fill-4" class="st9" d="M171 92l-56-31c-.2.5-102-56.1-108-59C1-1.8-5 .3-5 7v244c0 5.4 4.3 7.6 9 5 5.7-3.2 110.8-61.5 111-62l56-31c-.3.4 47.1-25.9 53-29 6.8-3.9 6.1-8.7 1-11-5.5-3.2-54.3-30.5-54-31"/></g></g><g id="Google-play" transform="translate(347 201)"><path id="Fill-1_1_" d="M664.6 147.9l-11.1 10.5c-2.6 1.4-5.1 3.1-7.6 4.2-7.7 3.5-15.5 4.4-22.5 4.4-7.4 0-19-.5-30.8-9.1-16.4-11.6-23.6-31.7-23.6-49.1 0-36.1 29.2-53.8 53.1-53.8 8.3 0 16.9 2.1 23.8 6.5 11.6 7.7 14.6 17.7 16.2 23.1l-54.4 22.1-17.8 1.4c5.8 29.6 25.7 46.8 47.7 46.8 11 0 19.1-3.6 26.6-7.3 0 0 1.5-.8.4.3zm-33.2-59.4c4.4-1.6 6.6-3 6.6-6.3 0-9.4-10.3-20.2-22.7-20.2-9.1 0-26.3 7.3-26.3 32.6 0 4 .5 8.2.7 12.4l41.7-18.5z"/><path id="Fill-2" d="M551 146.6c0 9 1.6 10.4 9.2 11.1 4 .5 7.9.7 11.8 1.1l-8.5 5.1h-40.7c5.3-7 6.3-7.7 6.3-12.3v-5.2l-.1-138h-18L528.3 0h33c-7.2 4.2-9.3 6.7-10.2 14.8l-.1 131.8"/><path id="Fill-3" d="M487.9 66.4c5.3 4.4 16.3 13.7 16.3 31.3 0 17.2-9.6 25.3-19.3 33-3 3-6.5 6.3-6.5 11.4 0 5.1 3.5 7.9 6 10l8.3 6.5c10.1 8.6 19.3 16.5 19.3 32.5 0 21.8-21 43.9-60.6 43.9-33.4 0-49.5-16-49.5-33.2 0-8.4 4.1-20.2 17.8-28.3 14.3-8.8 33.6-10 44-10.7-3.2-4.2-6.9-8.6-6.9-15.8 0-3.9 1.2-6.3 2.3-9.1-2.5.2-5.1.5-7.4.5-24.4 0-38.2-18.4-38.2-36.5 0-10.7 4.8-22.5 14.8-31.1C441.4 59.9 457.1 58 469.5 58H517l-14.8 8.4h-14.3zm-16.2 102.9c-1.9-.3-3-.3-5.3-.3-2.1 0-14.7.5-24.4 3.8-5.1 1.9-20 7.6-20 24.4 0 16.8 16 28.9 40.9 28.9 22.3 0 34.1-10.9 34.1-25.5 0-12.2-7.7-18.6-25.3-31.3zm6.5-44.8c5.3-5.3 5.8-12.7 5.8-16.9 0-16.7-9.8-42.6-28.9-42.6-5.9 0-12.4 3-16.1 7.7-3.9 4.8-5 11.1-5 17.1 0 15.5 9 41.2 28.7 41.2 5.7 0 11.9-2.8 15.5-6.5z"/><path id="Fill-4_1_" d="M344.3 167c-36.7 0-56.3-29-56.3-55.2 0-30.6 24.7-56.8 59.8-56.8 33.9 0 55.2 26.9 55.2 55.2 0 27.6-21 56.8-58.7 56.8zm28.7-18.9c5.6-7.5 7-16.9 7-26 0-20.7-9.7-60.1-38.5-60.1-7.6 0-15.3 3-20.9 8-9 8.2-10.7 18.5-10.7 28.6 0 23.2 11.3 61.4 39.4 61.4 9.2 0 18.4-4.4 23.7-11.9z"/><path id="Fill-5" d="M221.3 167c-36.7 0-56.3-29-56.3-55.2 0-30.6 24.7-56.8 59.8-56.8 33.9 0 55.2 26.9 55.2 55.2 0 27.6-21 56.8-58.7 56.8zm28.7-18.9c5.6-7.5 7-16.9 7-26 0-20.7-9.8-60.1-38.5-60.1-7.7 0-15.3 3-20.9 8-9.1 8.2-10.7 18.5-10.7 28.6 0 23.2 11.4 61.4 39.4 61.4 9.2 0 18.4-4.4 23.7-11.9z"/><path id="Fill-6" d="M149.8 160.1l-31.1 7.2c-12.6 2-23.9 3.8-35.9 3.8C22.8 171 0 126.6 0 91.8 0 49.4 32.4 10 87.8 10c11.7 0 23 1.7 33.3 4.6 16.3 4.6 23.9 10.3 28.7 13.6l-18.1 17.3-7.6 1.7 5.4-8.7c-7.4-7.2-20.9-20.6-46.5-20.6-34.3 0-60.2 26.2-60.2 64.5 0 41.1 29.5 79.8 76.9 79.8 13.9 0 21.1-2.8 27.6-5.4v-35.3l-32.8 1.8 17.4-9.4H158l-5.6 5.5c-1.5 1.3-1.7 1.7-2.2 3.5-.2 2-.4 8.3-.4 10.6v26.6"/><path id="Fill-7_1_" d="M731.7 148.9V208H720V57.7h11.7v17.1c7.6-11.1 21.6-19.8 37.7-19.8 29 0 48.6 22.1 48.6 57 0 34.7-19.5 57.2-48.6 57.2-15.2 0-28.9-7.9-37.7-20.3zm74.3-36c0-26.6-13.7-46.9-38.1-46.9-15.1 0-29.6 12-35.9 22.5v48.6c6.3 10.5 20.8 22.9 35.9 22.9 24.4 0 38.1-20.5 38.1-47.1z"/><path id="Fill-8" d="M834 16h12v151h-12V16z"/><path id="Fill-9" d="M976.5 197.6c2.5 1.1 6.8 1.8 9.5 1.8 7.2 0 12.1-2.9 16.6-13.3l8.5-19.4L965 57h13.1l39.5 95.1 39.2-95.1h13.2l-56.2 132.7c-5.8 13.7-15 20.3-27.6 20.3-3.8 0-8.8-.7-11.7-1.6l2-10.8"/><path id="Fill-10" d="M943.4 166.9c-.8-3.8-1.4-7.1-1.8-9.9-.4-2.8-.6-5.6-.6-8.5-4 5.9-9.7 10.9-17.1 14.8-7.3 3.9-14.3 5.8-23.8 5.8-11.5 0-20.4-2.8-26.7-8.6-6.3-5.7-9.5-13.5-9.5-23.3s4.6-17.8 13.8-23.9c9.2-6.1 21.1-9.2 35.8-9.2h27.4V90.5c0-7.8-2.7-14-8-18.4-5.3-4.5-12.8-6.7-22.5-6.7-8.9 0-16.1 2.1-21.6 6.1-5.4 4.1-8.2 9.2-8.2 15.3h-12l-.2-.6c-.4-8.3 3.3-15.5 11.4-21.8 8-6.3 18.4-9.4 31.3-9.4 12.8 0 23.2 3.1 31 9.3 7.8 6.1 11.7 15 11.7 26.5v54c0 3.9.2 7.6.7 11.3.5 3.7 1.3 7.3 2.3 10.8h-13.4zm-41.8-7.9c10 0 17.2-2.3 24.5-6.7 7.3-4.4 12.2-10.2 14.8-17.2V114h-27.6c-10.5 0-19.2 2.3-26.1 7.1-6.9 4.7-10.3 10.4-10.3 17.1 0 6.3 2.2 11.3 6.6 15.1 4.5 3.8 10.5 5.7 18.1 5.7z"/></g><g id="Get-it-on" transform="translate(343 79)"><path id="Fill-1_2_" d="M0 36.3C0 14.8 17.2.9 38.6.9c14.3 0 23.7 6.4 29.6 14.2l-10.5 5.6c-4-5.1-10.9-9.1-19.1-9.1-14.5 0-25.4 10.3-25.4 24.7C13.3 50.6 24.1 61 38.6 61c7.5 0 14.1-3.2 17.4-6.2V44.3H34V33.7h34.8v25.5c-7.2 7.5-17.5 12.5-30.2 12.5C17.2 71.8 0 57.8 0 36.3"/><path id="Fill-2_1_" d="M85.5 70.8V2h51.1v10.6h-38v17.7h37.2V41H98.6v19.2h38v10.6H85.5"/><path id="Fill-3_1_" d="M171.3 70.8V12.6h-22.2V2h57.3v10.6h-22.2v58.2h-12.9"/><path id="Fill-4_2_" d="M252.3 2h12.5v68.8h-12.5V2z"/><path id="Fill-5_1_" d="M300.6 70.8V12.6h-22.2V2h57.3v10.6h-22.2v58.2h-12.9"/><path id="Fill-6_1_" d="M378.5 36.4C378.5 16 394.2 1 416.6 1c22.2 0 38 15 38 35.4s-15.9 35.4-38 35.4c-22.4 0-38.1-15-38.1-35.4zm62.5-.6c0-14-9.6-24.5-24.5-24.5-15 0-24.5 10.5-24.5 24.5 0 13.9 9.5 24.5 24.5 24.5 14.9 0 24.5-10.5 24.5-24.5z"/><path id="Fill-7_2_" d="M520.3 70.8L482 21.6v49.2h-12.9V2h13.2l37.5 47.7V2h12.9v68.8h-12.4"/></g></g></g></g></svg>
Binary file
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
2
+ width="50" height="50"
3
+ viewBox="0 0 50 50"
4
+ fill="#fff"><path d="M 34.21875 5.46875 C 28.238281 5.46875 23.375 10.332031 23.375 16.3125 C 23.375 16.671875 23.464844 17.023438 23.5 17.375 C 16.105469 16.667969 9.566406 13.105469 5.125 7.65625 C 4.917969 7.394531 4.597656 7.253906 4.261719 7.277344 C 3.929688 7.300781 3.632813 7.492188 3.46875 7.78125 C 2.535156 9.386719 2 11.234375 2 13.21875 C 2 15.621094 2.859375 17.820313 4.1875 19.625 C 3.929688 19.511719 3.648438 19.449219 3.40625 19.3125 C 3.097656 19.148438 2.726563 19.15625 2.425781 19.335938 C 2.125 19.515625 1.941406 19.839844 1.9375 20.1875 L 1.9375 20.3125 C 1.9375 23.996094 3.84375 27.195313 6.65625 29.15625 C 6.625 29.152344 6.59375 29.164063 6.5625 29.15625 C 6.21875 29.097656 5.871094 29.21875 5.640625 29.480469 C 5.410156 29.742188 5.335938 30.105469 5.4375 30.4375 C 6.554688 33.910156 9.40625 36.5625 12.9375 37.53125 C 10.125 39.203125 6.863281 40.1875 3.34375 40.1875 C 2.582031 40.1875 1.851563 40.148438 1.125 40.0625 C 0.65625 40 0.207031 40.273438 0.0507813 40.71875 C -0.109375 41.164063 0.0664063 41.660156 0.46875 41.90625 C 4.980469 44.800781 10.335938 46.5 16.09375 46.5 C 25.425781 46.5 32.746094 42.601563 37.65625 37.03125 C 42.566406 31.460938 45.125 24.226563 45.125 17.46875 C 45.125 17.183594 45.101563 16.90625 45.09375 16.625 C 46.925781 15.222656 48.5625 13.578125 49.84375 11.65625 C 50.097656 11.285156 50.070313 10.789063 49.777344 10.445313 C 49.488281 10.101563 49 9.996094 48.59375 10.1875 C 48.078125 10.417969 47.476563 10.441406 46.9375 10.625 C 47.648438 9.675781 48.257813 8.652344 48.625 7.5 C 48.75 7.105469 48.613281 6.671875 48.289063 6.414063 C 47.964844 6.160156 47.511719 6.128906 47.15625 6.34375 C 45.449219 7.355469 43.558594 8.066406 41.5625 8.5 C 39.625 6.6875 37.074219 5.46875 34.21875 5.46875 Z M 34.21875 7.46875 C 36.769531 7.46875 39.074219 8.558594 40.6875 10.28125 C 40.929688 10.53125 41.285156 10.636719 41.625 10.5625 C 42.929688 10.304688 44.167969 9.925781 45.375 9.4375 C 44.679688 10.375 43.820313 11.175781 42.8125 11.78125 C 42.355469 12.003906 42.140625 12.53125 42.308594 13.011719 C 42.472656 13.488281 42.972656 13.765625 43.46875 13.65625 C 44.46875 13.535156 45.359375 13.128906 46.3125 12.875 C 45.457031 13.800781 44.519531 14.636719 43.5 15.375 C 43.222656 15.578125 43.070313 15.90625 43.09375 16.25 C 43.109375 16.65625 43.125 17.058594 43.125 17.46875 C 43.125 23.71875 40.726563 30.503906 36.15625 35.6875 C 31.585938 40.871094 24.875 44.5 16.09375 44.5 C 12.105469 44.5 8.339844 43.617188 4.9375 42.0625 C 9.15625 41.738281 13.046875 40.246094 16.1875 37.78125 C 16.515625 37.519531 16.644531 37.082031 16.511719 36.683594 C 16.378906 36.285156 16.011719 36.011719 15.59375 36 C 12.296875 35.941406 9.535156 34.023438 8.0625 31.3125 C 8.117188 31.3125 8.164063 31.3125 8.21875 31.3125 C 9.207031 31.3125 10.183594 31.1875 11.09375 30.9375 C 11.53125 30.808594 11.832031 30.402344 11.816406 29.945313 C 11.800781 29.488281 11.476563 29.097656 11.03125 29 C 7.472656 28.28125 4.804688 25.382813 4.1875 21.78125 C 5.195313 22.128906 6.226563 22.402344 7.34375 22.4375 C 7.800781 22.464844 8.214844 22.179688 8.355469 21.746094 C 8.496094 21.3125 8.324219 20.835938 7.9375 20.59375 C 5.5625 19.003906 4 16.296875 4 13.21875 C 4 12.078125 4.296875 11.03125 4.6875 10.03125 C 9.6875 15.519531 16.6875 19.164063 24.59375 19.5625 C 24.90625 19.578125 25.210938 19.449219 25.414063 19.210938 C 25.617188 18.96875 25.695313 18.648438 25.625 18.34375 C 25.472656 17.695313 25.375 17.007813 25.375 16.3125 C 25.375 11.414063 29.320313 7.46875 34.21875 7.46875 Z"></path>
5
+ </svg>
@@ -0,0 +1,100 @@
1
+ import { QueryClientProvider } from "@tanstack/react-query";
2
+ import { fireEvent, render, screen, waitFor, within } from '@testing-library/react';
3
+ import userEvent from "@testing-library/user-event";
4
+ import { WeightForm } from "components/BodyWeight/Form/WeightForm";
5
+ import { WeightEntry } from "components/BodyWeight/model";
6
+ import { useAddWeightEntryQuery, useBodyWeightQuery, useEditWeightEntryQuery } from "components/BodyWeight/queries";
7
+ import React from 'react';
8
+ import { testQueryClient } from "tests/queryClient";
9
+ import { testWeightEntries } from "tests/weight/testData";
10
+
11
+ jest.mock("services");
12
+ jest.mock("components/BodyWeight/queries");
13
+
14
+
15
+ describe("Test WeightForm component", () => {
16
+
17
+ beforeEach(() => {
18
+ (useBodyWeightQuery as jest.Mock).mockImplementation(() => ({ isSuccess: true, data: testWeightEntries }));
19
+ });
20
+
21
+
22
+ test('Passing an existing entry renders its values in the form', () => {
23
+
24
+ // Arrange
25
+ const weightEntry = new WeightEntry(
26
+ new Date('2021-12-10 17:00'),
27
+ 80,
28
+ 1,
29
+ );
30
+
31
+ // Act
32
+ render(
33
+ <QueryClientProvider client={testQueryClient}>
34
+ <WeightForm weightEntry={weightEntry} />
35
+ </QueryClientProvider>
36
+ );
37
+
38
+ // Assert
39
+ expect(screen.getByDisplayValue('12/10/2021 05:00 PM')).toBeInTheDocument();
40
+ expect(screen.getByDisplayValue('80')).toBeInTheDocument();
41
+ expect(screen.getAllByLabelText('date').length).toBeGreaterThan(0);
42
+ expect(screen.getByLabelText('weight')).toBeInTheDocument();
43
+ expect(screen.getByText('submit')).toBeInTheDocument();
44
+ });
45
+
46
+ test('Editing an existing entry', async () => {
47
+
48
+ // Arrange
49
+ const weightEntry = new WeightEntry(
50
+ new Date('2022-02-28'),
51
+ 80,
52
+ 1
53
+ );
54
+
55
+ // Act
56
+ render(
57
+ <QueryClientProvider client={testQueryClient}>
58
+ <WeightForm weightEntry={weightEntry} />
59
+ </QueryClientProvider>
60
+ );
61
+ const submitButton = screen.getByRole('button', { name: 'submit' });
62
+
63
+ // Assert
64
+ expect(submitButton).toBeInTheDocument();
65
+ fireEvent.click(submitButton);
66
+ await waitFor(() => {
67
+ expect(useEditWeightEntryQuery).toHaveBeenCalled();
68
+ });
69
+ });
70
+
71
+ test('Creating a new weight entry', async () => {
72
+
73
+ // Arrange
74
+ const user = userEvent.setup();
75
+ render(
76
+ <QueryClientProvider client={testQueryClient}>
77
+ <WeightForm />
78
+ </QueryClientProvider>
79
+ );
80
+
81
+ const group = screen.getByRole('group', { name: /date/i });
82
+ const dateInput = within(group).getByRole('textbox', { hidden: true });
83
+ const weightInput = await screen.findByLabelText('weight');
84
+ const submitButton = screen.getByRole('button', { name: 'submit' });
85
+
86
+ // Act
87
+ user.type(dateInput, '2022-02-28');
88
+ user.type(weightInput, '80');
89
+
90
+ // Assert
91
+ expect(dateInput).toBeInTheDocument();
92
+ expect(weightInput).toBeInTheDocument();
93
+ expect(submitButton).toBeInTheDocument();
94
+ await user.click(submitButton);
95
+ await waitFor(() => {
96
+ expect(useAddWeightEntryQuery).toHaveBeenCalled();
97
+ });
98
+ });
99
+
100
+ });
@@ -0,0 +1,102 @@
1
+ import { Button, Stack, TextField } from "@mui/material";
2
+ import { DateTimePicker, LocalizationProvider } from "@mui/x-date-pickers";
3
+ import { AdapterLuxon } from "@mui/x-date-pickers/AdapterLuxon";
4
+ import { WeightEntry } from "components/BodyWeight/model";
5
+ import { useAddWeightEntryQuery, useBodyWeightQuery, useEditWeightEntryQuery } from "components/BodyWeight/queries";
6
+ import { LoadingPlaceholder } from "components/Core/LoadingWidget/LoadingWidget";
7
+ import { Form, Formik } from "formik";
8
+ import { DateTime } from "luxon";
9
+ import { useState } from 'react';
10
+ import { useTranslation } from "react-i18next";
11
+ import { dateToYYYYMMDD } from "utils/date";
12
+ import * as yup from 'yup';
13
+
14
+ interface WeightFormProps {
15
+ weightEntry?: WeightEntry,
16
+ closeFn?: () => void,
17
+ }
18
+
19
+ export const WeightForm = ({ weightEntry, closeFn }: WeightFormProps) => {
20
+
21
+ const weightEntriesQuery = useBodyWeightQuery();
22
+ const addWeightQuery = useAddWeightEntryQuery();
23
+ const editWeightQuery = useEditWeightEntryQuery();
24
+
25
+ const [dateValue, setDateValue] = useState<DateTime | null>(weightEntry ? DateTime.fromJSDate(weightEntry.date) : DateTime.now);
26
+ const [t, i18n] = useTranslation();
27
+
28
+ const validationSchema = yup.object({
29
+ weight: yup
30
+ .number()
31
+ .min(30, 'Min weight is 30 kg')
32
+ .max(300, 'Max weight is 300 kg')
33
+ .required('Weight field is required'),
34
+ });
35
+
36
+ if (weightEntriesQuery.isLoading) {
37
+ return <LoadingPlaceholder />;
38
+ }
39
+
40
+ return (
41
+ (<Formik
42
+ initialValues={{
43
+ weight: weightEntry ? weightEntry.weight : 0,
44
+ date: weightEntry ? dateToYYYYMMDD(weightEntry.date) : dateToYYYYMMDD(new Date()),
45
+ }}
46
+ validationSchema={validationSchema}
47
+ onSubmit={async (values) => {
48
+
49
+ // Edit existing weight entry
50
+ if (weightEntry) {
51
+ weightEntry.weight = values.weight;
52
+ weightEntry.date = new Date(values.date);
53
+ editWeightQuery.mutate(weightEntry);
54
+
55
+ // Create a new weight entry
56
+ } else {
57
+ weightEntry = new WeightEntry(new Date(values.date), values.weight);
58
+ addWeightQuery.mutate(weightEntry);
59
+ }
60
+
61
+ if (closeFn) {
62
+ closeFn();
63
+ }
64
+ }}
65
+ >
66
+ {formik => (
67
+ <Form>
68
+ <Stack spacing={2}>
69
+ <TextField
70
+ fullWidth
71
+ id="weight"
72
+ label={t('weight')}
73
+ error={formik.touched.weight && Boolean(formik.touched.weight)}
74
+ helperText={formik.touched.weight && formik.errors.weight}
75
+ {...formik.getFieldProps('weight')}
76
+ />
77
+
78
+ <LocalizationProvider dateAdapter={AdapterLuxon} adapterLocale={i18n.language}>
79
+ <DateTimePicker
80
+ label={t('date')}
81
+ value={dateValue}
82
+ slotProps={{ textField: { variant: 'outlined' } }}
83
+ disableFuture={true}
84
+ onChange={(newValue) => {
85
+ if (newValue) {
86
+ formik.setFieldValue('date', newValue.toJSDate());
87
+ }
88
+ setDateValue(newValue);
89
+ }}
90
+ />
91
+ </LocalizationProvider>
92
+ <Stack direction="row" justifyContent="end" sx={{ mt: 2 }}>
93
+ <Button color="primary" variant="contained" type="submit" sx={{ mt: 2 }}>
94
+ {t('submit')}
95
+ </Button>
96
+ </Stack>
97
+ </Stack>
98
+ </Form>
99
+ )}
100
+ </Formik>)
101
+ );
102
+ };
@@ -0,0 +1,65 @@
1
+ import { QueryClientProvider } from "@tanstack/react-query";
2
+ import { fireEvent, render, screen } from '@testing-library/react';
3
+ import { WeightEntry } from "components/BodyWeight/model";
4
+ import { ActionButton } from 'components/BodyWeight/Table/ActionButton/ActionButton';
5
+ import React from 'react';
6
+ import { testQueryClient } from "tests/queryClient";
7
+
8
+ describe("Body weight test", () => {
9
+
10
+ test('renders without crashing', async () => {
11
+
12
+ // Arrange
13
+ //
14
+ const entry = new WeightEntry(new Date('2021-12-10'), 80, 1);
15
+ render(
16
+ <QueryClientProvider client={testQueryClient}>
17
+ <ActionButton weight={entry} />
18
+ </QueryClientProvider>
19
+ );
20
+
21
+ // Act
22
+ //
23
+ // Note that MUI renders the menu in a different point in the DOM so they are
24
+ // not present before clicking the button
25
+ const button = screen.getByRole("button");
26
+ const editButton = screen.queryByText("edit");
27
+ const deleteButton = screen.queryByText("delete");
28
+ const menuElement = screen.queryByRole('menu');
29
+
30
+ // Assert
31
+ //
32
+ expect(button).toBeInTheDocument();
33
+ expect(deleteButton).toBeNull();
34
+ expect(editButton).toBeNull();
35
+ expect(menuElement).toBeNull();
36
+
37
+ });
38
+
39
+ test('should have list of actions hidden', async () => {
40
+ // Arrange
41
+ //
42
+ const entry = new WeightEntry(new Date('2021-12-10'), 80, 1);
43
+
44
+ // Act
45
+ //
46
+ render(
47
+ <QueryClientProvider client={testQueryClient}>
48
+ <ActionButton weight={entry} />
49
+ </QueryClientProvider>
50
+ );
51
+ const button = screen.getByRole('button');
52
+ expect(button).toBeInTheDocument();
53
+ fireEvent.click(button);
54
+
55
+ // Assert
56
+ //
57
+ const editButton = await screen.findByText("edit");
58
+ const deleteButton = await screen.findByText("delete");
59
+ const menuElement = screen.getByRole('menu');
60
+ expect(deleteButton).toBeTruthy();
61
+ expect(editButton).toBeTruthy();
62
+ expect(menuElement).toBeInTheDocument();
63
+ });
64
+
65
+ });
@@ -0,0 +1,67 @@
1
+ import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
2
+
3
+ import { Button, Menu, MenuItem } from "@mui/material";
4
+ import { WeightForm } from "components/BodyWeight/Form/WeightForm";
5
+ import { WeightEntry } from "components/BodyWeight/model";
6
+ import { useDeleteWeightEntryQuery } from "components/BodyWeight/queries";
7
+ import { WgerModal } from "components/Core/Modals/WgerModal";
8
+ import React from 'react';
9
+ import { useTranslation } from "react-i18next";
10
+
11
+ interface ActionButtonProps {
12
+ weight: WeightEntry;
13
+ }
14
+
15
+ export const ActionButton = ({ weight }: ActionButtonProps) => {
16
+ const deleteWeightEntryQuery = useDeleteWeightEntryQuery();
17
+
18
+
19
+ const [t] = useTranslation();
20
+ const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
21
+ const [openModal, setOpenModal] = React.useState(false);
22
+ const open = Boolean(anchorEl);
23
+ const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
24
+ setAnchorEl(event.currentTarget);
25
+ };
26
+
27
+ const handleEdit = () => {
28
+ handleClose();
29
+ handleOpenModal();
30
+ };
31
+
32
+ const handleClose = () => {
33
+ setAnchorEl(null);
34
+ };
35
+
36
+ const handleDelete = () => {
37
+ deleteWeightEntryQuery.mutate(weight.id!);
38
+ setAnchorEl(null);
39
+ };
40
+
41
+ const handleOpenModal = () => setOpenModal(true);
42
+ const handleCloseModal = () => setOpenModal(false);
43
+
44
+
45
+ return (
46
+ <div>
47
+ <Button onClick={handleClick}>
48
+ <ArrowDropDownIcon />
49
+ </Button>
50
+ <Menu
51
+ anchorEl={anchorEl}
52
+ open={open}
53
+ onClose={handleClose}
54
+ MenuListProps={{
55
+ 'aria-labelledby': 'basic-button',
56
+ }}
57
+ >
58
+ <MenuItem onClick={handleEdit}>{t("edit")}</MenuItem>
59
+ <MenuItem onClick={handleDelete}>{t("delete")}</MenuItem>
60
+ </Menu>
61
+
62
+ <WgerModal title={t('edit')} isOpen={openModal} closeFn={handleCloseModal}>
63
+ <WeightForm weightEntry={weight} closeFn={handleCloseModal} />
64
+ </WgerModal>
65
+ </div>
66
+ );
67
+ };
@@ -0,0 +1,35 @@
1
+ import React from 'react';
2
+ import { Fab } from '@mui/material';
3
+ import AddIcon from '@mui/icons-material/Add';
4
+ import { WeightForm } from "components/BodyWeight/Form/WeightForm";
5
+ import { WgerModal } from "components/Core/Modals/WgerModal";
6
+ import { useTranslation } from "react-i18next";
7
+
8
+
9
+ export const WeightEntryFab = () => {
10
+
11
+ const [t] = useTranslation();
12
+ const [openModal, setOpenModal] = React.useState(false);
13
+ const handleOpenModal = () => setOpenModal(true);
14
+ const handleCloseModal = () => setOpenModal(false);
15
+
16
+ return (
17
+ <div>
18
+ <Fab
19
+ color="primary"
20
+ aria-label="add"
21
+ onClick={handleOpenModal}
22
+ sx={{
23
+ position: 'fixed',
24
+ bottom: '5rem',
25
+ right: (theme) => `max(${theme.spacing(2)}, calc((100vw - ${theme.breakpoints.values.lg}px) / 2 + ${theme.spacing(2)}))`,
26
+ zIndex: 9,
27
+ }}>
28
+ <AddIcon />
29
+ </Fab>
30
+ <WgerModal title={t('add')} isOpen={openModal} closeFn={handleCloseModal}>
31
+ <WeightForm closeFn={handleCloseModal} />
32
+ </WgerModal>
33
+ </div>
34
+ );
35
+ };
@@ -0,0 +1,33 @@
1
+ import { QueryClientProvider } from "@tanstack/react-query";
2
+ import { render, screen } from '@testing-library/react';
3
+ import { WeightEntry } from "components/BodyWeight/model";
4
+ import { BrowserRouter } from "react-router-dom";
5
+ import { testQueryClient } from "tests/queryClient";
6
+ import { WeightTable } from './index';
7
+
8
+ describe("Body weight test", () => {
9
+ test('renders without crashing', async () => {
10
+
11
+ const weightsData: WeightEntry[] = [
12
+ new WeightEntry(new Date('2021/12/10'), 80, 1),
13
+ new WeightEntry(new Date('2021/12/20'), 90, 2),
14
+ ];
15
+
16
+ // since I used context api to provide state, also need it here
17
+ render(
18
+ <BrowserRouter>
19
+ <QueryClientProvider client={testQueryClient}>
20
+ <WeightTable weights={weightsData} />
21
+ </QueryClientProvider>
22
+ </BrowserRouter>
23
+ );
24
+
25
+
26
+ // Both weights are found in th document
27
+ const weightRow = await screen.findByText('80');
28
+ expect(weightRow).toBeInTheDocument();
29
+
30
+ const weightRow2 = await screen.findByText("90");
31
+ expect(weightRow2).toBeInTheDocument();
32
+ });
33
+ });