Skip to content

refactor(diary): migrate diary to tanstack query and fix bugs#692

Merged
CodeWithCJ merged 3 commits intoCodeWithCJ:mainfrom
Sim-sat:migrate-diary
Feb 20, 2026
Merged

refactor(diary): migrate diary to tanstack query and fix bugs#692
CodeWithCJ merged 3 commits intoCodeWithCJ:mainfrom
Sim-sat:migrate-diary

Conversation

@Sim-sat
Copy link
Contributor

@Sim-sat Sim-sat commented Feb 20, 2026

Description

  • migrated the whole /pages/diary directory to tanstack query
  • Replaced manual window event listeners with query invalidation from fitbit data sync optimization #690
  • fixes bug preventing to upload images
  • splitting components in seperate files
  • decouple logic from ui by moving the functions to utils
  • removed a ton of useCallbacks, which were not needed and/or wrongly implemented
  • adding water intake doesn't cause rerender of daily energy goal anymore
  • Added eslint-plugin-unused-imports and cleaned up unused imports across the project. This enables the use of npm run format -- --fix to remove all unused imports directly
  • Simplified lint-staged to run only prettier
  • moved large default values into constants to make code more readable
  • add pnpm-lock and package-lock to .prettierignore

- migrated the whole /pages/diary directory to tanstack query
- fixed unnecessary use of window listeners from CodeWithCJ#690
- fixes bug preventing to upload images
- splitting components in seperate files
- decouple logic from ui by moving the functions to utils
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @Sim-sat, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request represents a significant refactoring effort focused on enhancing the diary functionality. By migrating to Tanstack Query, the application benefits from improved data fetching, caching, and synchronization, leading to a more robust and maintainable codebase. The changes also include crucial bug fixes, extensive code cleanup, and dependency updates, all contributing to a more stable and efficient user experience.

Highlights

  • Tanstack Query Migration: The entire /pages/diary directory has been migrated to Tanstack Query, centralizing data fetching and state management for daily progress, food entries, and meal types. This significantly reduces boilerplate and improves data consistency.
  • Bug Fixes: Addressed a bug that prevented image uploads in exercise entries and resolved an issue where adding water intake caused unnecessary re-renders of the daily energy goal.
  • Code Refactoring & Cleanup: Components within the diary section have been split into separate files, logic has been decoupled from UI by moving functions to utility files, and numerous unnecessary or incorrectly implemented useCallback hooks have been removed. Unused imports across the project were cleaned up with the addition of eslint-plugin-unused-imports.
  • Improved ESLint Configuration: Integrated eslint-plugin-unused-imports to automatically detect and remove unused imports, enhancing code quality and enabling npm run format -- --fix for direct cleanup. The lint-staged configuration was simplified to run only Prettier.
  • Dependency Updates: Updated various core dependencies including @typescript-eslint packages, semver, axios, fast-xml-parser, strnum, minimatch, and ajv to their latest versions, ensuring better performance and security.
  • Centralized Data Keys: Introduced new api/keys/diary.ts file to define consistent Tanstack Query keys for diary-related data, improving cache management and query invalidation.
