'use client'
import { useState, useEffect, useRef, useCallback } from 'react'
import { useAuth } from '@/components/AuthProvider'
export interface Book {
id: string
title: string
description: string | null
author?: string | null
lastModified: string
word_count: number
status: string
genre?: string | null
target_word_count?: number | null
cover_image_url?: string | null
created_at?: string
updated_at?: string
}
export function useBooks() {
const { user } = useAuth()
const [books, setBooks] = useState<Book[]>([])
const [loading, setLoading] = useState(true)
const [error, setError] = useState<string | null>(null)
const hasFetched = useRef(false)
useEffect(() => {
if (!user?.id) {
setBooks([])
setLoading(false)
hasFetched.current = false
return
}
// Only fetch if we haven't fetched for this user yet
if (!hasFetched.current) {
fetchBooks()
}
}, [user?.id])
const fetchBooks = async () => {
if (!user?.id) return
try {
setLoading(true)
setError(null)
const response = await fetch(`/api/books?userId=${user.id}`)
if (!response.ok) {
throw new Error('Failed to fetch books')
}
const data = await response.json()
const fetchedBooks = data.books || []
setBooks(fetchedBooks)
hasFetched.current = true
} catch (error) {
console.error('Error fetching books:', error)
setError('Failed to load books')
} finally {
setLoading(false)
}
}
// Get a specific book by ID
const getBook = useCallback((bookId: string): Book | undefined => {
return books.find(book => book.id === bookId)
}, [books])
// Get recent books (for dashboard)
const getRecentBooks = useCallback((limit: number = 5): Book[] => {
return books
.sort((a, b) => new Date(b.lastModified).getTime() - new Date(a.lastModified).getTime())
.slice(0, limit)
}, [books])
// Add a new book to the state
const addBook = useCallback((newBook: Book) => {
const updatedBooks = [newBook, ...books]
setBooks(updatedBooks)
}, [books])
// Update an existing book in the state
const updateBook = useCallback((bookId: string, updates: Partial<Book>) => {
const updatedBooks = books.map(book =>
book.id === bookId ? { ...book, ...updates } : book
)
setBooks(updatedBooks)
}, [books])
// Remove a book from the state
const deleteBook = useCallback((bookId: string) => {
const updatedBooks = books.filter(book => book.id !== bookId)
setBooks(updatedBooks)
}, [books])
// Force refresh by fetching fresh data
const refetch = useCallback(() => {
hasFetched.current = false
fetchBooks()
}, [])
return {
books,
loading,
error,
getBook,
getRecentBooks,
addBook,
updateBook,
deleteBook,
refetch
}
}