74588e50f6
Break the 615-line UserDetail.tsx into focused sub-components (header, stat cards, activity chart, request history, open alerts) and extract shared utilities to lib/ (format, userChart, enrichRequests). Promote storage load (GB/hr) to a stat card and collapse the chart UX to a single metric picker. Add server-wide average reference line alongside the user's own on every metric, and link request titles to their Seerr pages. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
47 lines
1.3 KiB
TypeScript
47 lines
1.3 KiB
TypeScript
import { OverseerrRequest, MediaEntry, EnrichedRequest } from "@/lib/types";
|
|
import { bytesToGB } from "@/lib/aggregate";
|
|
|
|
export function enrichRequests(
|
|
userRequests: OverseerrRequest[],
|
|
radarrMap: Map<number, MediaEntry>,
|
|
sonarrMap: Map<number, MediaEntry>,
|
|
seerrBaseUrl?: string
|
|
): EnrichedRequest[] {
|
|
return userRequests.map((req) => {
|
|
let sizeOnDisk = 0;
|
|
let title = req.media.title ?? "";
|
|
|
|
if (req.type === "movie") {
|
|
const entry = radarrMap.get(req.media.tmdbId);
|
|
sizeOnDisk = entry?.sizeOnDisk ?? 0;
|
|
if (entry?.title) title = entry.title;
|
|
} else if (req.type === "tv" && req.media.tvdbId) {
|
|
const entry = sonarrMap.get(req.media.tvdbId);
|
|
sizeOnDisk = entry?.sizeOnDisk ?? 0;
|
|
if (entry?.title) title = entry.title;
|
|
}
|
|
|
|
if (!title) {
|
|
title = req.type === "movie"
|
|
? `Movie #${req.media.tmdbId}`
|
|
: `Show #${req.media.tmdbId}`;
|
|
}
|
|
|
|
const seerrUrl = seerrBaseUrl
|
|
? `${seerrBaseUrl}/${req.type === "movie" ? "movie" : "tv"}/${req.media.tmdbId}`
|
|
: undefined;
|
|
|
|
return {
|
|
id: req.id,
|
|
type: req.type,
|
|
status: req.status,
|
|
createdAt: req.createdAt,
|
|
mediaId: req.type === "movie" ? req.media.tmdbId : (req.media.tvdbId ?? 0),
|
|
title,
|
|
sizeOnDisk,
|
|
sizeGB: bytesToGB(sizeOnDisk),
|
|
seerrUrl,
|
|
};
|
|
});
|
|
}
|