- {shelves.length} {shelves.length === 1 ? 'shelf' : 'shelves'} connected + {shelves.length} {shelves.length === 1 ? 'shelf' : 'shelves'}{' '} + connected
)}- Link a Goodreads shelf and we'll automatically request the audiobook for every book you add. + Link a Goodreads or Hardcover shelf and we'll automatically request the + audiobook for every book you add.
@@ -166,7 +233,7 @@ function ShelfCardSkeleton({ squareCovers }: { squareCovers: boolean }) { key={i} className={cn( 'rounded-xl bg-gray-100 dark:bg-gray-700/40 animate-pulse flex-shrink-0 ring-2 ring-white dark:ring-gray-800', - squareCovers ? 'w-[80px] h-[80px]' : 'w-[72px] h-[108px]' + squareCovers ? 'w-[80px] h-[80px]' : 'w-[72px] h-[108px]', )} style={{ marginLeft: i > 0 ? '-16px' : 0, zIndex: 5 - i }} /> @@ -179,13 +246,14 @@ function ShelfCardSkeleton({ squareCovers }: { squareCovers: boolean }) { /* ─── Shelf Card ─── */ interface ShelfCardProps { - shelf: GoodreadsShelf; + shelf: GenericShelf; squareCovers: boolean; isDeleting: boolean; isConfirmingDelete: boolean; onDelete: () => void; onConfirmDelete: () => void; onCancelDelete: () => void; + onManage: () => void; onBookClick: (asin: string) => void; } @@ -197,20 +265,44 @@ function ShelfCard({ onDelete, onConfirmDelete, onCancelDelete, + onManage, onBookClick, }: ShelfCardProps) { const displayBooks = shelf.books.slice(0, 6); const hasCovers = displayBooks.length > 0; - const remainingCount = Math.max(0, (shelf.bookCount || 0) - displayBooks.length); + const remainingCount = Math.max( + 0, + (shelf.bookCount || 0) - displayBooks.length, + ); const isSyncing = !shelf.lastSyncAt; + const providerIcon = + shelf.type === 'goodreads' ? ( +- Paste your Goodreads shelf RSS URL. Books will be automatically requested as audiobooks during each sync. -
-{successMessage}
-{error}
-+ Paste your Goodreads shelf RSS URL. Books will be automatically requested. +
+ > + ) : ( + <> ++ Connect a Hardcover reading list and books will be automatically requested as you add them. +
+ > + )} +{successMessage}
+{currentError}
+{validationError}
+ )} ++ Found under{' '} + Settings → API + {' '}on hardcover.app. Stored securely and never shared. +
++ Which list should we watch? +
++ Choose a reading status or one of your custom lists. +
+Status to sync
+
+ Paste the list URL from Hardcover, or enter just the slug (e.g.{' '}
+ my-audiobooks
+ ) or a numeric ID.
+
{currentError}
+