mirror of
https://github.com/fallenbagel/jellyseerr.git
synced 2026-01-02 04:39:14 -05:00
feat(requests): add request quotas (#1277)
* feat(quotas): rebased * feat: add getQuota() method to User entity * feat(ui): add default quota setting options * feat: user quota settings * feat: quota display in request modals * fix: only show user quotas on own profile or with manage users permission * feat: add request progress circles to profile page * feat: add migration * fix: add missing restricted field to api schema * fix: dont show auto approve message for movie request when restricted * fix(lang): change enable checkbox langauge to "enable override" Co-authored-by: Jakob Ankarhem <jakob.ankarhem@outlook.com> Co-authored-by: TheCatLady <52870424+TheCatLady@users.noreply.github.com>
This commit is contained in:
94
src/components/QuotaSelector/index.tsx
Normal file
94
src/components/QuotaSelector/index.tsx
Normal file
@@ -0,0 +1,94 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
|
||||
const messages = defineMessages({
|
||||
movieRequestLimit: '{quotaLimit} movies per {quotaDays} days',
|
||||
tvRequestLimit: '{quotaLimit} seasons per {quotaDays} days',
|
||||
unlimited: 'Unlimited',
|
||||
});
|
||||
|
||||
interface QuotaSelectorProps {
|
||||
mediaType: 'movie' | 'tv';
|
||||
defaultDays?: number;
|
||||
defaultLimit?: number;
|
||||
dayOverride?: number;
|
||||
limitOverride?: number;
|
||||
dayFieldName: string;
|
||||
limitFieldName: string;
|
||||
isDisabled?: boolean;
|
||||
onChange: (fieldName: string, value: number) => void;
|
||||
}
|
||||
|
||||
const QuotaSelector: React.FC<QuotaSelectorProps> = ({
|
||||
mediaType,
|
||||
dayFieldName,
|
||||
limitFieldName,
|
||||
defaultDays = 7,
|
||||
defaultLimit = 0,
|
||||
dayOverride,
|
||||
limitOverride,
|
||||
isDisabled = false,
|
||||
onChange,
|
||||
}) => {
|
||||
const initialDays = defaultDays ?? 7;
|
||||
const initialLimit = defaultLimit ?? 0;
|
||||
const [quotaDays, setQuotaDays] = useState(initialDays);
|
||||
const [quotaLimit, setQuotaLimit] = useState(initialLimit);
|
||||
const intl = useIntl();
|
||||
|
||||
useEffect(() => {
|
||||
onChange(dayFieldName, quotaDays);
|
||||
}, [dayFieldName, onChange, quotaDays]);
|
||||
|
||||
useEffect(() => {
|
||||
onChange(limitFieldName, quotaLimit);
|
||||
}, [limitFieldName, onChange, quotaLimit]);
|
||||
|
||||
return (
|
||||
<div className={`${isDisabled ? 'opacity-50' : ''}`}>
|
||||
{intl.formatMessage(
|
||||
mediaType === 'movie'
|
||||
? messages.movieRequestLimit
|
||||
: messages.tvRequestLimit,
|
||||
{
|
||||
quotaLimit: (
|
||||
<select
|
||||
className="inline short"
|
||||
value={limitOverride ?? quotaLimit}
|
||||
onChange={(e) => setQuotaLimit(Number(e.target.value))}
|
||||
disabled={isDisabled}
|
||||
>
|
||||
<option value="0">
|
||||
{intl.formatMessage(messages.unlimited)}
|
||||
</option>
|
||||
<option value="1">1</option>
|
||||
<option value="2">2</option>
|
||||
<option value="5">5</option>
|
||||
<option value="10">10</option>
|
||||
<option value="25">25</option>
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
</select>
|
||||
),
|
||||
quotaDays: (
|
||||
<select
|
||||
className="inline short"
|
||||
value={dayOverride ?? quotaDays}
|
||||
onChange={(e) => setQuotaDays(Number(e.target.value))}
|
||||
disabled={isDisabled}
|
||||
>
|
||||
<option value="1">1</option>
|
||||
<option value="7">7</option>
|
||||
<option value="14">14</option>
|
||||
<option value="30">30</option>
|
||||
<option value="60">60</option>
|
||||
<option value="90">90</option>
|
||||
</select>
|
||||
),
|
||||
}
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(QuotaSelector);
|
||||
Reference in New Issue
Block a user