All files / src/hooks useCollectionsPage.ts

37.25% Statements 19/51
8.33% Branches 1/12
50% Functions 3/6
38% Lines 19/50

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 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101            18x 18x 18x       18x 18x 18x 18x 18x   18x 10x 10x 10x 10x         10x     10x     18x                                                             18x                                 18x         18x                            
import { useState, useEffect } from 'react'
import { useNavigate, useSearchParams } from 'react-router-dom'
import { toast } from 'sonner'
import { api, type Collection } from '../api/client'
 
export function useCollectionsPage() {
  const navigate = useNavigate()
  const [searchParams] = useSearchParams()
  const pendingRecipeId = searchParams.get('addRecipe')
    ? Number(searchParams.get('addRecipe'))
    : null
 
  const [collections, setCollections] = useState<Collection[]>([])
  const [loading, setLoading] = useState(true)
  const [showCreateForm, setShowCreateForm] = useState(false)
  const [newCollectionName, setNewCollectionName] = useState('')
  const [creating, setCreating] = useState(false)
 
  useEffect(() => {
    const load = async () => {
      try {
        const data = await api.collections.list()
        setCollections(data)
      } catch (error) {
        console.error('Failed to load collections:', error)
        toast.error('Failed to load collections')
      } finally {
        setLoading(false)
      }
    }
    load()
  }, [])
 
  const handleCreateCollection = async (e: React.FormEvent) => {
    e.preventDefault()
    if (!newCollectionName.trim()) return
 
    setCreating(true)
    try {
      const collection = await api.collections.create({
        name: newCollectionName.trim(),
      })
      setCollections([collection, ...collections])
      setNewCollectionName('')
      setShowCreateForm(false)
      toast.success('Collection created')
 
      if (pendingRecipeId) {
        try {
          await api.collections.addRecipe(collection.id, pendingRecipeId)
          toast.success('Recipe added to collection')
        } catch (error) {
          console.error('Failed to add recipe to collection:', error)
        }
        navigate(`/collection/${collection.id}`)
      }
    } catch (error) {
      console.error('Failed to create collection:', error)
      toast.error('Failed to create collection')
    } finally {
      setCreating(false)
    }
  }
 
  const handleCollectionClick = async (collectionId: number) => {
    if (pendingRecipeId) {
      try {
        await api.collections.addRecipe(collectionId, pendingRecipeId)
        toast.success('Recipe added to collection')
      } catch (error: unknown) {
        if (error instanceof Error && !error.message.includes('already')) {
          console.error('Failed to add recipe to collection:', error)
          toast.error('Failed to add recipe to collection')
        } else {
          toast.info('Recipe is already in this collection')
        }
      }
    }
    navigate(`/collection/${collectionId}`)
  }
 
  const handleCancelCreate = () => {
    setShowCreateForm(false)
    setNewCollectionName('')
  }
 
  return {
    pendingRecipeId,
    collections,
    loading,
    showCreateForm,
    setShowCreateForm,
    newCollectionName,
    setNewCollectionName,
    creating,
    handleCreateCollection,
    handleCollectionClick,
    handleCancelCreate,
  }
}
 
← Back to Dashboard