Changelog
  • SparkyFitnessFrontend/eslint.config.js
    • Added eslint-plugin-unused-imports to the configuration.
    • Configured unused-imports/no-unused-imports rule to 'error'.
    • Disabled @typescript-eslint/no-unused-vars to prevent conflicts with the new unused imports plugin.
  • SparkyFitnessFrontend/package-lock.json
    • Updated project version from 0.16.4.1 to 0.16.4.4.
    • Added eslint-plugin-unused-imports dependency.
    • Updated @typescript-eslint related packages to version 8.56.0.
    • Updated semver to 7.7.4.
    • Updated axios to 1.13.5.
    • Updated fast-xml-parser to 5.3.6 and strnum to 2.1.2.
    • Updated minimatch to 10.2.1 and removed @isaacs/balanced-match and @isaacs/brace-expansion.
    • Updated ajv to 8.18.0.
  • SparkyFitnessFrontend/package.json
    • Added eslint-plugin-unused-imports as a dev dependency.
    • Simplified lint-staged configuration to only run prettier --write.
  • SparkyFitnessFrontend/src/api/Diary/dailyProgressService.ts
    • Updated import paths for apiCall and GroupedExerciseEntry to reflect the new directory structure.
  • SparkyFitnessFrontend/src/api/Diary/foodEntryService.ts
    • Updated import paths for apiCall.
    • Exported FoodEntryUpdateData interface.
    • Added DayData interface and loadMiniNutritionTrendData function for nutrition trends.
    • Renamed loadGoals to loadDiaryGoals.
    • Changed return types of copyFoodEntries and copyFoodEntriesFromYesterday to Promise<unknown>.
  • SparkyFitnessFrontend/src/api/Diary/mealTypeService.ts
    • Updated import path for apiCall.
  • SparkyFitnessFrontend/src/api/Exercises/exerciseEntryService.ts
    • Updated import path for getDailyExerciseEntries to the new api/Diary location.
    • Modified updateExerciseEntry to exclude image_url from the JSON body when no new image is provided, addressing a backend issue.
  • SparkyFitnessFrontend/src/api/Foods/meals.ts
    • Removed the logDayMealPlanToDiary function.
  • SparkyFitnessFrontend/src/api/keys/diary.ts
    • Added new file to define Tanstack Query keys for meal types, daily progress, food entries, food entry meals, and reports.
  • SparkyFitnessFrontend/src/api/keys/exercises.ts
    • Refactored exerciseSearchKeys to use exerciseSearch as the base key to prevent potential naming conflicts.
  • SparkyFitnessFrontend/src/components/GlobalNotificationIcon.tsx
    • Removed unused imports for Bell, Tooltip components, and Dialog components.
  • SparkyFitnessFrontend/src/components/MealBuilder.tsx
    • Removed direct service imports for food entry meal operations.
    • Integrated foodEntryMealDetailsOptions, useCreateFoodEntryMealMutation, and useUpdateFoodEntryMealMutation from hooks/Diary/useFoodEntries.
    • Removed onSave prop, now relying on query invalidation.
    • Replaced direct API calls with Tanstack Query mutations and queryClient.fetchQuery.
    • Removed explicit toast calls, relying on mutation meta for notifications.
    • Converted useCallback wrapped functions to regular functions.
    • Removed redundant nutrition calculations for individual meal foods.
  • SparkyFitnessFrontend/src/components/ai/ServiceForm.tsx
    • Removed unused import AIService.
  • SparkyFitnessFrontend/src/components/ai/ServiceList.tsx
    • Removed unused import Globe icon.
  • SparkyFitnessFrontend/src/components/ai/ServiceListItem.tsx
    • Removed unused import Globe icon.
  • SparkyFitnessFrontend/src/constants/nutrients.ts
    • Imported MealTotals interface from pages/Diary/Diary.
    • Added EMPTY_MEAL_TOTALS constant for initializing meal totals.
  • SparkyFitnessFrontend/src/hooks/Diary/useDailyProgress.ts
    • Added new file containing Tanstack Query hooks for daily goals, food intake, exercise stats, steps, and calculated BMR.
  • SparkyFitnessFrontend/src/hooks/Diary/useFoodEntries.ts
    • Added new file containing Tanstack Query hooks for food entries, diary goals, food entry meals, and their respective create, update, delete, and copy mutations.
  • SparkyFitnessFrontend/src/hooks/Diary/useMealTypes.ts
    • Added new file containing Tanstack Query hooks for fetching meal types and creating meals from diary entries.
  • SparkyFitnessFrontend/src/hooks/Exercises/useExerciseEntries.ts
    • Imported dailyProgressKeys for broader query invalidation.
    • Modified useUpdateExerciseEntryMutation to invalidate exerciseEntryKeys.all and dailyProgressKeys.all on success.
  • SparkyFitnessFrontend/src/hooks/Foods/useFoodVariants.ts
    • Added useFoodVariants hook for fetching food variants.
  • SparkyFitnessFrontend/src/hooks/Foods/useFoods.ts
    • Updated imports for createFoodEntry and loadMiniNutritionTrendData to point to api/Diary/foodEntryService.
    • Imported reportKeys from api/keys/diary.
    • Added useFoodView hook for fetching individual food details.
    • Added useMiniNutritionTrendData hook for fetching nutrition trend data.
  • SparkyFitnessFrontend/src/pages/Admin/AuthenticationSettings.tsx
    • Removed unused imports for Lock icon and OidcSettings component.
  • SparkyFitnessFrontend/src/pages/Admin/OidcProviderDialog.tsx
    • Removed unused import oidcSettingsService.
  • SparkyFitnessFrontend/src/pages/Auth/ResetPassword.tsx
    • Removed unused import error from utils/logging.
  • SparkyFitnessFrontend/src/pages/Diary/ConvertToMealDialog.tsx
    • Removed useEffect and useCallback hooks.
    • Removed onMealCreated prop.
    • Utilized useCreateMealFromDiaryMutation from hooks/Diary/useMealTypes.
    • Removed explicit toast calls, relying on mutation meta.
    • Initialized mealName directly in useState with a default value.
  • SparkyFitnessFrontend/src/pages/Diary/CopyFoodEntryDialog.tsx
    • Removed useCallback hooks.
    • Replaced direct getMealTypes call with useMealTypes hook.
    • Inlined handleDateSelect and handleMealTypeChange logic.
    • Added key prop to force remount on open/close.
  • SparkyFitnessFrontend/src/pages/Diary/DailyProgress.tsx
    • Removed local state management for goals, intake, exercise, steps, and BMR.
    • Replaced direct service calls with useDailyGoals, useDailyFoodIntake, useDailyExerciseStats, useDailySteps, and useCalculatedBMR hooks.
    • Removed refreshTrigger prop.
    • Introduced DailyProgressSkeleton for loading states.
    • Integrated EnergyCircle component for visual progress.
    • Simplified calorie calculation logic using derived state from hooks.
  • SparkyFitnessFrontend/src/pages/Diary/DailyProgressSkeleton.tsx
    • Added new file to provide a skeleton loading UI for the DailyProgress component.
  • SparkyFitnessFrontend/src/pages/Diary/Diary.tsx
    • Removed useEffect and useCallback hooks for data fetching and state management.
    • Removed externalRefreshTrigger state.
    • Replaced direct service calls with Tanstack Query hooks for all diary-related data.
    • Removed local data loading and calculation functions (_calculateDayTotals, _loadFoodEntriesAndMeals, _loadGoals, handleDataChange).
    • Derived foodEntries and foodEntryMeals directly from Tanstack Query data.
    • Utilized new utility functions calculateDayTotals, getEntryNutrition, getMealData, getMealTotals from utils/nutritionCalculations.
    • Removed onSave and onExerciseChange props from child components, relying on query invalidation.
    • Added key props to dialogs and cards to ensure proper remounting and state reset.
  • SparkyFitnessFrontend/src/pages/Diary/DiaryTopControls.tsx
    • Removed onGoalsUpdated and refreshTrigger props.
    • Updated DailyProgress, EditGoalsForToday, and MiniNutritionTrends components to no longer receive refreshTrigger or onGoalsUpdated.
  • SparkyFitnessFrontend/src/pages/Diary/EditExerciseDatabaseDialog.tsx
    • Refactored state management to use a single formData state with derived state logic.
    • Removed useCallback from handleSaveExerciseDatabaseEdit.
    • Simplified image handling and removed explicit toast calls.
  • SparkyFitnessFrontend/src/pages/Diary/EditExerciseEntryDialog.tsx
    • Removed toast imports and calls.
    • Removed various lucide-react icons and Select components, as SortableSetItem is now a separate component.
    • Imported SortableSetItem from the new ExerciseSortableItems file.
    • Removed loading state, using isPending from the mutation hook.
    • Simplified initial state setup for sets and distanceInput.
    • Removed onSave prop.
  • SparkyFitnessFrontend/src/pages/Diary/EditFoodEntryDialog.tsx
    • Removed useCallback and useEffect for data loading.
    • Removed toast imports and calls.
    • Replaced direct service calls with useFoodView, useFoodVariants, and useUpdateFoodEntryMutation hooks.
    • Removed onSave prop.
    • Replaced local calculateNutrition with an imported utility function.
    • Introduced NutrientGrid component for displaying nutrition details.
    • Utilized useMemo for variants and selectedVariant for optimization.
    • Added useRef for input focus management.
  • SparkyFitnessFrontend/src/pages/Diary/EditMealFoodEntryDialog.tsx
    • Removed local state (useState, useEffect) and logging imports.
    • Removed onSave prop.
    • Derived initialMealFoods directly from foodEntry.foods.
    • Removed loading state logic.
  • SparkyFitnessFrontend/src/pages/Diary/EnergyProgressCircle.tsx
    • Added new file to encapsulate the energy progress circle UI component.
  • SparkyFitnessFrontend/src/pages/Diary/ExerciseCard.tsx
    • Removed onExerciseChange prop.
    • Removed useEffect for foodDiaryRefresh event listener.
    • Removed handleDataChange function and explicit toast calls.
    • Removed expandedPresets state.
    • Simplified handleCloseAddDialog and handleExerciseSelect.
    • Simplified mutation success callbacks by removing redundant onExerciseChange calls.
    • Utilized useMemo for stats calculation to optimize performance.
    • Added key props to dialogs to ensure proper remounting.
  • SparkyFitnessFrontend/src/pages/Diary/ExerciseSortableItems.tsx
    • Added new file to extract the SortableSetItem component, used in exercise entry dialogs.
  • SparkyFitnessFrontend/src/pages/Diary/LogExerciseEntryDialog.tsx
    • Removed debug, info, warn, useToast imports and calls.
    • Removed various lucide-react icons and Select components, as SortableSetItem is now a separate component.
    • Imported SortableSetItem from the new ExerciseSortableItems file.
    • Removed initialNotes and initialImageUrl props.
    • Simplified initial state setup for sets and caloriesBurnedInput using useState initializer functions.
    • Removed loading state, using isPending from the mutation hook.
    • Added previewUrl state for image previews and useEffect for revoking object URLs.
    • Simplified handleSetChange and handleRemoveSet logic.
    • Added DragEndEvent type for handleDragEnd.
    • Improved activity_details mapping logic.
  • SparkyFitnessFrontend/src/pages/Diary/LogMealDialog.tsx
    • Removed usePreferences import.
    • Removed onSave prop.
    • Explicitly typed initialFoods as MealFood[].
  • SparkyFitnessFrontend/src/pages/Diary/MealCard.tsx
    • Removed useAuth and info imports.
    • Removed onEditFood, onMealAdded, and onCopyFromYesterday props.
    • Integrated useCopyFoodEntriesFromYesterdayMutation hook.
    • Removed local handleEditFood, handleSaveFood, handleCancelFood functions.
    • Removed foodDatabaseNutrients and foodDatabaseVisibleNutrients variables.
    • Simplified handleCopyFromYesterday to use the mutation hook.
  • SparkyFitnessFrontend/src/pages/Diary/MiniNutritionTrends.tsx
    • Removed local state management for chart data and mounting.
    • Removed useAuth import and direct loadMiniNutritionTrendData call.
    • Integrated useMiniNutritionTrendData hook for data fetching.
    • Utilized useMemo for dateRange calculation.
    • Refactored CustomTooltip and MiniTrendChart into separate, memoized components.
    • Added explicit loading and no data available states.
  • SparkyFitnessFrontend/src/pages/Diary/NutrientsGrid.tsx
    • Added new file to extract the nutrient display grid component, used in EditFoodEntryDialog.
  • SparkyFitnessFrontend/src/pages/Exercises/ExerciseSearch.tsx
    • Removed unused useMemo import.
  • SparkyFitnessFrontend/src/pages/Exercises/WorkoutPresetSelector.tsx
    • Removed unused useEffect import.
  • SparkyFitnessFrontend/src/pages/Foods/MealManagement.tsx
    • Removed toast import.
    • Removed meal parameter from handleMealSave as it is no longer needed due to query invalidation.
  • SparkyFitnessFrontend/src/pages/Goals/EditGoalsForToday.tsx
    • Removed onGoalsUpdated prop.
    • Removed the onGoalsUpdated() call from handleSaveGoals.
  • SparkyFitnessFrontend/src/pages/Integrations/PolarCallback.tsx
    • Removed unused apiCall import.
  • SparkyFitnessFrontend/src/pages/Reports/NutritionChartsGrid.tsx
    • Removed unused useEffect import.
    • Removed unused getNutrientMetadata import.
  • SparkyFitnessFrontend/src/pages/Settings/ExternalProviderSettings.tsx
    • Imported exerciseEntryKeys and useQueryClient.
    • Replaced window.dispatchEvent(new CustomEvent('foodDiaryRefresh')) with queryClient.invalidateQueries({ queryKey: exerciseEntryKeys.all }) for all external provider syncs (Garmin, Fitbit, Polar, Hevy).
  • SparkyFitnessFrontend/src/pages/Settings/MealTypeManager.tsx
    • Updated import paths for meal type service functions to api/Diary/mealTypeService.
  • SparkyFitnessFrontend/src/services/dailyProgressService.ts
    • Renamed to SparkyFitnessFrontend/src/api/Diary/dailyProgressService.ts.
  • SparkyFitnessFrontend/src/services/foodEntryService.ts
    • Renamed to SparkyFitnessFrontend/src/api/Diary/foodEntryService.ts.
  • SparkyFitnessFrontend/src/services/mealTypeService.ts
    • Renamed to SparkyFitnessFrontend/src/api/Diary/mealTypeService.ts.
  • SparkyFitnessFrontend/src/services/miniNutritionTrendsService.ts
    • Removed file; its functionality has been moved to api/Diary/foodEntryService.ts and integrated via Tanstack Query hooks.
  • SparkyFitnessFrontend/src/utils/aiServiceUtils.ts
    • Removed unused useTranslation import.
  • SparkyFitnessFrontend/src/utils/nutritionCalculations.ts
    • Imported EMPTY_MEAL_TOTALS, i18n, MealTotals, FoodVariant, and FoodEntryMeal.
    • Added getEnergyUnitString function.
    • Defined CalculatedNutrition interface.
    • Added calculateNutrition function (extracted from EditFoodEntryDialog).
    • Added calculateDayTotals function (extracted from Diary).
    • Added getMealTotals function (extracted from Diary).
    • Added getEntryNutrition function (extracted from Diary).
    • Added getMealData function (extracted from Diary).
