/ apps / web / src / hooks / useSimpleUserSongs.ts
useSimpleUserSongs.ts
  1  import { useState, useEffect } from 'react'
  2  import { useAccount } from 'wagmi'
  3  import { usePGLite } from '../contexts/PGLiteContext'
  4  import { gunDBService } from '../services/database/gundb'
  5  
  6  interface UserSong {
  7    songId: number
  8    title: string
  9    artist: string
 10    artwork_thumbnail: string | null
 11    newCount: number
 12    learningCount: number
 13    dueCount: number
 14  }
 15  
 16  /**
 17   * Simple hook to get user's songs from PGLite
 18   */
 19  export function useSimpleUserSongs() {
 20    const { isConnected } = useAccount()
 21    const { readService, isReady } = usePGLite()
 22    const [userSongs, setUserSongs] = useState<UserSong[]>([])
 23    const [totalStats, setTotalStats] = useState({ new: 0, learning: 0, due: 0 })
 24    const [isLoading, setIsLoading] = useState(true)
 25  
 26    // Load user songs and stats from PGLite
 27    useEffect(() => {
 28      const loadUserSongs = async () => {
 29        if (!isConnected || !isReady) {
 30          setUserSongs([])
 31          setTotalStats({ new: 0, learning: 0, due: 0 })
 32          setIsLoading(false)
 33          return
 34        }
 35  
 36        try {
 37          setIsLoading(true)
 38          
 39          // Get song stats from PGLite
 40          const songStats = await readService.getSongStats()
 41          
 42          // Calculate total stats
 43          let newTotal = 0
 44          let learningTotal = 0
 45          let dueTotal = 0
 46          
 47          songStats.forEach(stat => {
 48            newTotal += stat.new_cards
 49            learningTotal += stat.learning_cards
 50            dueTotal += stat.due_cards
 51          })
 52          
 53          setTotalStats({
 54            new: newTotal,
 55            learning: learningTotal,
 56            due: dueTotal
 57          })
 58          
 59          // Convert to UserSong format and fetch artwork
 60          const songsWithArtwork = await Promise.all(
 61            songStats.map(async (stat) => {
 62              let artwork_thumbnail = null
 63              try {
 64                const songData = await gunDBService.getSongByGeniusId(stat.song_id)
 65                artwork_thumbnail = songData?.artwork_thumbnail || null
 66              } catch (error) {
 67                console.warn(`Failed to fetch metadata for song ${stat.song_id}:`, error)
 68              }
 69              
 70              return {
 71                songId: stat.song_id,
 72                title: stat.song_title || 'Unknown Song',
 73                artist: stat.artist_name || 'Unknown Artist',
 74                artwork_thumbnail,
 75                newCount: stat.new_cards,
 76                learningCount: stat.learning_cards,
 77                dueCount: stat.due_cards
 78              }
 79            })
 80          )
 81          
 82          // Sort by due cards
 83          const sortedSongs = songsWithArtwork.sort((a, b) => {
 84            if (a.dueCount !== b.dueCount) {
 85              return b.dueCount - a.dueCount
 86            }
 87            const totalA = a.newCount + a.learningCount + a.dueCount
 88            const totalB = b.newCount + b.learningCount + b.dueCount
 89            return totalB - totalA
 90          })
 91          
 92          setUserSongs(sortedSongs)
 93        } catch (error) {
 94          console.error('Failed to load songs from PGLite:', error)
 95        } finally {
 96          setIsLoading(false)
 97        }
 98      }
 99  
100      loadUserSongs()
101    }, [isConnected, isReady, readService])
102  
103    return {
104      userSongs,
105      totalStats,
106      isLoading
107    }
108  }