All files / src/hooks usePlayModeData.ts

65.62% Statements 21/32
50% Branches 6/12
71.42% Functions 5/7
67.85% Lines 19/28

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 55 56 57 58 59 60 61 62              22x 22x 22x 22x   22x 11x 11x 11x 11x       11x 11x           11x     11x     22x       22x                                 22x 11x 1x     1x    
import { useState, useEffect, useCallback } from 'react'
import { useNavigate } from 'react-router-dom'
import { toast } from 'sonner'
import { api, type RecipeDetail } from '../api/client'
import { playTimerAlert } from '../lib/audio'
 
export function usePlayModeData(recipeId: number) {
  const navigate = useNavigate()
  const [recipe, setRecipe] = useState<RecipeDetail | null>(null)
  const [loading, setLoading] = useState(true)
  const [aiAvailable, setAiAvailable] = useState(false)
 
  useEffect(() => {
    Iif (!recipeId) return
    const load = async () => {
      try {
        const [recipeData, aiStatus] = await Promise.all([
          api.recipes.get(recipeId),
          api.ai.status(),
        ])
        setRecipe(recipeData)
        setAiAvailable(aiStatus.available)
      } catch (error) {
        console.error('Failed to load recipe:', error)
        toast.error('Failed to load recipe')
        navigate(-1)
      } finally {
        setLoading(false)
      }
    }
    load()
  }, [recipeId, navigate])
 
  return { recipe, loading, aiAvailable }
}
 
export function useTimerComplete() {
  return useCallback((timer: { label: string }) => {
    playTimerAlert()
    toast.success(`Timer complete: ${timer.label}`, { duration: 10000 })
    try {
      if ('Notification' in window && Notification.permission === 'granted') {
        new Notification('Timer Complete!', {
          body: timer.label,
          icon: '/favicon.ico',
        })
      }
    } catch {
      // Notification not supported or blocked
    }
  }, [])
}
 
export function getInstructions(recipe: RecipeDetail | null): string[] {
  if (!recipe) return []
  if (recipe.instructions.length > 0) return recipe.instructions
  Iif (recipe.instructions_text) {
    return recipe.instructions_text.split('\n').filter((s) => s.trim())
  }
  return []
}
 
← Back to Dashboard