import React, { ReactElement } from "react"; import Header from "../shared/Header"; import { GetLibraryStatisticsQuery, DirectorySize } from "../../graphql/generated"; type Stats = Omit & { comicDirectorySize: DirectorySize; comicsMissingFiles: number; }; /** Props for {@link LibraryStatistics}. */ interface LibraryStatisticsProps { stats: Stats | null | undefined; } /** * Displays a snapshot of library metrics: total comic files, tagging coverage, * file-type breakdown, and the publisher with the most issues. * * Returns `null` when `stats` is absent or the statistics array is empty. */ export const LibraryStatistics = ({ stats }: LibraryStatisticsProps): ReactElement | null => { if (!stats || !stats.totalDocuments) return null; const facet = stats.statistics?.[0]; if (!facet) return null; const { issues, issuesWithComicInfoXML, fileTypes, publisherWithMostComicsInLibrary } = facet; const topPublisher = publisherWithMostComicsInLibrary?.[0]; return (
{/* TODO: Switch iconClassNames to Solar icon */}
A brief snapshot of your library.} iconClassNames="fa-solid fa-binoculars mr-2" />
{/* Total records in database */}
In database
{stats.totalDocuments} comics
{/* Missing files */}
Missing files
{stats.comicsMissingFiles}
{/* Disk space consumed */} {stats.comicDirectorySize.totalSizeInGB != null && (
Size on disk
{stats.comicDirectorySize.totalSizeInGB.toFixed(2)} GB
)} {/* Tagging coverage */}
{issues && issues.length > 0 && (
{issues.length} tagged with ComicVine
)} {issuesWithComicInfoXML && issuesWithComicInfoXML.length > 0 && (
{issuesWithComicInfoXML.length} with ComicInfo.xml
)}
{/* File-type breakdown */} {fileTypes && fileTypes.length > 0 && (
{fileTypes.map((ft) => ( {ft.data.length} {ft.id} ))}
)} {/* Publisher with most issues */} {topPublisher && (
{topPublisher.id} {" has the most issues "} {topPublisher.count}
)}
); }; export default LibraryStatistics;