import { useMemo } from "react"; import { ActionIcon, Anchor, Avatar, Badge, Card, Group, Image, ScrollArea, Stack, Text, Tooltip } from "@mantine/core"; import { IconThumbDown, IconThumbUp } from "@tabler/icons-react"; import { clientApi } from "@homarr/api/client"; import { MediaAvailability, MediaRequestStatus } from "@homarr/integrations/types"; import type { ScopedTranslationFunction } from "@homarr/translation"; import { useScopedI18n } from "@homarr/translation/client"; import type { WidgetComponentProps } from "../../definition"; import { NoIntegrationSelectedError } from "../../errors"; import { NoIntegrationDataError } from "../../errors/no-data-integration"; export default function MediaServerWidget({ integrationIds, isEditMode, options, serverData, itemId, }: WidgetComponentProps<"mediaRequests-requestList">) { const t = useScopedI18n("widget.mediaRequests-requestList"); const isQueryEnabled = Boolean(itemId); const { data: mediaRequests, isError: _isError } = clientApi.widget.mediaRequests.getLatestRequests.useQuery( { integrationIds, // eslint-disable-next-line @typescript-eslint/no-non-null-assertion itemId: itemId!, }, { initialData: !serverData ? undefined : serverData.initialData, refetchOnMount: false, refetchOnWindowFocus: false, refetchOnReconnect: false, enabled: integrationIds.length > 0 && isQueryEnabled, }, ); const sortedMediaRequests = useMemo( () => mediaRequests ?.filter((group) => group != null) .flatMap((group) => group.data) .flatMap(({ medias, integration }) => medias.map((media) => ({ ...media, integrationId: integration.id }))) .sort(({ status: statusA }, { status: statusB }) => { if (statusA === MediaRequestStatus.PendingApproval) { return -1; } if (statusB === MediaRequestStatus.PendingApproval) { return 1; } return 0; }) ?? [], [mediaRequests, integrationIds], ); const { mutate: mutateRequestAnswer } = clientApi.widget.mediaRequests.answerRequest.useMutation(); if (integrationIds.length === 0) throw new NoIntegrationSelectedError(); if (sortedMediaRequests.length === 0) throw new NoIntegrationDataError(); return ( {sortedMediaRequests.map((mediaRequest) => ( {mediaRequest.airDate?.getFullYear() ?? t("toBeDetermined")} {getAvailabilityProperties(mediaRequest.availability, t).label} {mediaRequest.name || "unknown"} {(mediaRequest.requestedBy?.displayName ?? "") || "unknown"} {mediaRequest.status === MediaRequestStatus.PendingApproval && ( { mutateRequestAnswer({ integrationId: mediaRequest.integrationId, requestId: mediaRequest.id, answer: "approve", }); }} > { mutateRequestAnswer({ integrationId: mediaRequest.integrationId, requestId: mediaRequest.id, answer: "decline", }); }} > )} ))} ); } function getAvailabilityProperties( mediaRequestAvailability: MediaAvailability, t: ScopedTranslationFunction<"widget.mediaRequests-requestList">, ) { switch (mediaRequestAvailability) { case MediaAvailability.Available: return { color: "green", label: t("availability.available") }; case MediaAvailability.PartiallyAvailable: return { color: "yellow", label: t("availability.partiallyAvailable") }; case MediaAvailability.Pending: return { color: "violet", label: t("availability.pending") }; case MediaAvailability.Processing: return { color: "blue", label: t("availability.processing") }; default: return { color: "red", label: t("availability.unknown") }; } }