✏️ Fix request Modal

This commit is contained in:
ajnart
2022-08-08 13:45:36 +02:00
parent f9caf6ef26
commit b430e24cdb

View File

@@ -1,8 +1,19 @@
import { Alert, Checkbox, createStyles, Group, LoadingOverlay, Stack, Table } from '@mantine/core'; import {
Alert,
Button,
Checkbox,
createStyles,
Group,
LoadingOverlay,
Modal,
Stack,
Table,
} from '@mantine/core';
import { openConfirmModal } from '@mantine/modals'; import { openConfirmModal } from '@mantine/modals';
import { showNotification, updateNotification } from '@mantine/notifications'; import { showNotification, updateNotification } from '@mantine/notifications';
import { IconAlertCircle, IconCheck, IconDownload } from '@tabler/icons'; import { IconAlertCircle, IconCheck, IconDownload } from '@tabler/icons';
import axios from 'axios'; import axios from 'axios';
import Consola from 'consola';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { useColorTheme } from '../../tools/color'; import { useColorTheme } from '../../tools/color';
import { MovieResult } from './Movie.d'; import { MovieResult } from './Movie.d';
@@ -11,6 +22,8 @@ import { TvShowResult, TvShowResultSeason } from './TvShow.d';
interface RequestModalProps { interface RequestModalProps {
base: Result; base: Result;
opened: boolean;
setOpened: (opened: boolean) => void;
} }
const useStyles = createStyles((theme) => ({ const useStyles = createStyles((theme) => ({
@@ -22,43 +35,53 @@ const useStyles = createStyles((theme) => ({
}, },
})); }));
export default function RequestModal({ base }: RequestModalProps) { export function RequestModal({ base, opened, setOpened }: RequestModalProps) {
const [result, setResult] = useState<MovieResult | TvShowResult>(); const [result, setResult] = useState<MovieResult | TvShowResult>();
const { secondaryColor } = useColorTheme();
useEffect(() => { function getResults(base: Result) {
// Use the overseerr API get the media info.
axios.get(`/api/modules/overseerr/${base.id}?type=${base.mediaType}`).then((res) => { axios.get(`/api/modules/overseerr/${base.id}?type=${base.mediaType}`).then((res) => {
setResult(res.data); setResult(res.data);
}); });
}, [base]); }
if (opened && !result) {
const { secondaryColor } = useColorTheme(); getResults(base);
if (!result) { }
return <LoadingOverlay color={secondaryColor} visible />; if (!result || !opened) {
return null;
} }
return base.mediaType === 'movie' ? ( return base.mediaType === 'movie' ? (
<MovieRequestModal result={result as MovieResult} /> <MovieRequestModal result={result as MovieResult} opened={opened} setOpened={setOpened} />
) : ( ) : (
<TvRequestModal result={result as TvShowResult} /> <TvRequestModal result={result as TvShowResult} opened={opened} setOpened={setOpened} />
); );
} }
function MovieRequestModal({ result }: { result: MovieResult }) { export function MovieRequestModal({
result,
opened,
setOpened,
}: {
result: MovieResult;
opened: boolean;
setOpened: (opened: boolean) => void;
}) {
const { secondaryColor } = useColorTheme(); const { secondaryColor } = useColorTheme();
openConfirmModal({ return (
title: ( <Modal
<Group> onClose={() => setOpened(false)}
<IconDownload /> radius="lg"
Ask for {result.title} size="lg"
</Group> trapFocus
), zIndex={150}
radius: 'lg', withinPortal
labels: { confirm: 'Request', cancel: 'Cancel' }, opened={opened}
onConfirm: () => { title={
askForMedia(MediaType.Movie, result.id, result.title); <Group>
}, <IconDownload />
size: 'lg', Ask for {result.title}
children: ( </Group>
}
>
<Stack> <Stack>
<Alert <Alert
icon={<IconAlertCircle size={16} />} icon={<IconAlertCircle size={16} />}
@@ -69,13 +92,30 @@ function MovieRequestModal({ result }: { result: MovieResult }) {
> >
This request will be automatically approved This request will be automatically approved
</Alert> </Alert>
<Group>
<Button onClick={() => setOpened(false)}>Cancel</Button>
<Button
onClick={() => {
askForMedia(MediaType.Movie, result.id, result.title, []);
}}
>
Request
</Button>
</Group>
</Stack> </Stack>
), </Modal>
}); );
return null;
} }
function TvRequestModal({ result }: { result: TvShowResult }) { export function TvRequestModal({
result,
opened,
setOpened,
}: {
result: TvShowResult;
opened: boolean;
setOpened: (opened: boolean) => void;
}) {
const [selection, setSelection] = useState<TvShowResultSeason[]>(result.seasons); const [selection, setSelection] = useState<TvShowResultSeason[]>(result.seasons);
const { classes, cx } = useStyles(); const { classes, cx } = useStyles();
@@ -107,28 +147,8 @@ function TvRequestModal({ result }: { result: TvShowResult }) {
}); });
const { secondaryColor } = useColorTheme(); const { secondaryColor } = useColorTheme();
openConfirmModal({ return (
title: ( <Modal onClose={() => setOpened(false)} radius="lg" size="lg" opened={opened}>
<Group>
<IconDownload />
Ask for {result.name}
</Group>
),
radius: 'lg',
labels: { confirm: 'Request', cancel: 'Cancel' },
confirmProps: {
disabled: selection.length === 0,
},
onConfirm: () => {
askForMedia(
MediaType.Tv,
result.id,
result.name,
selection.map((s) => s.seasonNumber)
);
},
size: 'lg',
children: (
<Stack> <Stack>
<Alert <Alert
icon={<IconAlertCircle size={16} />} icon={<IconAlertCircle size={16} />}
@@ -157,13 +177,29 @@ function TvRequestModal({ result }: { result: TvShowResult }) {
</thead> </thead>
<tbody>{rows}</tbody> <tbody>{rows}</tbody>
</Table> </Table>
<Group>
<Button onClick={() => setOpened(false)}>Cancel</Button>
<Button
disabled={selection.length === 0}
onClick={() => {
askForMedia(
MediaType.Tv,
result.id,
result.name,
selection.map((s) => s.seasonNumber)
);
}}
>
Request
</Button>
</Group>
</Stack> </Stack>
), </Modal>
}); );
return null;
} }
function askForMedia(type: MediaType, id: number, name: string, seasons?: number[]) { function askForMedia(type: MediaType, id: number, name: string, seasons?: number[]) {
Consola.info(`Requesting ${type} ${id} ${name}`);
showNotification({ showNotification({
title: 'Request', title: 'Request',
id: id.toString(), id: id.toString(),