You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
overseerr/src/components/RequestModal/QuotaDisplay/index.tsx

150 lines
5.2 KiB

import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/solid';
import Link from 'next/link';
import React, { useState } from 'react';
import { defineMessages, useIntl } from 'react-intl';
import type { QuotaStatus } from '../../../../server/interfaces/api/userInterfaces';
import ProgressCircle from '../../Common/ProgressCircle';
const messages = defineMessages({
requestsremaining:
'{remaining, plural, =0 {No} other {<strong>#</strong>}} {type} {remaining, plural, one {request} other {requests}} remaining',
movielimit: '{limit, plural, one {movie} other {movies}}',
seasonlimit: '{limit, plural, one {season} other {seasons}}',
allowedRequests:
'You are allowed to request <strong>{limit}</strong> {type} every <strong>{days}</strong> days.',
allowedRequestsUser:
'This user is allowed to request <strong>{limit}</strong> {type} every <strong>{days}</strong> days.',
quotaLink:
'You can view a summary of your request limits on your <ProfileLink>profile page</ProfileLink>.',
quotaLinkUser:
"You can view a summary of this user's request limits on their <ProfileLink>profile page</ProfileLink>.",
movie: 'movie',
season: 'season',
notenoughseasonrequests: 'Not enough season requests remaining',
requiredquota:
'You need to have at least <strong>{seasons}</strong> {seasons, plural, one {season request} other {season requests}} remaining in order to submit a request for this series.',
requiredquotaUser:
'This user needs to have at least <strong>{seasons}</strong> {seasons, plural, one {season request} other {season requests}} remaining in order to submit a request for this series.',
});
interface QuotaDisplayProps {
quota?: QuotaStatus;
mediaType: 'movie' | 'tv';
userOverride?: number | null;
remaining?: number;
overLimit?: number;
}
const QuotaDisplay = ({
quota,
mediaType,
userOverride,
remaining,
overLimit,
}: QuotaDisplayProps) => {
const intl = useIntl();
const [showDetails, setShowDetails] = useState(false);
return (
<div
className="my-4 flex flex-col rounded-md bg-gray-800 p-4"
onClick={() => setShowDetails((s) => !s)}
onKeyDown={(e) => {
if (e.key === 'Enter') {
setShowDetails((s) => !s);
}
}}
role="button"
tabIndex={0}
>
<div className="flex items-center">
<ProgressCircle
className="h-8 w-8"
progress={Math.round(
((remaining ?? quota?.remaining ?? 0) / (quota?.limit ?? 1)) * 100
)}
useHeatLevel
/>
<div
className={`flex items-end ${
(remaining ?? quota?.remaining ?? 0) <= 0 || quota?.restricted
? 'text-red-500'
: ''
}`}
>
<div className="ml-2 text-lg">
{overLimit !== undefined
? intl.formatMessage(messages.notenoughseasonrequests)
: intl.formatMessage(messages.requestsremaining, {
remaining: remaining ?? quota?.remaining ?? 0,
type: intl.formatMessage(
mediaType === 'movie' ? messages.movie : messages.season
),
strong: (msg: React.ReactNode) => <strong>{msg}</strong>,
})}
</div>
</div>
<div className="flex flex-1 justify-end">
{showDetails ? (
<ChevronUpIcon className="h-6 w-6" />
) : (
<ChevronDownIcon className="h-6 w-6" />
)}
</div>
</div>
{showDetails && (
<div className="mt-4">
{overLimit !== undefined && (
<div className="mb-2">
{intl.formatMessage(
userOverride
? messages.requiredquotaUser
: messages.requiredquota,
{
seasons: overLimit,
strong: (msg: React.ReactNode) => <strong>{msg}</strong>,
}
)}
</div>
)}
<div>
{intl.formatMessage(
userOverride
? messages.allowedRequestsUser
: messages.allowedRequests,
{
limit: quota?.limit,
days: quota?.days,
type: intl.formatMessage(
mediaType === 'movie'
? messages.movielimit
: messages.seasonlimit,
{ limit: quota?.limit }
),
strong: (msg: React.ReactNode) => <strong>{msg}</strong>,
}
)}
</div>
<div className="mt-2">
{intl.formatMessage(
userOverride ? messages.quotaLinkUser : messages.quotaLink,
{
ProfileLink: (msg: React.ReactNode) => (
<Link
href={userOverride ? `/users/${userOverride}` : '/profile'}
>
<a className="text-white transition duration-300 hover:underline">
{msg}
</a>
</Link>
),
}
)}
</div>
</div>
)}
</div>
);
};
export default QuotaDisplay;