Activity
  • The pull request was created by Sim-sat.
  • No human activity (comments, reviews) has been recorded on this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request primarily refactors the frontend's data fetching and state management by migrating several components and services to use TanStack Query hooks. Key changes include introducing new query keys for diary and exercise search data, creating dedicated hooks for daily progress, food entries, and meal types, and updating components like MealBuilder, DailyProgress, ExerciseCard, and various dialogs to consume these new hooks. This refactoring aims to centralize data management, reduce boilerplate, and improve caching. Additionally, eslint-plugin-unused-imports was added to the project configuration, and several dependencies in package-lock.json were updated. Minor cleanups include removing unused imports and console.log statements, and addressing a backend workaround for image URLs in exercise entry updates. Review comments highlight several issues: a circular dependency for MealTotals (now resolved by moving it to constants/nutrients.ts), incorrect unit conversions for calories in exercise entry forms, missing UI inputs for exercise details, a stale state issue in LogExerciseEntryDialog due to an insufficient key, and a redundant check in getMealData.

@Sim-sat
Copy link
Contributor Author

Sim-sat commented Feb 20, 2026

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This is an impressive refactoring effort. Migrating the entire diary feature to TanStack Query is a significant improvement for state management, data consistency, and performance. The code is now much cleaner, more organized, and follows modern React best practices by separating concerns into custom hooks, utility functions, and presentational components. The bug fixes, especially for image uploads, and the cleanup of unused code and dependencies are also valuable contributions. The suggestions to ensure components with internal state are correctly reset when their props change, which is a common pattern to ensure robustness in complex UIs, have been kept. Overall, this is a high-quality pull request that greatly improves the maintainability of the codebase.

@CodeWithCJ CodeWithCJ merged commit 4cac06b into CodeWithCJ:main Feb 20, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants