import { Alert, Button, Checkbox, createStyles, Group, Modal, Stack, Table } from '@mantine/core'; import { showNotification, updateNotification } from '@mantine/notifications'; import { IconAlertCircle, IconCheck, IconDownload } from '@tabler/icons'; import axios from 'axios'; import Consola from 'consola'; import { useTranslation } from 'next-i18next'; import { useState } from 'react'; import { useColorTheme } from '../../tools/color'; import { MovieResult } from './Movie.d'; import { MediaType, Result } from './SearchResult.d'; import { TvShowResult, TvShowResultSeason } from './TvShow.d'; interface RequestModalProps { base: Result; opened: boolean; setOpened: (opened: boolean) => void; } const useStyles = createStyles((theme) => ({ rowSelected: { backgroundColor: theme.colorScheme === 'dark' ? theme.fn.rgba(theme.colors[theme.primaryColor][7], 0.2) : theme.colors[theme.primaryColor][0], }, })); export function RequestModal({ base, opened, setOpened }: RequestModalProps) { const [result, setResult] = useState(); const { secondaryColor } = useColorTheme(); function getResults(base: Result) { axios.get(`/api/modules/overseerr/${base.id}?type=${base.mediaType}`).then((res) => { setResult(res.data); }); } if (opened && !result) { getResults(base); } if (!result || !opened) { return null; } return base.mediaType === 'movie' ? ( ) : ( ); } export function MovieRequestModal({ result, opened, setOpened, }: { result: MovieResult; opened: boolean; setOpened: (opened: boolean) => void; }) { const { secondaryColor } = useColorTheme(); const { t } = useTranslation('modules/overseerr'); return ( setOpened(false)} radius="lg" size="lg" trapFocus zIndex={150} withinPortal opened={opened} title={ {t('popup.item.buttons.askFor', { title: result.title })} } > } title={t('popup.item.alerts.automaticApproval.title')} color={secondaryColor} radius="md" variant="filled" > {t('popup.item.alerts.automaticApproval.text')} ); } export function TvRequestModal({ result, opened, setOpened, }: { result: TvShowResult; opened: boolean; setOpened: (opened: boolean) => void; }) { const [selection, setSelection] = useState(result.seasons); const { classes, cx } = useStyles(); const { t } = useTranslation('modules/overseerr'); const toggleRow = (container: TvShowResultSeason) => setSelection((current: TvShowResultSeason[]) => current.includes(container) ? current.filter((c) => c !== container) : [...current, container] ); const toggleAll = () => setSelection((current: any) => current.length === result.seasons.length ? [] : result.seasons.map((c) => c) ); const rows = result.seasons.map((element) => { const selected = selection.includes(element); return ( toggleRow(element)} transitionDuration={0} /> {element.name} {element.episodeCount} ); }); const { secondaryColor } = useColorTheme(); return ( setOpened(false)} radius="lg" size="lg" opened={opened} title={ {t('popup.item.buttons.askFor', { title: result.name ?? result.originalName ?? 'a TV show', })} } > } title={t('popup.item.alerts.automaticApproval.title')} color={secondaryColor} radius="md" variant="filled" > {t('popup.item.alerts.automaticApproval.text')} {rows}
{t('popup.seasonSelector.caption')}
0 && selection.length !== result.seasons.length} transitionDuration={0} /> {t('popup.seasonSelector.table.header.season')} {t('popup.seasonSelector.table.header.numberOfEpisodes')}
); } function askForMedia(type: MediaType, id: number, name: string, seasons?: number[]) { Consola.info(`Requesting ${type} ${id} ${name}`); showNotification({ title: 'Request', id: id.toString(), message: `Requesting media ${name}`, color: 'orange', loading: true, autoClose: false, withCloseButton: false, icon: , }); axios .post(`/api/modules/overseerr/${id}`, { type, seasons }) .then(() => { updateNotification({ id: id.toString(), title: '', color: 'green', message: ` ${name} requested`, icon: , autoClose: 2000, }); }) .catch((err) => { updateNotification({ id: id.toString(), color: 'red', title: 'There was an error', message: err.message, autoClose: 2000, }); }); }