"use client";
import { ActionIcon, Avatar, Badge, Box, Card, Grid, Group, ScrollArea, Stack, Text, Tooltip } from "@mantine/core";
import type { Icon } from "@tabler/icons-react";
import {
IconDeviceTv,
IconHourglass,
IconLoaderQuarter,
IconMovie,
IconPlayerPlay,
IconReceipt,
IconSearch,
IconThumbDown,
IconThumbUp,
} from "@tabler/icons-react";
import combineClasses from "clsx";
import { clientApi } from "@homarr/api/client";
import { useRequiredBoard } from "@homarr/boards/context";
import type { RequestStats } from "@homarr/integrations/types";
import { openMediaRequestSearch } from "@homarr/spotlight";
import { useI18n } from "@homarr/translation/client";
import { WidgetEmptyState } from "../../common/empty-state";
import { getSafeApplicationUrl, SAFE_NEW_TAB_REL } from "../../common/application-url";
import { getUsableWidgetQueryData, isInitialWidgetQueryPending } from "../../common/query-state";
import { WidgetQueryLoadingState } from "../../common/query-state-indicator";
import actionTargetClasses from "../../common/action-target.module.css";
import { IntegrationErrorIndicator } from "../../common/integration-error-indicator";
import type { WidgetComponentProps } from "../../definition";
import { NoIntegrationDataError } from "../../errors/no-data-integration";
import classes from "./component.module.css";
import searchClasses from "../search-button.module.css";
const OVERSEERR_COLOR = "#ECB000";
const JELLYSEERR_COLOR = "#6677CC";
export default function MediaServerWidget({
integrationIds,
isEditMode,
width,
height,
}: WidgetComponentProps<"mediaRequests-requestStats">) {
const t = useI18n("widget.mediaRequests-requestStats");
const tCommon = useI18n("common");
const requestStatsQuery = clientApi.widget.mediaRequests.getStats.useQuery({ integrationIds });
const requestStats = getUsableWidgetQueryData(requestStatsQuery);
const board = useRequiredBoard();
if (isInitialWidgetQueryPending(requestStatsQuery)) return ;
if (!requestStats) return ;
if (
requestStats.users.length === 0 &&
requestStats.stats.length === 0 &&
requestStats.failedIntegrations.length === 0
)
throw new NoIntegrationDataError();
const data = [
{
name: "approved",
icon: IconThumbUp,
number: requestStats.stats.reduce((count, { approved }) => count + approved, 0),
},
{
name: "pending",
icon: IconHourglass,
number: requestStats.stats.reduce((count, { pending }) => count + pending, 0),
},
{
name: "processing",
icon: IconLoaderQuarter,
number: requestStats.stats.reduce((count, { processing }) => count + processing, 0),
},
{
name: "declined",
icon: IconThumbDown,
number: requestStats.stats.reduce((count, { declined }) => count + declined, 0),
},
{
name: "available",
icon: IconPlayerPlay,
number: requestStats.stats.reduce((count, { available }) => count + available, 0),
},
{
name: "tv",
icon: IconDeviceTv,
number: requestStats.stats.reduce((count, { tv }) => count + tv, 0),
},
{
name: "movie",
icon: IconMovie,
number: requestStats.stats.reduce((count, { movie }) => count + movie, 0),
},
{
name: "total",
icon: IconReceipt,
number: requestStats.stats.reduce((count, { total }) => count + total, 0),
},
] satisfies { name: keyof RequestStats; icon: Icon; number: number }[];
const isTiny = width < 256;
const showIntegrationLegend = requestStats.integrations.length > 1 && height >= 240;
return (
{!isEditMode && }
{t("titles.stats.main")}
{data.map((stat) => (
{stat.number}
))}
{t("titles.users.main")} ({t("titles.users.requests")})
{requestStats.users.map((user) => {
const href = getSafeApplicationUrl(user.link);
return (
{user.displayName}
{user.requestCount}
);
})}
{showIntegrationLegend && (
{requestStats.integrations.map((integration) => (
{integration.name}
))}
)}
);
}
const MediaRequestSearchButton = ({ integrationIds }: { integrationIds: string[] }) => {
const t = useI18n("search.mode.media");
return (
openMediaRequestSearch({ integrationIds })}
>
);
};