diff --git a/src/components/MovieDetails/index.tsx b/src/components/MovieDetails/index.tsx index e00d194fb..d34681047 100644 --- a/src/components/MovieDetails/index.tsx +++ b/src/components/MovieDetails/index.tsx @@ -4,6 +4,7 @@ import { defineMessages, FormattedNumber, FormattedDate, + useIntl, } from 'react-intl'; import type { MovieDetails as MovieDetailsType } from '../../../server/models/Movie'; import useSWR from 'swr'; @@ -20,6 +21,8 @@ import TitleCard from '../TitleCard'; import PersonCard from '../PersonCard'; import { LanguageContext } from '../../context/LanguageContext'; import LoadingSpinner from '../Common/LoadingSpinner'; +import { useUser, Permission } from '../../hooks/useUser'; +import PendingRequest from '../PendingRequest'; const messages = defineMessages({ releasedate: 'Release Date', @@ -33,6 +36,12 @@ const messages = defineMessages({ cast: 'Cast', recommendations: 'Recommendations', similar: 'Similar Titles', + cancelrequest: 'Cancel Request', + available: 'Available', + unavailable: 'Unavailable', + request: 'Request', + pending: 'Pending', + overviewunavailable: 'Overview unavailable', }); interface MovieDetailsProps { @@ -54,7 +63,9 @@ enum MediaRequestStatus { } const MovieDetails: React.FC = ({ movie }) => { + const { user, hasPermission } = useUser(); const router = useRouter(); + const intl = useIntl(); const { locale } = useContext(LanguageContext); const { addToast } = useToasts(); const [showRequestModal, setShowRequestModal] = useState(false); @@ -175,13 +186,16 @@ const MovieDetails: React.FC = ({ movie }) => { d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" /> - Request + )} {data.request?.status === MediaRequestStatus.PENDING && ( )} {data.request?.status === MediaRequestStatus.APPROVED && ( @@ -216,7 +232,7 @@ const MovieDetails: React.FC = ({ movie }) => { d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" /> - Unavailable + )} {data.request?.status === MediaRequestStatus.AVAILABLE && ( @@ -235,7 +251,7 @@ const MovieDetails: React.FC = ({ movie }) => { d="M5 13l4 4L19 7" /> - Available + )} - + {hasPermission(Permission.MANAGE_REQUESTS) && ( + + )}
+ {data.request?.status === MediaRequestStatus.PENDING && + hasPermission(Permission.MANAGE_REQUESTS) && ( + revalidate()} + /> + )}

-

{data.overview}

+

+ {data.overview + ? data.overview + : intl.formatMessage(messages.overviewunavailable)} +

diff --git a/src/components/PendingRequest/index.tsx b/src/components/PendingRequest/index.tsx new file mode 100644 index 000000000..b7bcb3b5a --- /dev/null +++ b/src/components/PendingRequest/index.tsx @@ -0,0 +1,108 @@ +import React, { useState } from 'react'; +import { FormattedMessage, useIntl, defineMessages } from 'react-intl'; +import Button from '../Common/Button'; +import { MediaRequest } from '../../../server/entity/MediaRequest'; +import axios from 'axios'; + +const messages = defineMessages({ + pendingtitle: 'Pending Request', + pendingdescription: + 'This title was requested by {username} ({email}) on {date}', + approve: 'Approve', + decline: 'Decline', +}); + +interface PendingRequestProps { + request: MediaRequest; + onUpdate: () => void; +} + +const PendingRequest: React.FC = ({ + request, + onUpdate, +}) => { + const intl = useIntl(); + const [isLoading, setLoading] = useState(false); + + const updateStatus = async (status: 'approve' | 'decline') => { + setLoading(true); + const response = await axios.get(`/api/v1/request/${request.id}/${status}`); + + if (response.data) { + onUpdate(); + setLoading(false); + } + }; + + return ( +
+
+

+ +

+
+

+ +

+
+
+ + + + + + +
+
+
+ ); +}; + +export default PendingRequest; diff --git a/src/i18n/locale/en.json b/src/i18n/locale/en.json index 37cfb45c4..3f6608fd6 100644 --- a/src/i18n/locale/en.json +++ b/src/i18n/locale/en.json @@ -9,17 +9,27 @@ "components.Layout.Sidebar.dashboard": "Dashboard", "components.Layout.Sidebar.requests": "Requests", "components.Layout.Sidebar.settings": "Settings", + "components.MovieDetails.available": "Available", "components.MovieDetails.budget": "Budget", + "components.MovieDetails.cancelrequest": "Cancel Request", "components.MovieDetails.cast": "Cast", "components.MovieDetails.originallanguage": "Original Language", "components.MovieDetails.overview": "Overview", + "components.MovieDetails.overviewunavailable": "Overview unavailable", + "components.MovieDetails.pending": "Pending", "components.MovieDetails.recommendations": "Recommendations", "components.MovieDetails.releasedate": "Release Date", + "components.MovieDetails.request": "Request", "components.MovieDetails.revenue": "Revenue", "components.MovieDetails.runtime": "{minutes} minutes", "components.MovieDetails.similar": "Similar Titles", "components.MovieDetails.status": "Status", + "components.MovieDetails.unavailable": "Unavailable", "components.MovieDetails.userrating": "User Rating", + "components.PendingRequest.approve": "Approve", + "components.PendingRequest.decline": "Decline", + "components.PendingRequest.pendingdescription": "This title was requested by {username} ({email}) on {date}", + "components.PendingRequest.pendingtitle": "Pending Request", "components.RequestModal.cancelrequest": "This will remove your request. Are you sure you want to continue?", "components.RequestModal.requestadmin": "Your request will be immediately approved. Do you wish to continue?" } diff --git a/src/i18n/locale/ja.json b/src/i18n/locale/ja.json index 78bd888a8..a3f9f7062 100644 --- a/src/i18n/locale/ja.json +++ b/src/i18n/locale/ja.json @@ -9,17 +9,27 @@ "components.Layout.Sidebar.dashboard": "ホーム", "components.Layout.Sidebar.requests": "リクエスト", "components.Layout.Sidebar.settings": "設定", + "components.MovieDetails.available": "", "components.MovieDetails.budget": "興行収入", + "components.MovieDetails.cancelrequest": "チャンセルリクエスト", "components.MovieDetails.cast": "キャスト", "components.MovieDetails.originallanguage": "言語", "components.MovieDetails.overview": "ストーリー", + "components.MovieDetails.overviewunavailable": "", + "components.MovieDetails.pending": "リクエスト中", "components.MovieDetails.recommendations": "オススメの作品", "components.MovieDetails.releasedate": "公開日", + "components.MovieDetails.request": "リクエストする", "components.MovieDetails.revenue": "製作費", "components.MovieDetails.runtime": "{minutes}分", "components.MovieDetails.similar": "関連作品", "components.MovieDetails.status": "状態", + "components.MovieDetails.unavailable": "", "components.MovieDetails.userrating": "ユーザー評価", + "components.PendingRequest.approve": "", + "components.PendingRequest.decline": "", + "components.PendingRequest.pendingdescription": "", + "components.PendingRequest.pendingtitle": "", "components.RequestModal.cancelrequest": "このリクエストをキャンセルしてよろしいですか?", "components.RequestModal.requestadmin": "このリクエストが今すぐ承認致します。よろしいですか?" }