refactor(css): add styles targeting SVG button/modal icons (#1464)
* refactor(css): add global classes for common icon types * refactor(css): target child SVGs instead of creating new icon classes * fix: fix ButtonWithDropdown style class spacing
This commit is contained in:
@@ -247,7 +247,7 @@ const CollectionDetails: React.FC<CollectionDetailsProps> = ({
|
|||||||
title={intl.formatMessage(
|
title={intl.formatMessage(
|
||||||
is4k ? messages.requestcollection4k : messages.requestcollection
|
is4k ? messages.requestcollection4k : messages.requestcollection
|
||||||
)}
|
)}
|
||||||
iconSvg={<DuplicateIcon className="w-6 h-6" />}
|
iconSvg={<DuplicateIcon />}
|
||||||
>
|
>
|
||||||
<p>
|
<p>
|
||||||
{intl.formatMessage(
|
{intl.formatMessage(
|
||||||
@@ -339,7 +339,7 @@ const CollectionDetails: React.FC<CollectionDetailsProps> = ({
|
|||||||
}}
|
}}
|
||||||
text={
|
text={
|
||||||
<>
|
<>
|
||||||
<DownloadIcon className="w-5 h-5 mr-1" />
|
<DownloadIcon />
|
||||||
<span>
|
<span>
|
||||||
{intl.formatMessage(
|
{intl.formatMessage(
|
||||||
hasRequestable
|
hasRequestable
|
||||||
@@ -364,7 +364,7 @@ const CollectionDetails: React.FC<CollectionDetailsProps> = ({
|
|||||||
setIs4k(true);
|
setIs4k(true);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DownloadIcon className="w-5 h-5 mr-1" />
|
<DownloadIcon />
|
||||||
<span>
|
<span>
|
||||||
{intl.formatMessage(messages.requestcollection4k)}
|
{intl.formatMessage(messages.requestcollection4k)}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -81,16 +81,14 @@ function Button<P extends ElementTypes = 'button'>(
|
|||||||
|
|
||||||
switch (buttonSize) {
|
switch (buttonSize) {
|
||||||
case 'sm':
|
case 'sm':
|
||||||
buttonStyle.push('px-2.5 py-1.5 text-xs');
|
buttonStyle.push('px-2.5 py-1.5 text-xs button-sm');
|
||||||
break;
|
|
||||||
case 'md':
|
|
||||||
buttonStyle.push('px-4 py-2 text-sm');
|
|
||||||
break;
|
break;
|
||||||
case 'lg':
|
case 'lg':
|
||||||
buttonStyle.push('px-6 py-3 text-base');
|
buttonStyle.push('px-6 py-3 text-base button-lg');
|
||||||
break;
|
break;
|
||||||
|
case 'md':
|
||||||
default:
|
default:
|
||||||
buttonStyle.push('px-4 py-2 text-sm');
|
buttonStyle.push('px-4 py-2 text-sm button-md');
|
||||||
}
|
}
|
||||||
|
|
||||||
buttonStyle.push(className ?? '');
|
buttonStyle.push(className ?? '');
|
||||||
|
|||||||
@@ -19,16 +19,16 @@ const DropdownItem: React.FC<DropdownItemProps> = ({
|
|||||||
buttonType = 'primary',
|
buttonType = 'primary',
|
||||||
...props
|
...props
|
||||||
}) => {
|
}) => {
|
||||||
let styleClass = '';
|
let styleClass = 'button-md text-white';
|
||||||
|
|
||||||
switch (buttonType) {
|
switch (buttonType) {
|
||||||
case 'ghost':
|
case 'ghost':
|
||||||
styleClass =
|
styleClass +=
|
||||||
'text-white bg-gray-700 hover:bg-gray-600 hover:text-white focus:border-gray-500 focus:text-white';
|
' bg-gray-700 hover:bg-gray-600 focus:border-gray-500 focus:text-white';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
styleClass =
|
styleClass +=
|
||||||
'text-white bg-indigo-600 hover:bg-indigo-500 hover:text-white focus:border-indigo-700 focus:text-white';
|
' bg-indigo-600 hover:bg-indigo-500 focus:border-indigo-700 focus:text-white';
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<a
|
<a
|
||||||
@@ -60,9 +60,9 @@ const ButtonWithDropdown: React.FC<ButtonWithDropdownProps> = ({
|
|||||||
useClickOutside(buttonRef, () => setIsOpen(false));
|
useClickOutside(buttonRef, () => setIsOpen(false));
|
||||||
|
|
||||||
const styleClasses = {
|
const styleClasses = {
|
||||||
mainButtonClasses: 'text-white border',
|
mainButtonClasses: 'button-md text-white border',
|
||||||
dropdownSideButtonClasses: 'border',
|
dropdownSideButtonClasses: 'button-md border',
|
||||||
dropdownClasses: '',
|
dropdownClasses: 'button-md',
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (buttonType) {
|
switch (buttonType) {
|
||||||
@@ -70,14 +70,14 @@ const ButtonWithDropdown: React.FC<ButtonWithDropdownProps> = ({
|
|||||||
styleClasses.mainButtonClasses +=
|
styleClasses.mainButtonClasses +=
|
||||||
' bg-transparent border-gray-600 hover:border-gray-200 focus:border-gray-100 active:border-gray-100';
|
' bg-transparent border-gray-600 hover:border-gray-200 focus:border-gray-100 active:border-gray-100';
|
||||||
styleClasses.dropdownSideButtonClasses = styleClasses.mainButtonClasses;
|
styleClasses.dropdownSideButtonClasses = styleClasses.mainButtonClasses;
|
||||||
styleClasses.dropdownClasses = 'bg-gray-700';
|
styleClasses.dropdownClasses += ' bg-gray-700';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
styleClasses.mainButtonClasses +=
|
styleClasses.mainButtonClasses +=
|
||||||
' bg-indigo-600 border-indigo-600 hover:bg-indigo-500 hover:border-indigo-500 active:bg-indigo-700 active:border-indigo-700 focus:ring-blue';
|
' bg-indigo-600 border-indigo-600 hover:bg-indigo-500 hover:border-indigo-500 active:bg-indigo-700 active:border-indigo-700 focus:ring-blue';
|
||||||
styleClasses.dropdownSideButtonClasses +=
|
styleClasses.dropdownSideButtonClasses +=
|
||||||
' bg-indigo-700 border-indigo-600 hover:bg-indigo-500 active:bg-indigo-700 focus:ring-blue';
|
' bg-indigo-700 border-indigo-600 hover:bg-indigo-500 active:bg-indigo-700 focus:ring-blue';
|
||||||
styleClasses.dropdownClasses = 'bg-indigo-600';
|
styleClasses.dropdownClasses += ' bg-indigo-600';
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -100,11 +100,7 @@ const ButtonWithDropdown: React.FC<ButtonWithDropdownProps> = ({
|
|||||||
aria-label="Expand"
|
aria-label="Expand"
|
||||||
onClick={() => setIsOpen((state) => !state)}
|
onClick={() => setIsOpen((state) => !state)}
|
||||||
>
|
>
|
||||||
{dropdownIcon ? (
|
{dropdownIcon ? dropdownIcon : <ChevronDownIcon />}
|
||||||
dropdownIcon
|
|
||||||
) : (
|
|
||||||
<ChevronDownIcon className="w-5 h-5" />
|
|
||||||
)}
|
|
||||||
</button>
|
</button>
|
||||||
<Transition
|
<Transition
|
||||||
show={isOpen}
|
show={isOpen}
|
||||||
|
|||||||
@@ -108,11 +108,7 @@ const Modal: React.FC<ModalProps> = ({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="sm:flex sm:items-center">
|
<div className="sm:flex sm:items-center">
|
||||||
{iconSvg && (
|
{iconSvg && <div className="modal-icon">{iconSvg}</div>}
|
||||||
<div className="flex items-center justify-center flex-shrink-0 w-12 h-12 mx-auto text-white bg-gray-600 rounded-full sm:mx-0 sm:h-10 sm:w-10">
|
|
||||||
{iconSvg}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div
|
<div
|
||||||
className={`mt-3 text-center sm:mt-0 sm:text-left ${
|
className={`mt-3 text-center sm:mt-0 sm:text-left ${
|
||||||
iconSvg ? 'sm:ml-4' : 'sm:mb-4'
|
iconSvg ? 'sm:ml-4' : 'sm:mb-4'
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ const PlayButton: React.FC<PlayButtonProps> = ({ links }) => {
|
|||||||
text={
|
text={
|
||||||
<>
|
<>
|
||||||
{links[0].svg}
|
{links[0].svg}
|
||||||
{links[0].text}
|
<span>{links[0].text}</span>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@@ -40,7 +40,7 @@ const PlayButton: React.FC<PlayButtonProps> = ({ links }) => {
|
|||||||
buttonType="ghost"
|
buttonType="ghost"
|
||||||
>
|
>
|
||||||
{link.svg}
|
{link.svg}
|
||||||
{link.text}
|
<span>{link.text}</span>
|
||||||
</ButtonWithDropdown.Item>
|
</ButtonWithDropdown.Item>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ const MovieGenreSlider: React.FC = () => {
|
|||||||
<Link href="/discover/movies/genres">
|
<Link href="/discover/movies/genres">
|
||||||
<a className="slider-title">
|
<a className="slider-title">
|
||||||
<span>{intl.formatMessage(messages.moviegenres)}</span>
|
<span>{intl.formatMessage(messages.moviegenres)}</span>
|
||||||
<ArrowCircleRightIcon className="w-6 h-6 ml-2" />
|
<ArrowCircleRightIcon />
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ const TvGenreSlider: React.FC = () => {
|
|||||||
<Link href="/discover/tv/genres">
|
<Link href="/discover/tv/genres">
|
||||||
<a className="slider-title">
|
<a className="slider-title">
|
||||||
<span>{intl.formatMessage(messages.tvgenres)}</span>
|
<span>{intl.formatMessage(messages.tvgenres)}</span>
|
||||||
<ArrowCircleRightIcon className="w-6 h-6 ml-2" />
|
<ArrowCircleRightIcon />
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ const Discover: React.FC = () => {
|
|||||||
<Link href="/requests?filter=all">
|
<Link href="/requests?filter=all">
|
||||||
<a className="slider-title">
|
<a className="slider-title">
|
||||||
<span>{intl.formatMessage(messages.recentrequests)}</span>
|
<span>{intl.formatMessage(messages.recentrequests)}</span>
|
||||||
<ArrowCircleRightIcon className="w-6 h-6 ml-2" />
|
<ArrowCircleRightIcon />
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ const SearchInput: React.FC = () => {
|
|||||||
className="absolute inset-y-0 p-1 m-auto text-gray-400 transition border-none outline-none right-2 h-7 w-7 focus:outline-none focus:border-none hover:text-white"
|
className="absolute inset-y-0 p-1 m-auto text-gray-400 transition border-none outline-none right-2 h-7 w-7 focus:outline-none focus:border-none hover:text-white"
|
||||||
onClick={() => clear()}
|
onClick={() => clear()}
|
||||||
>
|
>
|
||||||
<XCircleIcon className="w-5 h-5" />
|
<XCircleIcon />
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -104,8 +104,10 @@ const LocalLogin: React.FC<LocalLoginProps> = ({ revalidate }) => {
|
|||||||
<span className="inline-flex rounded-md shadow-sm">
|
<span className="inline-flex rounded-md shadow-sm">
|
||||||
<Link href="/resetpassword" passHref>
|
<Link href="/resetpassword" passHref>
|
||||||
<Button as="a" buttonType="ghost">
|
<Button as="a" buttonType="ghost">
|
||||||
<SupportIcon className="w-5 h-5 mr-1" />
|
<SupportIcon />
|
||||||
{intl.formatMessage(messages.forgotpassword)}
|
<span>
|
||||||
|
{intl.formatMessage(messages.forgotpassword)}
|
||||||
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
</span>
|
</span>
|
||||||
@@ -115,10 +117,12 @@ const LocalLogin: React.FC<LocalLoginProps> = ({ revalidate }) => {
|
|||||||
type="submit"
|
type="submit"
|
||||||
disabled={isSubmitting || !isValid}
|
disabled={isSubmitting || !isValid}
|
||||||
>
|
>
|
||||||
<LoginIcon className="w-5 h-5 mr-1" />
|
<LoginIcon />
|
||||||
{isSubmitting
|
<span>
|
||||||
? intl.formatMessage(messages.signingin)
|
{isSubmitting
|
||||||
: intl.formatMessage(messages.signin)}
|
? intl.formatMessage(messages.signingin)
|
||||||
|
: intl.formatMessage(messages.signin)}
|
||||||
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ const MediaSlider: React.FC<MediaSliderProps> = ({
|
|||||||
<Link href={linkUrl}>
|
<Link href={linkUrl}>
|
||||||
<a className="slider-title">
|
<a className="slider-title">
|
||||||
<span>{title}</span>
|
<span>{title}</span>
|
||||||
<ArrowCircleRightIcon className="w-6 h-6 ml-2" />
|
<ArrowCircleRightIcon />
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
|||||||
mediaLinks.push({
|
mediaLinks.push({
|
||||||
text: intl.formatMessage(messages.playonplex),
|
text: intl.formatMessage(messages.playonplex),
|
||||||
url: data.mediaInfo?.plexUrl,
|
url: data.mediaInfo?.plexUrl,
|
||||||
svg: <PlayIcon className="w-5 h-5 mr-1" />,
|
svg: <PlayIcon />,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
|||||||
mediaLinks.push({
|
mediaLinks.push({
|
||||||
text: intl.formatMessage(messages.play4konplex),
|
text: intl.formatMessage(messages.play4konplex),
|
||||||
url: data.mediaInfo?.plexUrl4k,
|
url: data.mediaInfo?.plexUrl4k,
|
||||||
svg: <PlayIcon className="w-5 h-5 mr-1" />,
|
svg: <PlayIcon />,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +142,7 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
|||||||
mediaLinks.push({
|
mediaLinks.push({
|
||||||
text: intl.formatMessage(messages.watchtrailer),
|
text: intl.formatMessage(messages.watchtrailer),
|
||||||
url: trailerUrl,
|
url: trailerUrl,
|
||||||
svg: <FilmIcon className="w-5 h-5 mr-1" />,
|
svg: <FilmIcon />,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,7 +280,7 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
|||||||
className="w-full sm:mb-0"
|
className="w-full sm:mb-0"
|
||||||
buttonType="success"
|
buttonType="success"
|
||||||
>
|
>
|
||||||
<CheckCircleIcon className="w-5 h-5 mr-1" />
|
<CheckCircleIcon />
|
||||||
<span>{intl.formatMessage(messages.markavailable)}</span>
|
<span>{intl.formatMessage(messages.markavailable)}</span>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@@ -294,7 +294,7 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
|||||||
className="w-full sm:mb-0"
|
className="w-full sm:mb-0"
|
||||||
buttonType="success"
|
buttonType="success"
|
||||||
>
|
>
|
||||||
<CheckCircleIcon className="w-5 h-5 mr-1" />
|
<CheckCircleIcon />
|
||||||
<span>
|
<span>
|
||||||
{intl.formatMessage(messages.mark4kavailable)}
|
{intl.formatMessage(messages.mark4kavailable)}
|
||||||
</span>
|
</span>
|
||||||
@@ -333,7 +333,7 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
|||||||
className="block mb-2 last:mb-0"
|
className="block mb-2 last:mb-0"
|
||||||
>
|
>
|
||||||
<Button buttonType="ghost" className="w-full">
|
<Button buttonType="ghost" className="w-full">
|
||||||
<ExternalLinkIcon className="w-5 h-5 mr-1" />
|
<ExternalLinkIcon />
|
||||||
<span>{intl.formatMessage(messages.openradarr)}</span>
|
<span>{intl.formatMessage(messages.openradarr)}</span>
|
||||||
</Button>
|
</Button>
|
||||||
</a>
|
</a>
|
||||||
@@ -345,7 +345,7 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
|||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
>
|
>
|
||||||
<Button buttonType="ghost" className="w-full">
|
<Button buttonType="ghost" className="w-full">
|
||||||
<ExternalLinkIcon className="w-5 h-5 mr-1" />
|
<ExternalLinkIcon />
|
||||||
<span>{intl.formatMessage(messages.openradarr4k)}</span>
|
<span>{intl.formatMessage(messages.openradarr4k)}</span>
|
||||||
</Button>
|
</Button>
|
||||||
</a>
|
</a>
|
||||||
@@ -359,10 +359,10 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
|||||||
confirmText={intl.formatMessage(globalMessages.areyousure)}
|
confirmText={intl.formatMessage(globalMessages.areyousure)}
|
||||||
className="w-full"
|
className="w-full"
|
||||||
>
|
>
|
||||||
<DocumentRemoveIcon className="w-5 h-5 mr-1" />
|
<DocumentRemoveIcon />
|
||||||
{intl.formatMessage(messages.manageModalClearMedia)}
|
<span>{intl.formatMessage(messages.manageModalClearMedia)}</span>
|
||||||
</ConfirmButton>
|
</ConfirmButton>
|
||||||
<div className="mt-2 text-sm text-gray-400">
|
<div className="mt-3 text-xs text-gray-400">
|
||||||
{intl.formatMessage(messages.manageModalClearMediaWarning)}
|
{intl.formatMessage(messages.manageModalClearMediaWarning)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -470,7 +470,7 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
|||||||
<Link href={`/movie/${data.id}/crew`}>
|
<Link href={`/movie/${data.id}/crew`}>
|
||||||
<a className="flex items-center text-gray-400 transition duration-300 hover:text-gray-100">
|
<a className="flex items-center text-gray-400 transition duration-300 hover:text-gray-100">
|
||||||
<span>{intl.formatMessage(messages.viewfullcrew)}</span>
|
<span>{intl.formatMessage(messages.viewfullcrew)}</span>
|
||||||
<ArrowCircleRightIcon className="inline-block w-5 h-5 ml-1" />
|
<ArrowCircleRightIcon className="inline-block w-5 h-5 ml-1.5" />
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
@@ -653,7 +653,7 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
|||||||
<Link href="/movie/[movieId]/cast" as={`/movie/${data.id}/cast`}>
|
<Link href="/movie/[movieId]/cast" as={`/movie/${data.id}/cast`}>
|
||||||
<a className="slider-title">
|
<a className="slider-title">
|
||||||
<span>{intl.formatMessage(messages.cast)}</span>
|
<span>{intl.formatMessage(messages.cast)}</span>
|
||||||
<ArrowCircleRightIcon className="w-6 h-6 ml-2" />
|
<ArrowCircleRightIcon />
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -49,12 +49,14 @@ const PlexLoginButton: React.FC<PlexLoginButtonProps> = ({
|
|||||||
disabled={loading || isProcessing}
|
disabled={loading || isProcessing}
|
||||||
className="plex-button"
|
className="plex-button"
|
||||||
>
|
>
|
||||||
<LoginIcon className="w-5 h-5 mr-1" />
|
<LoginIcon />
|
||||||
{loading
|
<span>
|
||||||
? intl.formatMessage(globalMessages.loading)
|
{loading
|
||||||
: isProcessing
|
? intl.formatMessage(globalMessages.loading)
|
||||||
? intl.formatMessage(messages.signingin)
|
: isProcessing
|
||||||
: intl.formatMessage(messages.signinwithplex)}
|
? intl.formatMessage(messages.signingin)
|
||||||
|
: intl.formatMessage(messages.signinwithplex)}
|
||||||
|
</span>
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -125,8 +125,8 @@ const RegionSelector: React.FC<RegionSelectorProps> = ({
|
|||||||
})
|
})
|
||||||
: intl.formatMessage(messages.regionDefault)}
|
: intl.formatMessage(messages.regionDefault)}
|
||||||
</span>
|
</span>
|
||||||
<span className="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
|
<span className="absolute inset-y-0 right-0 flex items-center pr-2 text-gray-500 pointer-events-none">
|
||||||
<ChevronDownIcon className="w-5 h-5 text-gray-500" />
|
<ChevronDownIcon />
|
||||||
</span>
|
</span>
|
||||||
</Listbox.Button>
|
</Listbox.Button>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -95,42 +95,42 @@ const RequestBlock: React.FC<RequestBlockProps> = ({ request, onUpdate }) => {
|
|||||||
<div className="flex flex-wrap flex-shrink-0 ml-2">
|
<div className="flex flex-wrap flex-shrink-0 ml-2">
|
||||||
{request.status === MediaRequestStatus.PENDING && (
|
{request.status === MediaRequestStatus.PENDING && (
|
||||||
<>
|
<>
|
||||||
<span className="mr-1">
|
<Button
|
||||||
<Button
|
buttonType="success"
|
||||||
buttonType="success"
|
buttonSize="sm"
|
||||||
onClick={() => updateRequest('approve')}
|
className="mr-1"
|
||||||
disabled={isUpdating}
|
onClick={() => updateRequest('approve')}
|
||||||
>
|
disabled={isUpdating}
|
||||||
<CheckIcon className="w-4 h-4" />
|
>
|
||||||
</Button>
|
<CheckIcon />
|
||||||
</span>
|
</Button>
|
||||||
<span className="mr-1">
|
<Button
|
||||||
<Button
|
buttonType="danger"
|
||||||
buttonType="danger"
|
buttonSize="sm"
|
||||||
onClick={() => updateRequest('decline')}
|
className="mr-1"
|
||||||
disabled={isUpdating}
|
onClick={() => updateRequest('decline')}
|
||||||
>
|
disabled={isUpdating}
|
||||||
<XIcon className="w-4 h-4" />
|
>
|
||||||
</Button>
|
<XIcon />
|
||||||
</span>
|
</Button>
|
||||||
<span>
|
<Button
|
||||||
<Button
|
buttonType="primary"
|
||||||
buttonType="primary"
|
buttonSize="sm"
|
||||||
onClick={() => setShowEditModal(true)}
|
onClick={() => setShowEditModal(true)}
|
||||||
disabled={isUpdating}
|
disabled={isUpdating}
|
||||||
>
|
>
|
||||||
<PencilIcon className="w-4 h-4" />
|
<PencilIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</span>
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{request.status !== MediaRequestStatus.PENDING && (
|
{request.status !== MediaRequestStatus.PENDING && (
|
||||||
<Button
|
<Button
|
||||||
buttonType="danger"
|
buttonType="danger"
|
||||||
|
buttonSize="sm"
|
||||||
onClick={() => deleteRequest()}
|
onClick={() => deleteRequest()}
|
||||||
disabled={isUpdating}
|
disabled={isUpdating}
|
||||||
>
|
>
|
||||||
<TrashIcon className="w-4 h-4" />
|
<TrashIcon />
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ const RequestButton: React.FC<RequestButtonProps> = ({
|
|||||||
setEditRequest(false);
|
setEditRequest(false);
|
||||||
setShowRequestModal(true);
|
setShowRequestModal(true);
|
||||||
},
|
},
|
||||||
svg: <DownloadIcon className="w-5 h-5 mr-1" />,
|
svg: <DownloadIcon />,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,7 +151,7 @@ const RequestButton: React.FC<RequestButtonProps> = ({
|
|||||||
setEditRequest(false);
|
setEditRequest(false);
|
||||||
setShowRequest4kModal(true);
|
setShowRequest4kModal(true);
|
||||||
},
|
},
|
||||||
svg: <DownloadIcon className="w-5 h-5 mr-1" />,
|
svg: <DownloadIcon />,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,7 +168,7 @@ const RequestButton: React.FC<RequestButtonProps> = ({
|
|||||||
setEditRequest(true);
|
setEditRequest(true);
|
||||||
setShowRequestModal(true);
|
setShowRequestModal(true);
|
||||||
},
|
},
|
||||||
svg: <InformationCircleIcon className="w-5 h-5 mr-1" />,
|
svg: <InformationCircleIcon />,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,7 +185,7 @@ const RequestButton: React.FC<RequestButtonProps> = ({
|
|||||||
setEditRequest(true);
|
setEditRequest(true);
|
||||||
setShowRequest4kModal(true);
|
setShowRequest4kModal(true);
|
||||||
},
|
},
|
||||||
svg: <InformationCircleIcon className="w-5 h-5 mr-1" />,
|
svg: <InformationCircleIcon />,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,7 +201,7 @@ const RequestButton: React.FC<RequestButtonProps> = ({
|
|||||||
action: () => {
|
action: () => {
|
||||||
modifyRequest(activeRequest, 'approve');
|
modifyRequest(activeRequest, 'approve');
|
||||||
},
|
},
|
||||||
svg: <CheckIcon className="w-5 h-5 mr-1" />,
|
svg: <CheckIcon />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'decline-request',
|
id: 'decline-request',
|
||||||
@@ -209,7 +209,7 @@ const RequestButton: React.FC<RequestButtonProps> = ({
|
|||||||
action: () => {
|
action: () => {
|
||||||
modifyRequest(activeRequest, 'decline');
|
modifyRequest(activeRequest, 'decline');
|
||||||
},
|
},
|
||||||
svg: <XIcon className="w-5 h-5 mr-1" />,
|
svg: <XIcon />,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -229,7 +229,7 @@ const RequestButton: React.FC<RequestButtonProps> = ({
|
|||||||
action: () => {
|
action: () => {
|
||||||
modifyRequests(activeRequests, 'approve');
|
modifyRequests(activeRequests, 'approve');
|
||||||
},
|
},
|
||||||
svg: <CheckIcon className="w-5 h-5 mr-1" />,
|
svg: <CheckIcon />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'decline-request-batch',
|
id: 'decline-request-batch',
|
||||||
@@ -239,7 +239,7 @@ const RequestButton: React.FC<RequestButtonProps> = ({
|
|||||||
action: () => {
|
action: () => {
|
||||||
modifyRequests(activeRequests, 'decline');
|
modifyRequests(activeRequests, 'decline');
|
||||||
},
|
},
|
||||||
svg: <XIcon className="w-5 h-5 mr-1" />,
|
svg: <XIcon />,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -256,7 +256,7 @@ const RequestButton: React.FC<RequestButtonProps> = ({
|
|||||||
action: () => {
|
action: () => {
|
||||||
modifyRequest(active4kRequest, 'approve');
|
modifyRequest(active4kRequest, 'approve');
|
||||||
},
|
},
|
||||||
svg: <CheckIcon className="w-5 h-5 mr-1" />,
|
svg: <CheckIcon />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'decline-4k-request',
|
id: 'decline-4k-request',
|
||||||
@@ -264,7 +264,7 @@ const RequestButton: React.FC<RequestButtonProps> = ({
|
|||||||
action: () => {
|
action: () => {
|
||||||
modifyRequest(active4kRequest, 'decline');
|
modifyRequest(active4kRequest, 'decline');
|
||||||
},
|
},
|
||||||
svg: <XIcon className="w-5 h-5 mr-1" />,
|
svg: <XIcon />,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -284,7 +284,7 @@ const RequestButton: React.FC<RequestButtonProps> = ({
|
|||||||
action: () => {
|
action: () => {
|
||||||
modifyRequests(active4kRequests, 'approve');
|
modifyRequests(active4kRequests, 'approve');
|
||||||
},
|
},
|
||||||
svg: <CheckIcon className="w-5 h-5 mr-1" />,
|
svg: <CheckIcon />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'decline-4k-request-batch',
|
id: 'decline-4k-request-batch',
|
||||||
@@ -294,7 +294,7 @@ const RequestButton: React.FC<RequestButtonProps> = ({
|
|||||||
action: () => {
|
action: () => {
|
||||||
modifyRequests(active4kRequests, 'decline');
|
modifyRequests(active4kRequests, 'decline');
|
||||||
},
|
},
|
||||||
svg: <XIcon className="w-5 h-5 mr-1" />,
|
svg: <XIcon />,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -315,7 +315,7 @@ const RequestButton: React.FC<RequestButtonProps> = ({
|
|||||||
setEditRequest(false);
|
setEditRequest(false);
|
||||||
setShowRequestModal(true);
|
setShowRequestModal(true);
|
||||||
},
|
},
|
||||||
svg: <DownloadIcon className="w-5 h-5 mr-1" />,
|
svg: <DownloadIcon />,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,7 +338,7 @@ const RequestButton: React.FC<RequestButtonProps> = ({
|
|||||||
setEditRequest(false);
|
setEditRequest(false);
|
||||||
setShowRequest4kModal(true);
|
setShowRequest4kModal(true);
|
||||||
},
|
},
|
||||||
svg: <DownloadIcon className="w-5 h-5 mr-1" />,
|
svg: <DownloadIcon />,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,8 +376,8 @@ const RequestButton: React.FC<RequestButtonProps> = ({
|
|||||||
<ButtonWithDropdown
|
<ButtonWithDropdown
|
||||||
text={
|
text={
|
||||||
<>
|
<>
|
||||||
{buttonOne.svg ?? null}
|
{buttonOne.svg}
|
||||||
{buttonOne.text}
|
<span>{buttonOne.text}</span>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
onClick={buttonOne.action}
|
onClick={buttonOne.action}
|
||||||
@@ -390,7 +390,7 @@ const RequestButton: React.FC<RequestButtonProps> = ({
|
|||||||
key={`request-option-${button.id}`}
|
key={`request-option-${button.id}`}
|
||||||
>
|
>
|
||||||
{button.svg}
|
{button.svg}
|
||||||
{button.text}
|
<span>{button.text}</span>
|
||||||
</ButtonWithDropdown.Item>
|
</ButtonWithDropdown.Item>
|
||||||
))
|
))
|
||||||
: null}
|
: null}
|
||||||
|
|||||||
@@ -62,16 +62,15 @@ const RequestCardError: React.FC<RequestCardErrorProps> = ({ mediaId }) => {
|
|||||||
{intl.formatMessage(messages.mediaerror)}
|
{intl.formatMessage(messages.mediaerror)}
|
||||||
</div>
|
</div>
|
||||||
{hasPermission(Permission.MANAGE_REQUESTS) && mediaId && (
|
{hasPermission(Permission.MANAGE_REQUESTS) && mediaId && (
|
||||||
<div className="mt-4">
|
<Button
|
||||||
<Button
|
buttonType="danger"
|
||||||
buttonType="danger"
|
buttonSize="sm"
|
||||||
buttonSize="sm"
|
className="mt-4"
|
||||||
onClick={() => deleteRequest()}
|
onClick={() => deleteRequest()}
|
||||||
>
|
>
|
||||||
<TrashIcon className="w-5 h-5 mr-1" />
|
<TrashIcon />
|
||||||
<span>{intl.formatMessage(messages.deleterequest)}</span>
|
<span>{intl.formatMessage(messages.deleterequest)}</span>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -240,31 +239,27 @@ const RequestCard: React.FC<RequestCardProps> = ({ request, onTitleData }) => {
|
|||||||
</div>
|
</div>
|
||||||
{requestData.status === MediaRequestStatus.PENDING &&
|
{requestData.status === MediaRequestStatus.PENDING &&
|
||||||
hasPermission(Permission.MANAGE_REQUESTS) && (
|
hasPermission(Permission.MANAGE_REQUESTS) && (
|
||||||
<div className="flex items-end flex-1">
|
<div className="flex items-end flex-1 space-x-2">
|
||||||
<span className="mr-2">
|
<Button
|
||||||
<Button
|
buttonType="success"
|
||||||
buttonType="success"
|
buttonSize="sm"
|
||||||
buttonSize="sm"
|
onClick={() => modifyRequest('approve')}
|
||||||
onClick={() => modifyRequest('approve')}
|
>
|
||||||
>
|
<CheckIcon style={{ marginRight: '0' }} />
|
||||||
<CheckIcon className="w-4 h-4 mr-0 sm:mr-1" />
|
<span className="hidden ml-1.5 sm:block">
|
||||||
<span className="hidden sm:block">
|
{intl.formatMessage(globalMessages.approve)}
|
||||||
{intl.formatMessage(globalMessages.approve)}
|
</span>
|
||||||
</span>
|
</Button>
|
||||||
</Button>
|
<Button
|
||||||
</span>
|
buttonType="danger"
|
||||||
<span>
|
buttonSize="sm"
|
||||||
<Button
|
onClick={() => modifyRequest('decline')}
|
||||||
buttonType="danger"
|
>
|
||||||
buttonSize="sm"
|
<XIcon style={{ marginRight: '0' }} />
|
||||||
onClick={() => modifyRequest('decline')}
|
<span className="hidden ml-1.5 sm:block">
|
||||||
>
|
{intl.formatMessage(globalMessages.decline)}
|
||||||
<XIcon className="w-4 h-4 mr-0 sm:mr-1" />
|
</span>
|
||||||
<span className="hidden sm:block">
|
</Button>
|
||||||
{intl.formatMessage(globalMessages.decline)}
|
|
||||||
</span>
|
|
||||||
</Button>
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ const RequestItemError: React.FC<RequestItemErroProps> = ({
|
|||||||
buttonSize="sm"
|
buttonSize="sm"
|
||||||
onClick={() => deleteRequest()}
|
onClick={() => deleteRequest()}
|
||||||
>
|
>
|
||||||
<TrashIcon className="w-5 h-5 mr-1" />
|
<TrashIcon />
|
||||||
<span>{intl.formatMessage(messages.deleterequest)}</span>
|
<span>{intl.formatMessage(messages.deleterequest)}</span>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@@ -373,10 +373,10 @@ const RequestItem: React.FC<RequestItemProps> = ({
|
|||||||
onClick={() => retryRequest()}
|
onClick={() => retryRequest()}
|
||||||
>
|
>
|
||||||
<RefreshIcon
|
<RefreshIcon
|
||||||
className={`w-5 h-5 mr-1 ${isRetrying ? 'animate-spin' : ''}`}
|
className={isRetrying ? 'animate-spin' : ''}
|
||||||
style={{ animationDirection: 'reverse' }}
|
style={{ animationDirection: 'reverse' }}
|
||||||
/>
|
/>
|
||||||
<span className="block">
|
<span>
|
||||||
{intl.formatMessage(
|
{intl.formatMessage(
|
||||||
isRetrying ? globalMessages.retrying : globalMessages.retry
|
isRetrying ? globalMessages.retrying : globalMessages.retry
|
||||||
)}
|
)}
|
||||||
@@ -390,10 +390,8 @@ const RequestItem: React.FC<RequestItemProps> = ({
|
|||||||
confirmText={intl.formatMessage(globalMessages.areyousure)}
|
confirmText={intl.formatMessage(globalMessages.areyousure)}
|
||||||
className="w-full"
|
className="w-full"
|
||||||
>
|
>
|
||||||
<TrashIcon className="w-5 h-5 mr-1" />
|
<TrashIcon />
|
||||||
<span className="block">
|
<span>{intl.formatMessage(messages.deleterequest)}</span>
|
||||||
{intl.formatMessage(messages.deleterequest)}
|
|
||||||
</span>
|
|
||||||
</ConfirmButton>
|
</ConfirmButton>
|
||||||
)}
|
)}
|
||||||
{requestData.status === MediaRequestStatus.PENDING &&
|
{requestData.status === MediaRequestStatus.PENDING &&
|
||||||
@@ -405,10 +403,8 @@ const RequestItem: React.FC<RequestItemProps> = ({
|
|||||||
buttonType="success"
|
buttonType="success"
|
||||||
onClick={() => modifyRequest('approve')}
|
onClick={() => modifyRequest('approve')}
|
||||||
>
|
>
|
||||||
<CheckIcon className="w-5 h-5 mr-1" />
|
<CheckIcon />
|
||||||
<span className="block">
|
<span>{intl.formatMessage(globalMessages.approve)}</span>
|
||||||
{intl.formatMessage(globalMessages.approve)}
|
|
||||||
</span>
|
|
||||||
</Button>
|
</Button>
|
||||||
</span>
|
</span>
|
||||||
<span className="w-full">
|
<span className="w-full">
|
||||||
@@ -417,10 +413,8 @@ const RequestItem: React.FC<RequestItemProps> = ({
|
|||||||
buttonType="danger"
|
buttonType="danger"
|
||||||
onClick={() => modifyRequest('decline')}
|
onClick={() => modifyRequest('decline')}
|
||||||
>
|
>
|
||||||
<XIcon className="w-5 h-5 mr-1" />
|
<XIcon />
|
||||||
<span className="block">
|
<span>{intl.formatMessage(globalMessages.decline)}</span>
|
||||||
{intl.formatMessage(globalMessages.decline)}
|
|
||||||
</span>
|
|
||||||
</Button>
|
</Button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -436,10 +430,8 @@ const RequestItem: React.FC<RequestItemProps> = ({
|
|||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
onClick={() => setShowEditModal(true)}
|
onClick={() => setShowEditModal(true)}
|
||||||
>
|
>
|
||||||
<PencilIcon className="w-5 h-5 mr-1" />
|
<PencilIcon />
|
||||||
<span className="block">
|
<span>{intl.formatMessage(messages.editrequest)}</span>
|
||||||
{intl.formatMessage(messages.editrequest)}
|
|
||||||
</span>
|
|
||||||
</Button>
|
</Button>
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
@@ -451,10 +443,8 @@ const RequestItem: React.FC<RequestItemProps> = ({
|
|||||||
confirmText={intl.formatMessage(globalMessages.areyousure)}
|
confirmText={intl.formatMessage(globalMessages.areyousure)}
|
||||||
className="w-full"
|
className="w-full"
|
||||||
>
|
>
|
||||||
<XIcon className="w-5 h-5 mr-1" />
|
<XIcon />
|
||||||
<span className="block">
|
<span>{intl.formatMessage(messages.cancelRequest)}</span>
|
||||||
{intl.formatMessage(messages.cancelRequest)}
|
|
||||||
</span>
|
|
||||||
</ConfirmButton>
|
</ConfirmButton>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
/* eslint-disable react-hooks/exhaustive-deps */
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import { Listbox, Transition } from '@headlessui/react';
|
import { Listbox, Transition } from '@headlessui/react';
|
||||||
import {
|
import { AdjustmentsIcon } from '@heroicons/react/outline';
|
||||||
AdjustmentsIcon,
|
import { CheckIcon, ChevronDownIcon } from '@heroicons/react/solid';
|
||||||
CheckIcon,
|
|
||||||
ChevronDownIcon,
|
|
||||||
} from '@heroicons/react/solid';
|
|
||||||
import { isEqual } from 'lodash';
|
import { isEqual } from 'lodash';
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
@@ -274,7 +271,7 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="flex items-center mb-2 font-bold tracking-wider">
|
<div className="flex items-center mb-2 font-bold tracking-wider">
|
||||||
<AdjustmentsIcon className="w-5 h-5 mr-1" />
|
<AdjustmentsIcon className="w-5 h-5 mr-1.5" />
|
||||||
{intl.formatMessage(messages.advancedoptions)}
|
{intl.formatMessage(messages.advancedoptions)}
|
||||||
</div>
|
</div>
|
||||||
<div className="p-4 bg-gray-600 rounded-md shadow">
|
<div className="p-4 bg-gray-600 rounded-md shadow">
|
||||||
@@ -522,8 +519,8 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
|||||||
({selectedUser.email})
|
({selectedUser.email})
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<span className="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
|
<span className="absolute inset-y-0 right-0 flex items-center pr-2 text-gray-500 pointer-events-none">
|
||||||
<ChevronDownIcon className="w-5 h-5 text-gray-500" />
|
<ChevronDownIcon />
|
||||||
</span>
|
</span>
|
||||||
</Listbox.Button>
|
</Listbox.Button>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -236,7 +236,7 @@ const MovieRequestModal: React.FC<RequestModalProps> = ({
|
|||||||
}
|
}
|
||||||
secondaryButtonType="danger"
|
secondaryButtonType="danger"
|
||||||
cancelText={intl.formatMessage(globalMessages.close)}
|
cancelText={intl.formatMessage(globalMessages.close)}
|
||||||
iconSvg={<DownloadIcon className="w-6 h-6" />}
|
iconSvg={<DownloadIcon />}
|
||||||
>
|
>
|
||||||
{isOwner
|
{isOwner
|
||||||
? intl.formatMessage(messages.pendingapproval)
|
? intl.formatMessage(messages.pendingapproval)
|
||||||
@@ -294,7 +294,7 @@ const MovieRequestModal: React.FC<RequestModalProps> = ({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
okButtonType={'primary'}
|
okButtonType={'primary'}
|
||||||
iconSvg={<DownloadIcon className="w-6 h-6" />}
|
iconSvg={<DownloadIcon />}
|
||||||
>
|
>
|
||||||
{hasAutoApprove && !quota?.movie.restricted && (
|
{hasAutoApprove && !quota?.movie.restricted && (
|
||||||
<div className="mt-6">
|
<div className="mt-6">
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ const SearchByNameModal: React.FC<SearchByNameModalProps> = ({
|
|||||||
okText={intl.formatMessage(globalMessages.next)}
|
okText={intl.formatMessage(globalMessages.next)}
|
||||||
okDisabled={!tvdbId}
|
okDisabled={!tvdbId}
|
||||||
okButtonType="primary"
|
okButtonType="primary"
|
||||||
iconSvg={<DownloadIcon className="w-6 h-6" />}
|
iconSvg={<DownloadIcon />}
|
||||||
>
|
>
|
||||||
<Alert
|
<Alert
|
||||||
title={intl.formatMessage(messages.notvdbiddescription)}
|
title={intl.formatMessage(messages.notvdbiddescription)}
|
||||||
|
|||||||
@@ -419,7 +419,7 @@ const TvRequestModal: React.FC<RequestModalProps> = ({
|
|||||||
? intl.formatMessage(globalMessages.back)
|
? intl.formatMessage(globalMessages.back)
|
||||||
: intl.formatMessage(globalMessages.cancel)
|
: intl.formatMessage(globalMessages.cancel)
|
||||||
}
|
}
|
||||||
iconSvg={<DownloadIcon className="w-6 h-6" />}
|
iconSvg={<DownloadIcon />}
|
||||||
>
|
>
|
||||||
{editRequest
|
{editRequest
|
||||||
? isOwner
|
? isOwner
|
||||||
|
|||||||
@@ -124,8 +124,10 @@ const ResetPassword: React.FC = () => {
|
|||||||
type="submit"
|
type="submit"
|
||||||
disabled={isSubmitting || !isValid}
|
disabled={isSubmitting || !isValid}
|
||||||
>
|
>
|
||||||
<AtSymbolIcon className="w-5 h-5 mr-1" />
|
<AtSymbolIcon />
|
||||||
{intl.formatMessage(messages.emailresetlink)}
|
<span>
|
||||||
|
{intl.formatMessage(messages.emailresetlink)}
|
||||||
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ const CopyButton: React.FC<{ textToCopy: string }> = ({ textToCopy }) => {
|
|||||||
}}
|
}}
|
||||||
className="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium leading-5 text-white transition duration-150 ease-in-out bg-indigo-600 border border-gray-500 hover:bg-indigo-500 focus:outline-none focus:ring-blue focus:border-blue-300 active:bg-gray-100 active:text-gray-700"
|
className="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium leading-5 text-white transition duration-150 ease-in-out bg-indigo-600 border border-gray-500 hover:bg-indigo-500 focus:outline-none focus:ring-blue focus:border-blue-300 active:bg-gray-100 active:text-gray-700"
|
||||||
>
|
>
|
||||||
<ClipboardCopyIcon className="w-5 h-5 text-white" />
|
<ClipboardCopyIcon />
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { QuestionMarkCircleIcon, RefreshIcon } from '@heroicons/react/solid';
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { Field, Form, Formik } from 'formik';
|
import { Field, Form, Formik } from 'formik';
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
|
import Link from 'next/link';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
import { useToasts } from 'react-toast-notifications';
|
import { useToasts } from 'react-toast-notifications';
|
||||||
@@ -263,18 +264,25 @@ const NotificationsWebhook: React.FC = () => {
|
|||||||
}}
|
}}
|
||||||
className="mr-2"
|
className="mr-2"
|
||||||
>
|
>
|
||||||
<RefreshIcon className="w-5 h-5 mr-1" />
|
<RefreshIcon />
|
||||||
{intl.formatMessage(messages.resetPayload)}
|
<span>{intl.formatMessage(messages.resetPayload)}</span>
|
||||||
</Button>
|
</Button>
|
||||||
<a
|
<Link
|
||||||
href="https://docs.overseerr.dev/using-overseerr/notifications/webhooks#template-variables"
|
href="https://docs.overseerr.dev/using-overseerr/notifications/webhooks#template-variables"
|
||||||
target="_blank"
|
passHref
|
||||||
rel="noreferrer"
|
|
||||||
className="inline-flex items-center justify-center font-medium leading-5 text-white transition duration-150 ease-in-out bg-indigo-600 border border-transparent rounded-md focus:outline-none hover:bg-indigo-500 focus:border-indigo-700 focus:ring-indigo active:bg-indigo-700 disabled:opacity-50 px-2.5 py-1.5 text-xs"
|
|
||||||
>
|
>
|
||||||
<QuestionMarkCircleIcon className="w-5 h-5 mr-1" />
|
<Button
|
||||||
{intl.formatMessage(messages.templatevariablehelp)}
|
as="a"
|
||||||
</a>
|
buttonSize="sm"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
<QuestionMarkCircleIcon />
|
||||||
|
<span>
|
||||||
|
{intl.formatMessage(messages.templatevariablehelp)}
|
||||||
|
</span>
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -357,13 +357,7 @@ const RadarrModal: React.FC<RadarrModalProps> = ({
|
|||||||
values.is4k ? messages.edit4kradarr : messages.editradarr
|
values.is4k ? messages.edit4kradarr : messages.editradarr
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
iconSvg={
|
iconSvg={!radarr ? <PlusIcon /> : <PencilIcon />}
|
||||||
!radarr ? (
|
|
||||||
<PlusIcon className="w-6 h-6" />
|
|
||||||
) : (
|
|
||||||
<PencilIcon className="w-6 h-6" />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<div className="mb-6">
|
<div className="mb-6">
|
||||||
<div className="form-row">
|
<div className="form-row">
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ const Release: React.FC<ReleaseProps> = ({
|
|||||||
>
|
>
|
||||||
<Modal
|
<Modal
|
||||||
onCancel={() => setModalOpen(false)}
|
onCancel={() => setModalOpen(false)}
|
||||||
iconSvg={<DocumentTextIcon className="w-6 h-6" />}
|
iconSvg={<DocumentTextIcon />}
|
||||||
title={intl.formatMessage(messages.versionChangelog)}
|
title={intl.formatMessage(messages.versionChangelog)}
|
||||||
cancelText={intl.formatMessage(globalMessages.close)}
|
cancelText={intl.formatMessage(globalMessages.close)}
|
||||||
okText={intl.formatMessage(messages.viewongithub)}
|
okText={intl.formatMessage(messages.viewongithub)}
|
||||||
@@ -112,8 +112,8 @@ const Release: React.FC<ReleaseProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex-1 text-center sm:text-right">
|
<div className="flex-1 text-center sm:text-right">
|
||||||
<Button buttonType="primary" onClick={() => setModalOpen(true)}>
|
<Button buttonType="primary" onClick={() => setModalOpen(true)}>
|
||||||
<DocumentTextIcon className="w-5 h-5 mr-1" />
|
<DocumentTextIcon />
|
||||||
{intl.formatMessage(messages.viewchangelog)}
|
<span>{intl.formatMessage(messages.viewchangelog)}</span>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -181,13 +181,13 @@ const SettingsJobs: React.FC = () => {
|
|||||||
<Table.TD alignText="right">
|
<Table.TD alignText="right">
|
||||||
{job.running ? (
|
{job.running ? (
|
||||||
<Button buttonType="danger" onClick={() => cancelJob(job)}>
|
<Button buttonType="danger" onClick={() => cancelJob(job)}>
|
||||||
<StopIcon className="w-5 h-5 mr-1" />
|
<StopIcon />
|
||||||
{intl.formatMessage(messages.canceljob)}
|
<span>{intl.formatMessage(messages.canceljob)}</span>
|
||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<Button buttonType="primary" onClick={() => runJob(job)}>
|
<Button buttonType="primary" onClick={() => runJob(job)}>
|
||||||
<PlayIcon className="w-5 h-5 mr-1" />
|
<PlayIcon className="w-5 h-5 mr-1" />
|
||||||
{intl.formatMessage(messages.runnow)}
|
<span>{intl.formatMessage(messages.runnow)}</span>
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</Table.TD>
|
</Table.TD>
|
||||||
@@ -226,8 +226,8 @@ const SettingsJobs: React.FC = () => {
|
|||||||
<Table.TD>{formatBytes(cache.stats.vsize)}</Table.TD>
|
<Table.TD>{formatBytes(cache.stats.vsize)}</Table.TD>
|
||||||
<Table.TD alignText="right">
|
<Table.TD alignText="right">
|
||||||
<Button buttonType="danger" onClick={() => flushCache(cache)}>
|
<Button buttonType="danger" onClick={() => flushCache(cache)}>
|
||||||
<TrashIcon className="w-5 h-5 mr-1" />
|
<TrashIcon />
|
||||||
{intl.formatMessage(messages.flushcache)}
|
<span>{intl.formatMessage(messages.flushcache)}</span>
|
||||||
</Button>
|
</Button>
|
||||||
</Table.TD>
|
</Table.TD>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ const SettingsLogs: React.FC = () => {
|
|||||||
>
|
>
|
||||||
<Modal
|
<Modal
|
||||||
title={intl.formatMessage(messages.logDetails)}
|
title={intl.formatMessage(messages.logDetails)}
|
||||||
iconSvg={<DocumentSearchIcon className="w-6 h-6" />}
|
iconSvg={<DocumentSearchIcon />}
|
||||||
onCancel={() => setActiveLog(null)}
|
onCancel={() => setActiveLog(null)}
|
||||||
cancelText={intl.formatMessage(globalMessages.close)}
|
cancelText={intl.formatMessage(globalMessages.close)}
|
||||||
onOk={() => (activeLog ? copyLogString(activeLog) : undefined)}
|
onOk={() => (activeLog ? copyLogString(activeLog) : undefined)}
|
||||||
@@ -243,13 +243,7 @@ const SettingsLogs: React.FC = () => {
|
|||||||
buttonType={refreshInterval ? 'default' : 'primary'}
|
buttonType={refreshInterval ? 'default' : 'primary'}
|
||||||
onClick={() => toggleLogs()}
|
onClick={() => toggleLogs()}
|
||||||
>
|
>
|
||||||
<span>
|
{refreshInterval ? <PauseIcon /> : <PlayIcon />}
|
||||||
{refreshInterval ? (
|
|
||||||
<PauseIcon className="w-5 h-5 mr-1" />
|
|
||||||
) : (
|
|
||||||
<PlayIcon className="w-5 h-5 mr-1" />
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
<span>
|
<span>
|
||||||
{intl.formatMessage(
|
{intl.formatMessage(
|
||||||
refreshInterval ? messages.pauseLogs : messages.resumeLogs
|
refreshInterval ? messages.pauseLogs : messages.resumeLogs
|
||||||
@@ -335,7 +329,7 @@ const SettingsLogs: React.FC = () => {
|
|||||||
onClick={() => setActiveLog(row)}
|
onClick={() => setActiveLog(row)}
|
||||||
className="mr-2"
|
className="mr-2"
|
||||||
>
|
>
|
||||||
<DocumentSearchIcon className="w-5 h-5 text-white" />
|
<DocumentSearchIcon />
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
<Button
|
<Button
|
||||||
@@ -343,7 +337,7 @@ const SettingsLogs: React.FC = () => {
|
|||||||
buttonSize="sm"
|
buttonSize="sm"
|
||||||
onClick={() => copyLogString(row)}
|
onClick={() => copyLogString(row)}
|
||||||
>
|
>
|
||||||
<ClipboardCopyIcon className="w-5 h-5 text-white" />
|
<ClipboardCopyIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</Table.TD>
|
</Table.TD>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ const SettingsMain: React.FC = () => {
|
|||||||
}}
|
}}
|
||||||
className="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium leading-5 text-white transition duration-150 ease-in-out bg-indigo-600 border border-gray-500 rounded-r-md hover:bg-indigo-500 focus:outline-none focus:ring-blue focus:border-blue-300 active:bg-gray-100 active:text-gray-700"
|
className="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium leading-5 text-white transition duration-150 ease-in-out bg-indigo-600 border border-gray-500 rounded-r-md hover:bg-indigo-500 focus:outline-none focus:ring-blue focus:border-blue-300 active:bg-gray-100 active:text-gray-700"
|
||||||
>
|
>
|
||||||
<RefreshIcon className="w-5 h-5" />
|
<RefreshIcon />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -435,9 +435,7 @@ const SettingsPlex: React.FC<SettingsPlexProps> = ({ onComplete }) => {
|
|||||||
className="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium leading-5 text-white transition duration-150 ease-in-out bg-indigo-600 border border-gray-500 rounded-r-md hover:bg-indigo-500 focus:outline-none focus:ring-blue focus:border-blue-300 active:bg-gray-100 active:text-gray-700"
|
className="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium leading-5 text-white transition duration-150 ease-in-out bg-indigo-600 border border-gray-500 rounded-r-md hover:bg-indigo-500 focus:outline-none focus:ring-blue focus:border-blue-300 active:bg-gray-100 active:text-gray-700"
|
||||||
>
|
>
|
||||||
<RefreshIcon
|
<RefreshIcon
|
||||||
className={`w-5 h-5 ${
|
className={isRefreshingPresets ? 'animate-spin' : ''}
|
||||||
isRefreshingPresets ? 'animate-spin' : ''
|
|
||||||
}`}
|
|
||||||
style={{ animationDirection: 'reverse' }}
|
style={{ animationDirection: 'reverse' }}
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
@@ -530,7 +528,7 @@ const SettingsPlex: React.FC<SettingsPlexProps> = ({ onComplete }) => {
|
|||||||
<div className="section">
|
<div className="section">
|
||||||
<Button onClick={() => syncLibraries()} disabled={isSyncing}>
|
<Button onClick={() => syncLibraries()} disabled={isSyncing}>
|
||||||
<RefreshIcon
|
<RefreshIcon
|
||||||
className={`w-5 h-5 mr-1 ${isSyncing ? 'animate-spin' : ''}`}
|
className={isSyncing ? 'animate-spin' : ''}
|
||||||
style={{ animationDirection: 'reverse' }}
|
style={{ animationDirection: 'reverse' }}
|
||||||
/>
|
/>
|
||||||
{isSyncing
|
{isSyncing
|
||||||
@@ -606,14 +604,14 @@ const SettingsPlex: React.FC<SettingsPlexProps> = ({ onComplete }) => {
|
|||||||
<div className="flex-1 text-right">
|
<div className="flex-1 text-right">
|
||||||
{!dataSync?.running && (
|
{!dataSync?.running && (
|
||||||
<Button buttonType="warning" onClick={() => startScan()}>
|
<Button buttonType="warning" onClick={() => startScan()}>
|
||||||
<SearchIcon className="w-5 h-5 mr-1" />
|
<SearchIcon />
|
||||||
{intl.formatMessage(messages.startscan)}
|
{intl.formatMessage(messages.startscan)}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{dataSync?.running && (
|
{dataSync?.running && (
|
||||||
<Button buttonType="danger" onClick={() => cancelScan()}>
|
<Button buttonType="danger" onClick={() => cancelScan()}>
|
||||||
<XIcon className="w-5 h-5 mr-1" />
|
<XIcon />
|
||||||
{intl.formatMessage(messages.cancelscan)}
|
{intl.formatMessage(messages.cancelscan)}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -139,8 +139,8 @@ const ServerInstance: React.FC<ServerInstanceProps> = ({
|
|||||||
onClick={() => onEdit()}
|
onClick={() => onEdit()}
|
||||||
className="relative inline-flex items-center justify-center flex-1 w-0 py-4 -mr-px text-sm font-medium leading-5 text-gray-200 transition duration-150 ease-in-out border border-transparent rounded-bl-lg hover:text-white focus:outline-none focus:ring-blue focus:border-gray-500 focus:z-10"
|
className="relative inline-flex items-center justify-center flex-1 w-0 py-4 -mr-px text-sm font-medium leading-5 text-gray-200 transition duration-150 ease-in-out border border-transparent rounded-bl-lg hover:text-white focus:outline-none focus:ring-blue focus:border-gray-500 focus:z-10"
|
||||||
>
|
>
|
||||||
<PencilIcon className="w-5 h-5 mr-2" />
|
<PencilIcon />
|
||||||
{intl.formatMessage(globalMessages.edit)}
|
<span>{intl.formatMessage(globalMessages.edit)}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-1 w-0 -ml-px">
|
<div className="flex flex-1 w-0 -ml-px">
|
||||||
@@ -148,8 +148,8 @@ const ServerInstance: React.FC<ServerInstanceProps> = ({
|
|||||||
onClick={() => onDelete()}
|
onClick={() => onDelete()}
|
||||||
className="relative inline-flex items-center justify-center flex-1 w-0 py-4 text-sm font-medium leading-5 text-gray-200 transition duration-150 ease-in-out border border-transparent rounded-br-lg hover:text-white focus:outline-none focus:ring-blue focus:border-gray-500 focus:z-10"
|
className="relative inline-flex items-center justify-center flex-1 w-0 py-4 text-sm font-medium leading-5 text-gray-200 transition duration-150 ease-in-out border border-transparent rounded-br-lg hover:text-white focus:outline-none focus:ring-blue focus:border-gray-500 focus:z-10"
|
||||||
>
|
>
|
||||||
<TrashIcon className="w-5 h-5 mr-2" />
|
<TrashIcon />
|
||||||
{intl.formatMessage(globalMessages.delete)}
|
<span>{intl.formatMessage(globalMessages.delete)}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -265,7 +265,7 @@ const SettingsServices: React.FC = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
title="Delete Server"
|
title="Delete Server"
|
||||||
iconSvg={<TrashIcon className="w-6 h-6" />}
|
iconSvg={<TrashIcon />}
|
||||||
>
|
>
|
||||||
{intl.formatMessage(messages.deleteserverconfirm)}
|
{intl.formatMessage(messages.deleteserverconfirm)}
|
||||||
</Modal>
|
</Modal>
|
||||||
@@ -341,8 +341,8 @@ const SettingsServices: React.FC = () => {
|
|||||||
setEditRadarrModal({ open: true, radarr: null })
|
setEditRadarrModal({ open: true, radarr: null })
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<PlusIcon className="w-5 h-5 mr-1" />
|
<PlusIcon />
|
||||||
{intl.formatMessage(messages.addradarr)}
|
<span>{intl.formatMessage(messages.addradarr)}</span>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
@@ -431,8 +431,8 @@ const SettingsServices: React.FC = () => {
|
|||||||
setEditSonarrModal({ open: true, sonarr: null })
|
setEditSonarrModal({ open: true, sonarr: null })
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<PlusIcon className="w-5 h-5 mr-1" />
|
<PlusIcon />
|
||||||
{intl.formatMessage(messages.addsonarr)}
|
<span>{intl.formatMessage(messages.addsonarr)}</span>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -388,13 +388,7 @@ const SonarrModal: React.FC<SonarrModalProps> = ({
|
|||||||
values.is4k ? messages.edit4ksonarr : messages.editsonarr
|
values.is4k ? messages.edit4ksonarr : messages.editsonarr
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
iconSvg={
|
iconSvg={!sonarr ? <PlusIcon /> : <PencilIcon />}
|
||||||
!sonarr ? (
|
|
||||||
<PlusIcon className="w-6 h-6" />
|
|
||||||
) : (
|
|
||||||
<PencilIcon className="w-6 h-6" />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<div className="mb-6">
|
<div className="mb-6">
|
||||||
<div className="form-row">
|
<div className="form-row">
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ const StatusChecker: React.FC = () => {
|
|||||||
show={data.commitTag !== process.env.commitTag}
|
show={data.commitTag !== process.env.commitTag}
|
||||||
>
|
>
|
||||||
<Modal
|
<Modal
|
||||||
iconSvg={<SparklesIcon className="w-6 h-6" />}
|
iconSvg={<SparklesIcon />}
|
||||||
title={intl.formatMessage(messages.newversionavailable)}
|
title={intl.formatMessage(messages.newversionavailable)}
|
||||||
onOk={() => location.reload()}
|
onOk={() => location.reload()}
|
||||||
okText={intl.formatMessage(messages.reloadOverseerr)}
|
okText={intl.formatMessage(messages.reloadOverseerr)}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { useIsTouch } from '../../hooks/useIsTouch';
|
|||||||
import { Permission, useUser } from '../../hooks/useUser';
|
import { Permission, useUser } from '../../hooks/useUser';
|
||||||
import globalMessages from '../../i18n/globalMessages';
|
import globalMessages from '../../i18n/globalMessages';
|
||||||
import { withProperties } from '../../utils/typeHelpers';
|
import { withProperties } from '../../utils/typeHelpers';
|
||||||
|
import Button from '../Common/Button';
|
||||||
import CachedImage from '../Common/CachedImage';
|
import CachedImage from '../Common/CachedImage';
|
||||||
import RequestModal from '../RequestModal';
|
import RequestModal from '../RequestModal';
|
||||||
import Transition from '../Transition';
|
import Transition from '../Transition';
|
||||||
@@ -229,18 +230,18 @@ const TitleCard: React.FC<TitleCardProps> = ({
|
|||||||
<div className="absolute bottom-0 left-0 right-0 flex justify-between px-2 py-2">
|
<div className="absolute bottom-0 left-0 right-0 flex justify-between px-2 py-2">
|
||||||
{hasPermission(Permission.REQUEST) &&
|
{hasPermission(Permission.REQUEST) &&
|
||||||
(!currentStatus || currentStatus === MediaStatus.UNKNOWN) && (
|
(!currentStatus || currentStatus === MediaStatus.UNKNOWN) && (
|
||||||
<button
|
<Button
|
||||||
|
buttonType="primary"
|
||||||
|
buttonSize="sm"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setShowRequestModal(true);
|
setShowRequestModal(true);
|
||||||
}}
|
}}
|
||||||
className="flex items-center justify-center w-full text-white transition duration-150 ease-in-out bg-indigo-600 rounded-md h-7 hover:bg-indigo-500 focus:border-indigo-700 focus:ring-indigo active:bg-indigo-700"
|
className="w-full h-7"
|
||||||
>
|
>
|
||||||
<DownloadIcon className="w-4 h-4 mr-1" />
|
<DownloadIcon />
|
||||||
<span className="text-xs">
|
<span>{intl.formatMessage(globalMessages.request)}</span>
|
||||||
{intl.formatMessage(globalMessages.request)}
|
</Button>
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ const Toast: React.FC<ToastProps> = ({
|
|||||||
onClick={() => onDismiss()}
|
onClick={() => onDismiss()}
|
||||||
className="inline-flex text-gray-400 transition duration-150 ease-in-out focus:outline-none focus:text-gray-500"
|
className="inline-flex text-gray-400 transition duration-150 ease-in-out focus:outline-none focus:text-gray-500"
|
||||||
>
|
>
|
||||||
<XIcon className="w-5 h-5" />
|
<XIcon />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
|||||||
mediaLinks.push({
|
mediaLinks.push({
|
||||||
text: intl.formatMessage(messages.playonplex),
|
text: intl.formatMessage(messages.playonplex),
|
||||||
url: data.mediaInfo?.plexUrl,
|
url: data.mediaInfo?.plexUrl,
|
||||||
svg: <PlayIcon className="w-5 h-5 mr-1" />,
|
svg: <PlayIcon />,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
|||||||
mediaLinks.push({
|
mediaLinks.push({
|
||||||
text: intl.formatMessage(messages.play4konplex),
|
text: intl.formatMessage(messages.play4konplex),
|
||||||
url: data.mediaInfo?.plexUrl4k,
|
url: data.mediaInfo?.plexUrl4k,
|
||||||
svg: <PlayIcon className="w-5 h-5 mr-1" />,
|
svg: <PlayIcon />,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,7 +150,7 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
|||||||
mediaLinks.push({
|
mediaLinks.push({
|
||||||
text: intl.formatMessage(messages.watchtrailer),
|
text: intl.formatMessage(messages.watchtrailer),
|
||||||
url: trailerUrl,
|
url: trailerUrl,
|
||||||
svg: <FilmIcon className="w-5 h-5 mr-1" />,
|
svg: <FilmIcon />,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,7 +316,7 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
|||||||
className="w-full sm:mb-0"
|
className="w-full sm:mb-0"
|
||||||
buttonType="success"
|
buttonType="success"
|
||||||
>
|
>
|
||||||
<CheckCircleIcon className="w-5 h-5 mr-1" />
|
<CheckCircleIcon />
|
||||||
<span>{intl.formatMessage(messages.markavailable)}</span>
|
<span>{intl.formatMessage(messages.markavailable)}</span>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@@ -330,14 +330,14 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
|||||||
className="w-full sm:mb-0"
|
className="w-full sm:mb-0"
|
||||||
buttonType="success"
|
buttonType="success"
|
||||||
>
|
>
|
||||||
<CheckCircleIcon className="w-5 h-5 mr-1" />
|
<CheckCircleIcon />
|
||||||
<span>
|
<span>
|
||||||
{intl.formatMessage(messages.mark4kavailable)}
|
{intl.formatMessage(messages.mark4kavailable)}
|
||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="mt-3 text-xs text-gray-300">
|
<div className="mt-3 text-xs text-gray-400">
|
||||||
{intl.formatMessage(messages.allseasonsmarkedavailable)}
|
{intl.formatMessage(messages.allseasonsmarkedavailable)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -372,7 +372,7 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
|||||||
className="block mb-2 last:mb-0"
|
className="block mb-2 last:mb-0"
|
||||||
>
|
>
|
||||||
<Button buttonType="ghost" className="w-full">
|
<Button buttonType="ghost" className="w-full">
|
||||||
<ExternalLinkIcon className="w-5 h-5 mr-1" />
|
<ExternalLinkIcon />
|
||||||
<span>{intl.formatMessage(messages.opensonarr)}</span>
|
<span>{intl.formatMessage(messages.opensonarr)}</span>
|
||||||
</Button>
|
</Button>
|
||||||
</a>
|
</a>
|
||||||
@@ -384,7 +384,7 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
|||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
>
|
>
|
||||||
<Button buttonType="ghost" className="w-full">
|
<Button buttonType="ghost" className="w-full">
|
||||||
<ExternalLinkIcon className="w-5 h-5 mr-1" />
|
<ExternalLinkIcon />
|
||||||
<span>{intl.formatMessage(messages.opensonarr4k)}</span>
|
<span>{intl.formatMessage(messages.opensonarr4k)}</span>
|
||||||
</Button>
|
</Button>
|
||||||
</a>
|
</a>
|
||||||
@@ -398,10 +398,10 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
|||||||
confirmText={intl.formatMessage(globalMessages.areyousure)}
|
confirmText={intl.formatMessage(globalMessages.areyousure)}
|
||||||
className="w-full"
|
className="w-full"
|
||||||
>
|
>
|
||||||
<DocumentRemoveIcon className="w-5 h-5 mr-1" />
|
<DocumentRemoveIcon />
|
||||||
{intl.formatMessage(messages.manageModalClearMedia)}
|
<span>{intl.formatMessage(messages.manageModalClearMedia)}</span>
|
||||||
</ConfirmButton>
|
</ConfirmButton>
|
||||||
<div className="mt-2 text-sm text-gray-400">
|
<div className="mt-3 text-xs text-gray-400">
|
||||||
{intl.formatMessage(messages.manageModalClearMediaWarning)}
|
{intl.formatMessage(messages.manageModalClearMediaWarning)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -522,7 +522,7 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
|||||||
<Link href={`/tv/${data.id}/crew`}>
|
<Link href={`/tv/${data.id}/crew`}>
|
||||||
<a className="flex items-center text-gray-400 transition duration-300 hover:text-gray-100">
|
<a className="flex items-center text-gray-400 transition duration-300 hover:text-gray-100">
|
||||||
<span>{intl.formatMessage(messages.viewfullcrew)}</span>
|
<span>{intl.formatMessage(messages.viewfullcrew)}</span>
|
||||||
<ArrowCircleRightIcon className="inline-block w-5 h-5 ml-1" />
|
<ArrowCircleRightIcon className="inline-block w-5 h-5 ml-1.5" />
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
@@ -679,7 +679,7 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
|||||||
<Link href="/tv/[tvId]/cast" as={`/tv/${data.id}/cast`}>
|
<Link href="/tv/[tvId]/cast" as={`/tv/${data.id}/cast`}>
|
||||||
<a className="slider-title">
|
<a className="slider-title">
|
||||||
<span>{intl.formatMessage(messages.cast)}</span>
|
<span>{intl.formatMessage(messages.cast)}</span>
|
||||||
<ArrowCircleRightIcon className="w-6 h-6 ml-2" />
|
<ArrowCircleRightIcon />
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ const BulkEditModal: React.FC<BulkEditProps> = ({
|
|||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
title={intl.formatMessage(messages.edituser)}
|
title={intl.formatMessage(messages.edituser)}
|
||||||
iconSvg={<PencilIcon className="w-6 h-6" />}
|
iconSvg={<PencilIcon />}
|
||||||
onOk={() => {
|
onOk={() => {
|
||||||
updateUsers();
|
updateUsers();
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -273,7 +273,7 @@ const UserList: React.FC = () => {
|
|||||||
okButtonType="danger"
|
okButtonType="danger"
|
||||||
onCancel={() => setDeleteModal({ isOpen: false })}
|
onCancel={() => setDeleteModal({ isOpen: false })}
|
||||||
title={intl.formatMessage(messages.deleteuser)}
|
title={intl.formatMessage(messages.deleteuser)}
|
||||||
iconSvg={<TrashIcon className="w-6 h-6" />}
|
iconSvg={<TrashIcon />}
|
||||||
>
|
>
|
||||||
{intl.formatMessage(messages.deleteconfirm)}
|
{intl.formatMessage(messages.deleteconfirm)}
|
||||||
</Modal>
|
</Modal>
|
||||||
@@ -335,7 +335,7 @@ const UserList: React.FC = () => {
|
|||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
title={intl.formatMessage(messages.createuser)}
|
title={intl.formatMessage(messages.createuser)}
|
||||||
iconSvg={<UserAddIcon className="w-6 h-6" />}
|
iconSvg={<UserAddIcon />}
|
||||||
onOk={() => handleSubmit()}
|
onOk={() => handleSubmit()}
|
||||||
okText={
|
okText={
|
||||||
isSubmitting
|
isSubmitting
|
||||||
@@ -451,8 +451,8 @@ const UserList: React.FC = () => {
|
|||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
onClick={() => setCreateModal({ isOpen: true })}
|
onClick={() => setCreateModal({ isOpen: true })}
|
||||||
>
|
>
|
||||||
<UserAddIcon className="w-5 h-5 mr-1" />
|
<UserAddIcon />
|
||||||
{intl.formatMessage(messages.createlocaluser)}
|
<span>{intl.formatMessage(messages.createlocaluser)}</span>
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
className="flex-grow outline lg:mr-2"
|
className="flex-grow outline lg:mr-2"
|
||||||
@@ -460,8 +460,8 @@ const UserList: React.FC = () => {
|
|||||||
disabled={isImporting}
|
disabled={isImporting}
|
||||||
onClick={() => importFromPlex()}
|
onClick={() => importFromPlex()}
|
||||||
>
|
>
|
||||||
<InboxInIcon className="w-5 h-5 mr-1" />
|
<InboxInIcon />
|
||||||
{intl.formatMessage(messages.importfromplex)}
|
<span>{intl.formatMessage(messages.importfromplex)}</span>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-grow mb-2 lg:mb-0 lg:flex-grow-0">
|
<div className="flex flex-grow mb-2 lg:mb-0 lg:flex-grow-0">
|
||||||
@@ -523,8 +523,8 @@ const UserList: React.FC = () => {
|
|||||||
onClick={() => setShowBulkEditModal(true)}
|
onClick={() => setShowBulkEditModal(true)}
|
||||||
disabled={selectedUsers.length === 0}
|
disabled={selectedUsers.length === 0}
|
||||||
>
|
>
|
||||||
<PencilIcon className="w-5 h-5 mr-1" />
|
<PencilIcon />
|
||||||
{intl.formatMessage(messages.bulkedit)}
|
<span>{intl.formatMessage(messages.bulkedit)}</span>
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</Table.TH>
|
</Table.TH>
|
||||||
|
|||||||
@@ -93,8 +93,8 @@ const ProfileHeader: React.FC<ProfileHeaderProps> = ({
|
|||||||
passHref
|
passHref
|
||||||
>
|
>
|
||||||
<Button as="a">
|
<Button as="a">
|
||||||
<CogIcon className="w-5 h-5 mr-1" />
|
<CogIcon />
|
||||||
{intl.formatMessage(messages.settings)}
|
<span>{intl.formatMessage(messages.settings)}</span>
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
) : (
|
) : (
|
||||||
@@ -106,8 +106,8 @@ const ProfileHeader: React.FC<ProfileHeaderProps> = ({
|
|||||||
passHref
|
passHref
|
||||||
>
|
>
|
||||||
<Button as="a">
|
<Button as="a">
|
||||||
<UserIcon className="w-5 h-5 mr-1" />
|
<UserIcon />
|
||||||
{intl.formatMessage(messages.profile)}
|
<span>{intl.formatMessage(messages.profile)}</span>
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ const UserProfile: React.FC = () => {
|
|||||||
<Link href={`/users/${user?.id}/requests?filter=all`}>
|
<Link href={`/users/${user?.id}/requests?filter=all`}>
|
||||||
<a className="slider-title">
|
<a className="slider-title">
|
||||||
<span>{intl.formatMessage(messages.recentrequests)}</span>
|
<span>{intl.formatMessage(messages.recentrequests)}</span>
|
||||||
<ArrowCircleRightIcon className="w-6 h-6 ml-2" />
|
<ArrowCircleRightIcon />
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -74,6 +74,10 @@ a.slider-title {
|
|||||||
@apply hover:text-white;
|
@apply hover:text-white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a.slider-title svg {
|
||||||
|
@apply w-6 h-6 ml-2;
|
||||||
|
}
|
||||||
|
|
||||||
.media-page {
|
.media-page {
|
||||||
@apply relative px-4 -mx-4 bg-center bg-cover;
|
@apply relative px-4 -mx-4 bg-center bg-cover;
|
||||||
margin-top: calc(-4rem - env(safe-area-inset-top));
|
margin-top: calc(-4rem - env(safe-area-inset-top));
|
||||||
@@ -281,6 +285,23 @@ select.short {
|
|||||||
@apply w-min;
|
@apply w-min;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button svg,
|
||||||
|
.button-md svg {
|
||||||
|
@apply w-5 h-5 mr-2 last:mr-0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-sm svg {
|
||||||
|
@apply w-4 h-4 mr-1.5 last:w-5 last:h-5 last:mr-0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-icon {
|
||||||
|
@apply flex items-center justify-center flex-shrink-0 w-12 h-12 mx-auto text-white bg-gray-600 rounded-full sm:mx-0 sm:h-10 sm:w-10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-icon svg {
|
||||||
|
@apply w-6 h-6;
|
||||||
|
}
|
||||||
|
|
||||||
.protocol {
|
.protocol {
|
||||||
@apply inline-flex items-center px-3 text-gray-100 bg-gray-600 border border-r-0 border-gray-500 cursor-default rounded-l-md sm:text-sm;
|
@apply inline-flex items-center px-3 text-gray-100 bg-gray-600 border border-r-0 border-gray-500 cursor-default rounded-l-md sm:text-sm;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,8 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
variants: {
|
variants: {
|
||||||
cursor: ['disabled'],
|
cursor: ['disabled'],
|
||||||
|
width: ['first', 'last', 'responsive'],
|
||||||
|
height: ['first', 'last', 'responsive'],
|
||||||
padding: ['first', 'last', 'responsive'],
|
padding: ['first', 'last', 'responsive'],
|
||||||
borderWidth: ['first', 'last'],
|
borderWidth: ['first', 'last'],
|
||||||
margin: ['first', 'last', 'responsive'],
|
margin: ['first', 'last', 'responsive'],
|
||||||
|
|||||||
Reference in New Issue
Block a user