All files / src/hooks useServingScale.ts

22.72% Statements 5/22
0% Branches 0/9
50% Functions 1/2
23.8% Lines 5/21

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54                                          30x 30x 30x   30x                                                   30x    
import { useState } from 'react'
import { toast } from 'sonner'
import { api, type RecipeDetail as RecipeDetailType, type ScaleResponse } from '../api/client'
import { handleQuotaError } from '../lib/utils'
 
interface UseServingScaleReturn {
  servings: number | null
  scaledData: ScaleResponse | null
  scalingLoading: boolean
  setServings: (s: number | null) => void
  setScaledData: (d: ScaleResponse | null) => void
  handleServingChange: (delta: number) => Promise<void>
}
 
/**
 * Manages serving count and AI-powered ingredient scaling.
 */
export function useServingScale(
  recipe: RecipeDetailType | null,
  profileId: number | undefined
): UseServingScaleReturn {
  const [servings, setServings] = useState<number | null>(null)
  const [scaledData, setScaledData] = useState<ScaleResponse | null>(null)
  const [scalingLoading, setScalingLoading] = useState(false)
 
  const handleServingChange = async (delta: number) => {
    if (!servings || !recipe || !profileId) return
    const newServings = Math.max(1, servings + delta)
    setServings(newServings)
 
    if (newServings === recipe.servings) {
      setScaledData(null)
      return
    }
 
    setScalingLoading(true)
    try {
      const result = await api.ai.scale(recipe.id, newServings, profileId)
      setScaledData(result)
      if (result.notes.length > 0) {
        toast.info(result.notes[0])
      }
    } catch (error) {
      console.error('Failed to scale recipe:', error)
      handleQuotaError(error, 'Failed to scale ingredients')
      setServings(servings)
    } finally {
      setScalingLoading(false)
    }
  }
 
  return { servings, scaledData, scalingLoading, setServings, setScaledData, handleServingChange }
}
 
← Back to Dashboard