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 }
}
|