style: add new tailwind prettier plugin (#2465)
This commit is contained in:
5
.vscode/extensions.json
vendored
5
.vscode/extensions.json
vendored
@@ -19,9 +19,6 @@
|
|||||||
|
|
||||||
"stylelint.vscode-stylelint",
|
"stylelint.vscode-stylelint",
|
||||||
|
|
||||||
"bradlc.vscode-tailwindcss",
|
"bradlc.vscode-tailwindcss"
|
||||||
|
|
||||||
// https://marketplace.visualstudio.com/items?itemName=heybourn.headwind
|
|
||||||
"heybourn.headwind"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,6 +131,7 @@
|
|||||||
"nodemon": "^2.0.15",
|
"nodemon": "^2.0.15",
|
||||||
"postcss": "^8.4.5",
|
"postcss": "^8.4.5",
|
||||||
"prettier": "^2.5.1",
|
"prettier": "^2.5.1",
|
||||||
|
"prettier-plugin-tailwindcss": "^0.1.3",
|
||||||
"semantic-release": "^19.0.2",
|
"semantic-release": "^19.0.2",
|
||||||
"semantic-release-docker-buildx": "^1.0.1",
|
"semantic-release-docker-buildx": "^1.0.1",
|
||||||
"tailwindcss": "^3.0.15",
|
"tailwindcss": "^3.0.15",
|
||||||
@@ -150,7 +151,7 @@
|
|||||||
"prettier --write",
|
"prettier --write",
|
||||||
"eslint"
|
"eslint"
|
||||||
],
|
],
|
||||||
"**/*.{json,md}": [
|
"**/*.{json,md,css}": [
|
||||||
"prettier --write"
|
"prettier --write"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const Alert: React.FC<AlertProps> = ({ title, children, type }) => {
|
|||||||
bgColor: 'bg-yellow-600',
|
bgColor: 'bg-yellow-600',
|
||||||
titleColor: 'text-yellow-100',
|
titleColor: 'text-yellow-100',
|
||||||
textColor: 'text-yellow-300',
|
textColor: 'text-yellow-300',
|
||||||
svg: <ExclamationIcon className="w-5 h-5" />,
|
svg: <ExclamationIcon className="h-5 w-5" />,
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@@ -24,7 +24,7 @@ const Alert: React.FC<AlertProps> = ({ title, children, type }) => {
|
|||||||
bgColor: 'bg-indigo-600',
|
bgColor: 'bg-indigo-600',
|
||||||
titleColor: 'text-indigo-100',
|
titleColor: 'text-indigo-100',
|
||||||
textColor: 'text-indigo-300',
|
textColor: 'text-indigo-300',
|
||||||
svg: <InformationCircleIcon className="w-5 h-5" />,
|
svg: <InformationCircleIcon className="h-5 w-5" />,
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case 'error':
|
case 'error':
|
||||||
@@ -32,13 +32,13 @@ const Alert: React.FC<AlertProps> = ({ title, children, type }) => {
|
|||||||
bgColor: 'bg-red-600',
|
bgColor: 'bg-red-600',
|
||||||
titleColor: 'text-red-100',
|
titleColor: 'text-red-100',
|
||||||
textColor: 'text-red-300',
|
textColor: 'text-red-300',
|
||||||
svg: <XCircleIcon className="w-5 h-5" />,
|
svg: <XCircleIcon className="h-5 w-5" />,
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`rounded-md p-4 mb-4 ${design.bgColor}`}>
|
<div className={`mb-4 rounded-md p-4 ${design.bgColor}`}>
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
<div className={`flex-shrink-0 ${design.titleColor}`}>{design.svg}</div>
|
<div className={`flex-shrink-0 ${design.titleColor}`}>{design.svg}</div>
|
||||||
<div className="ml-3">
|
<div className="ml-3">
|
||||||
@@ -48,7 +48,7 @@ const Alert: React.FC<AlertProps> = ({ title, children, type }) => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{children && (
|
{children && (
|
||||||
<div className={`mt-2 first:mt-0 text-sm ${design.textColor}`}>
|
<div className={`mt-2 text-sm first:mt-0 ${design.textColor}`}>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ const DropdownItem: React.FC<DropdownItemProps> = ({
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<a
|
<a
|
||||||
className={`flex items-center px-4 py-2 text-sm leading-5 cursor-pointer focus:outline-none ${styleClass}`}
|
className={`flex cursor-pointer items-center px-4 py-2 text-sm leading-5 focus:outline-none ${styleClass}`}
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
@@ -84,7 +84,7 @@ const ButtonWithDropdown: React.FC<ButtonWithDropdownProps> = ({
|
|||||||
<span className="relative inline-flex h-full rounded-md shadow-sm">
|
<span className="relative inline-flex h-full rounded-md shadow-sm">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={`relative inline-flex h-full items-center px-4 py-2 text-sm leading-5 font-medium z-10 hover:z-20 focus:z-20 focus:outline-none transition ease-in-out duration-150 ${
|
className={`relative z-10 inline-flex h-full items-center px-4 py-2 text-sm font-medium leading-5 transition duration-150 ease-in-out hover:z-20 focus:z-20 focus:outline-none ${
|
||||||
styleClasses.mainButtonClasses
|
styleClasses.mainButtonClasses
|
||||||
} ${children ? 'rounded-l-md' : 'rounded-md'} ${className}`}
|
} ${children ? 'rounded-l-md' : 'rounded-md'} ${className}`}
|
||||||
ref={buttonRef}
|
ref={buttonRef}
|
||||||
@@ -93,10 +93,10 @@ const ButtonWithDropdown: React.FC<ButtonWithDropdownProps> = ({
|
|||||||
{text}
|
{text}
|
||||||
</button>
|
</button>
|
||||||
{children && (
|
{children && (
|
||||||
<span className="relative block -ml-px">
|
<span className="relative -ml-px block">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={`relative inline-flex items-center h-full px-2 py-2 text-sm font-medium leading-5 text-white transition duration-150 ease-in-out rounded-r-md z-10 hover:z-20 focus:z-20 ${styleClasses.dropdownSideButtonClasses}`}
|
className={`relative z-10 inline-flex h-full items-center rounded-r-md px-2 py-2 text-sm font-medium leading-5 text-white transition duration-150 ease-in-out hover:z-20 focus:z-20 ${styleClasses.dropdownSideButtonClasses}`}
|
||||||
aria-label="Expand"
|
aria-label="Expand"
|
||||||
onClick={() => setIsOpen((state) => !state)}
|
onClick={() => setIsOpen((state) => !state)}
|
||||||
>
|
>
|
||||||
@@ -111,7 +111,7 @@ const ButtonWithDropdown: React.FC<ButtonWithDropdownProps> = ({
|
|||||||
leaveFrom="transform opacity-100 scale-100"
|
leaveFrom="transform opacity-100 scale-100"
|
||||||
leaveTo="transform opacity-0 scale-95"
|
leaveTo="transform opacity-0 scale-95"
|
||||||
>
|
>
|
||||||
<div className="absolute right-0 z-40 w-56 mt-2 -mr-1 origin-top-right rounded-md shadow-lg">
|
<div className="absolute right-0 z-40 mt-2 -mr-1 w-56 origin-top-right rounded-md shadow-lg">
|
||||||
<div
|
<div
|
||||||
className={`rounded-md ring-1 ring-black ring-opacity-5 ${styleClasses.dropdownClasses}`}
|
className={`rounded-md ring-1 ring-black ring-opacity-5 ${styleClasses.dropdownClasses}`}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ const ConfirmButton: React.FC<ConfirmButtonProps> = ({
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={`absolute flex items-center justify-center inset-0 w-full h-full duration-300 transition transform-gpu ${
|
className={`absolute inset-0 flex h-full w-full transform-gpu items-center justify-center transition duration-300 ${
|
||||||
isClicked
|
isClicked
|
||||||
? '-translate-y-full opacity-0'
|
? '-translate-y-full opacity-0'
|
||||||
: 'translate-y-0 opacity-100'
|
: 'translate-y-0 opacity-100'
|
||||||
@@ -44,7 +44,7 @@ const ConfirmButton: React.FC<ConfirmButtonProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={`absolute flex items-center justify-center inset-0 w-full h-full duration-300 transition transform-gpu ${
|
className={`absolute inset-0 flex h-full w-full transform-gpu items-center justify-center transition duration-300 ${
|
||||||
isClicked ? 'translate-y-0 opacity-100' : 'translate-y-full opacity-0'
|
isClicked ? 'translate-y-0 opacity-100' : 'translate-y-full opacity-0'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ const Header: React.FC<HeaderProps> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div className="mt-8 md:flex md:items-center md:justify-between">
|
<div className="mt-8 md:flex md:items-center md:justify-between">
|
||||||
<div className={`flex-1 min-w-0 mx-${extraMargin}`}>
|
<div className={`min-w-0 flex-1 mx-${extraMargin}`}>
|
||||||
<h2 className="mb-4 text-2xl font-bold leading-7 text-gray-100 truncate sm:text-4xl sm:leading-9 sm:overflow-visible md:mb-0">
|
<h2 className="mb-4 truncate text-2xl font-bold leading-7 text-gray-100 sm:overflow-visible sm:text-4xl sm:leading-9 md:mb-0">
|
||||||
<span className="text-transparent bg-clip-text bg-gradient-to-br from-indigo-400 to-purple-400">
|
<span className="bg-gradient-to-br from-indigo-400 to-purple-400 bg-clip-text text-transparent">
|
||||||
{children}
|
{children}
|
||||||
</span>
|
</span>
|
||||||
</h2>
|
</h2>
|
||||||
|
|||||||
@@ -59,13 +59,13 @@ const ImageFader: ForwardRefRenderFunction<HTMLDivElement, ImageFaderProps> = (
|
|||||||
{backgroundImages.map((imageUrl, i) => (
|
{backgroundImages.map((imageUrl, i) => (
|
||||||
<div
|
<div
|
||||||
key={`banner-image-${i}`}
|
key={`banner-image-${i}`}
|
||||||
className={`absolute absolute-top-shift inset-0 bg-cover bg-center transition-opacity duration-300 ease-in ${
|
className={`absolute-top-shift absolute inset-0 bg-cover bg-center transition-opacity duration-300 ease-in ${
|
||||||
i === activeIndex ? 'opacity-100' : 'opacity-0'
|
i === activeIndex ? 'opacity-100' : 'opacity-0'
|
||||||
}`}
|
}`}
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
<CachedImage
|
<CachedImage
|
||||||
className="absolute inset-0 w-full h-full"
|
className="absolute inset-0 h-full w-full"
|
||||||
alt=""
|
alt=""
|
||||||
src={imageUrl}
|
src={imageUrl}
|
||||||
layout="fill"
|
layout="fill"
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const ListItem: React.FC<ListItemProps> = ({ title, className, children }) => {
|
|||||||
<div>
|
<div>
|
||||||
<div className="max-w-6xl py-4 sm:grid sm:grid-cols-3 sm:gap-4">
|
<div className="max-w-6xl py-4 sm:grid sm:grid-cols-3 sm:gap-4">
|
||||||
<dt className="block text-sm font-bold text-gray-400">{title}</dt>
|
<dt className="block text-sm font-bold text-gray-400">{title}</dt>
|
||||||
<dd className="flex text-sm text-white sm:mt-0 sm:col-span-2">
|
<dd className="flex text-sm text-white sm:col-span-2 sm:mt-0">
|
||||||
<span className={`flex-grow ${className}`}>{children}</span>
|
<span className={`flex-grow ${className}`}>{children}</span>
|
||||||
</dd>
|
</dd>
|
||||||
</div>
|
</div>
|
||||||
@@ -31,7 +31,7 @@ const List: React.FC<ListProps> = ({ title, subTitle, children }) => {
|
|||||||
<h3 className="heading">{title}</h3>
|
<h3 className="heading">{title}</h3>
|
||||||
{subTitle && <p className="description">{subTitle}</p>}
|
{subTitle && <p className="description">{subTitle}</p>}
|
||||||
</div>
|
</div>
|
||||||
<div className="border-t border-gray-800 section">
|
<div className="section border-t border-gray-800">
|
||||||
<dl className="divide-y divide-gray-800">{children}</dl>
|
<dl className="divide-y divide-gray-800">{children}</dl>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ const ListView: React.FC<ListViewProps> = ({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{isEmpty && (
|
{isEmpty && (
|
||||||
<div className="w-full mt-64 text-2xl text-center text-gray-400">
|
<div className="mt-64 w-full text-center text-2xl text-gray-400">
|
||||||
{intl.formatMessage(globalMessages.noresults)}
|
{intl.formatMessage(globalMessages.noresults)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ import React from 'react';
|
|||||||
|
|
||||||
export const SmallLoadingSpinner: React.FC = () => {
|
export const SmallLoadingSpinner: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
<div className="inset-0 flex items-center justify-center w-full h-full text-gray-200">
|
<div className="inset-0 flex h-full w-full items-center justify-center text-gray-200">
|
||||||
<svg
|
<svg
|
||||||
className="w-10 h-10"
|
className="h-10 w-10"
|
||||||
viewBox="0 0 38 38"
|
viewBox="0 0 38 38"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
@@ -31,9 +31,9 @@ export const SmallLoadingSpinner: React.FC = () => {
|
|||||||
|
|
||||||
const LoadingSpinner: React.FC = () => {
|
const LoadingSpinner: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
<div className="inset-0 flex items-center justify-center h-64 text-gray-200">
|
<div className="inset-0 flex h-64 items-center justify-center text-gray-200">
|
||||||
<svg
|
<svg
|
||||||
className="w-16 h-16"
|
className="h-16 w-16"
|
||||||
viewBox="0 0 38 38"
|
viewBox="0 0 38 38"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ const Modal: React.FC<ModalProps> = ({
|
|||||||
return ReactDOM.createPortal(
|
return ReactDOM.createPortal(
|
||||||
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
|
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
|
||||||
<div
|
<div
|
||||||
className="fixed top-0 bottom-0 left-0 right-0 z-50 flex items-center justify-center w-full h-full bg-gray-800 bg-opacity-70"
|
className="fixed top-0 bottom-0 left-0 right-0 z-50 flex h-full w-full items-center justify-center bg-gray-800 bg-opacity-70"
|
||||||
onKeyDown={(e) => {
|
onKeyDown={(e) => {
|
||||||
if (e.key === 'Escape') {
|
if (e.key === 'Escape') {
|
||||||
typeof onCancel === 'function' && backgroundClickable
|
typeof onCancel === 'function' && backgroundClickable
|
||||||
@@ -101,7 +101,7 @@ const Modal: React.FC<ModalProps> = ({
|
|||||||
show={!loading}
|
show={!loading}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="relative inline-block w-full px-4 pt-5 pb-4 overflow-auto text-left align-bottom transition-all transform bg-gray-700 shadow-xl ring-1 ring-gray-500 sm:rounded-lg sm:my-8 sm:align-middle sm:max-w-3xl"
|
className="relative inline-block w-full transform overflow-auto bg-gray-700 px-4 pt-5 pb-4 text-left align-bottom shadow-xl ring-1 ring-gray-500 transition-all sm:my-8 sm:max-w-3xl sm:rounded-lg sm:align-middle"
|
||||||
role="dialog"
|
role="dialog"
|
||||||
aria-modal="true"
|
aria-modal="true"
|
||||||
aria-labelledby="modal-headline"
|
aria-labelledby="modal-headline"
|
||||||
@@ -111,7 +111,7 @@ const Modal: React.FC<ModalProps> = ({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{backdrop && (
|
{backdrop && (
|
||||||
<div className="absolute top-0 left-0 right-0 z-0 w-full h-64 max-h-full">
|
<div className="absolute top-0 left-0 right-0 z-0 h-64 max-h-full w-full">
|
||||||
<CachedImage
|
<CachedImage
|
||||||
alt=""
|
alt=""
|
||||||
src={backdrop}
|
src={backdrop}
|
||||||
@@ -131,13 +131,13 @@ const Modal: React.FC<ModalProps> = ({
|
|||||||
<div className="relative overflow-x-hidden sm:flex sm:items-center">
|
<div className="relative overflow-x-hidden sm:flex sm:items-center">
|
||||||
{iconSvg && <div className="modal-icon">{iconSvg}</div>}
|
{iconSvg && <div className="modal-icon">{iconSvg}</div>}
|
||||||
<div
|
<div
|
||||||
className={`mt-3 text-center sm:mt-0 sm:text-left truncate text-white ${
|
className={`mt-3 truncate text-center text-white sm:mt-0 sm:text-left ${
|
||||||
iconSvg ? 'sm:ml-4' : 'sm:mb-4'
|
iconSvg ? 'sm:ml-4' : 'sm:mb-4'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{title && (
|
{title && (
|
||||||
<span
|
<span
|
||||||
className="text-lg font-bold leading-6 truncate"
|
className="truncate text-lg font-bold leading-6"
|
||||||
id="modal-headline"
|
id="modal-headline"
|
||||||
>
|
>
|
||||||
{title}
|
{title}
|
||||||
@@ -151,7 +151,7 @@ const Modal: React.FC<ModalProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{(onCancel || onOk || onSecondary || onTertiary) && (
|
{(onCancel || onOk || onSecondary || onTertiary) && (
|
||||||
<div className="relative flex flex-row-reverse justify-center mt-5 sm:mt-4 sm:justify-start">
|
<div className="relative mt-5 flex flex-row-reverse justify-center sm:mt-4 sm:justify-start">
|
||||||
{typeof onOk === 'function' && (
|
{typeof onOk === 'function' && (
|
||||||
<Button
|
<Button
|
||||||
buttonType={okButtonType}
|
buttonType={okButtonType}
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ const SettingsTabs: React.FC<{
|
|||||||
</div>
|
</div>
|
||||||
{tabType === 'button' ? (
|
{tabType === 'button' ? (
|
||||||
<div className="hidden sm:block">
|
<div className="hidden sm:block">
|
||||||
<nav className="flex flex-wrap -mx-2 -my-1" aria-label="Tabs">
|
<nav className="-mx-2 -my-1 flex flex-wrap" aria-label="Tabs">
|
||||||
{settingsRoutes.map((route, index) => (
|
{settingsRoutes.map((route, index) => (
|
||||||
<SettingsLink
|
<SettingsLink
|
||||||
tabType={tabType}
|
tabType={tabType}
|
||||||
@@ -136,7 +136,7 @@ const SettingsTabs: React.FC<{
|
|||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="hidden overflow-x-scroll border-b border-gray-600 sm:block hide-scrollbar">
|
<div className="hide-scrollbar hidden overflow-x-scroll border-b border-gray-600 sm:block">
|
||||||
<nav className="flex">
|
<nav className="flex">
|
||||||
{settingsRoutes
|
{settingsRoutes
|
||||||
.filter(
|
.filter(
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ const SlideOver: React.FC<SlideOverProps> = ({
|
|||||||
>
|
>
|
||||||
{/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}
|
{/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}
|
||||||
<div
|
<div
|
||||||
className={`z-50 fixed inset-0 overflow-hidden bg-opacity-70 bg-gray-800`}
|
className={`fixed inset-0 z-50 overflow-hidden bg-gray-800 bg-opacity-70`}
|
||||||
onClick={() => onClose()}
|
onClick={() => onClose()}
|
||||||
onKeyDown={(e) => {
|
onKeyDown={(e) => {
|
||||||
if (e.key === 'Escape') {
|
if (e.key === 'Escape') {
|
||||||
@@ -70,19 +70,19 @@ const SlideOver: React.FC<SlideOverProps> = ({
|
|||||||
ref={slideoverRef}
|
ref={slideoverRef}
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
>
|
>
|
||||||
<div className="flex flex-col h-full overflow-y-scroll bg-gray-700 shadow-xl">
|
<div className="flex h-full flex-col overflow-y-scroll bg-gray-700 shadow-xl">
|
||||||
<header className="px-4 space-y-1 bg-indigo-600 slideover">
|
<header className="slideover space-y-1 bg-indigo-600 px-4">
|
||||||
<div className="flex items-center justify-between space-x-3">
|
<div className="flex items-center justify-between space-x-3">
|
||||||
<h2 className="text-lg font-bold leading-7 text-white">
|
<h2 className="text-lg font-bold leading-7 text-white">
|
||||||
{title}
|
{title}
|
||||||
</h2>
|
</h2>
|
||||||
<div className="flex items-center h-7">
|
<div className="flex h-7 items-center">
|
||||||
<button
|
<button
|
||||||
aria-label="Close panel"
|
aria-label="Close panel"
|
||||||
className="text-indigo-200 transition duration-150 ease-in-out hover:text-white"
|
className="text-indigo-200 transition duration-150 ease-in-out hover:text-white"
|
||||||
onClick={() => onClose()}
|
onClick={() => onClose()}
|
||||||
>
|
>
|
||||||
<XIcon className="w-6 h-6" />
|
<XIcon className="h-6 w-6" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { withProperties } from '../../../utils/typeHelpers';
|
|||||||
|
|
||||||
const TBody: React.FC = ({ children }) => {
|
const TBody: React.FC = ({ children }) => {
|
||||||
return (
|
return (
|
||||||
<tbody className="bg-gray-800 divide-y divide-gray-700">{children}</tbody>
|
<tbody className="divide-y divide-gray-700 bg-gray-800">{children}</tbody>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ const CompanyCard: React.FC<CompanyCardProps> = ({ image, url, name }) => {
|
|||||||
return (
|
return (
|
||||||
<Link href={url}>
|
<Link href={url}>
|
||||||
<a
|
<a
|
||||||
className={`relative flex items-center justify-center h-32 w-56 sm:h-36 sm:w-72 p-8 shadow transition ease-in-out duration-300 cursor-pointer transform-gpu ring-1 ${
|
className={`relative flex h-32 w-56 transform-gpu cursor-pointer items-center justify-center p-8 shadow ring-1 transition duration-300 ease-in-out sm:h-36 sm:w-72 ${
|
||||||
isHovered
|
isHovered
|
||||||
? 'bg-gray-700 scale-105 ring-gray-500'
|
? 'scale-105 bg-gray-700 ring-gray-500'
|
||||||
: 'bg-gray-800 scale-100 ring-gray-700'
|
: 'scale-100 bg-gray-800 ring-gray-700'
|
||||||
} rounded-xl`}
|
} rounded-xl`}
|
||||||
onMouseEnter={() => {
|
onMouseEnter={() => {
|
||||||
setHovered(true);
|
setHovered(true);
|
||||||
@@ -33,10 +33,10 @@ const CompanyCard: React.FC<CompanyCardProps> = ({ image, url, name }) => {
|
|||||||
<img
|
<img
|
||||||
src={image}
|
src={image}
|
||||||
alt={name}
|
alt={name}
|
||||||
className="relative z-40 max-w-full max-h-full"
|
className="relative z-40 max-h-full max-w-full"
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
className={`absolute bottom-0 left-0 right-0 h-12 rounded-b-xl bg-gradient-to-t z-0 ${
|
className={`absolute bottom-0 left-0 right-0 z-0 h-12 rounded-b-xl bg-gradient-to-t ${
|
||||||
isHovered ? 'from-gray-800' : 'from-gray-900'
|
isHovered ? 'from-gray-800' : 'from-gray-900'
|
||||||
}`}
|
}`}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ const DiscoverTvNetwork: React.FC = () => {
|
|||||||
<div className="mt-1 mb-5">
|
<div className="mt-1 mb-5">
|
||||||
<Header>
|
<Header>
|
||||||
{firstResultData?.network.logoPath ? (
|
{firstResultData?.network.logoPath ? (
|
||||||
<div className="flex justify-center mb-6">
|
<div className="mb-6 flex justify-center">
|
||||||
<img
|
<img
|
||||||
src={`//image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)${firstResultData.network.logoPath}`}
|
src={`//image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)${firstResultData.network.logoPath}`}
|
||||||
alt={firstResultData.network.name}
|
alt={firstResultData.network.name}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ const DiscoverMovieStudio: React.FC = () => {
|
|||||||
<div className="mt-1 mb-5">
|
<div className="mt-1 mb-5">
|
||||||
<Header>
|
<Header>
|
||||||
{firstResultData?.studio.logoPath ? (
|
{firstResultData?.studio.logoPath ? (
|
||||||
<div className="flex justify-center mb-6">
|
<div className="mb-6 flex justify-center">
|
||||||
<img
|
<img
|
||||||
src={`//image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)${firstResultData.studio.logoPath}`}
|
src={`//image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)${firstResultData.studio.logoPath}`}
|
||||||
alt={firstResultData.studio.name}
|
alt={firstResultData.studio.name}
|
||||||
|
|||||||
@@ -20,12 +20,12 @@ const DownloadBlock: React.FC<DownloadBlockProps> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="p-4">
|
<div className="p-4">
|
||||||
<div className="w-56 mb-2 text-sm truncate sm:w-80 md:w-full">
|
<div className="mb-2 w-56 truncate text-sm sm:w-80 md:w-full">
|
||||||
{downloadItem.title}
|
{downloadItem.title}
|
||||||
</div>
|
</div>
|
||||||
<div className="relative h-6 min-w-0 mb-2 overflow-hidden bg-gray-700 rounded-full">
|
<div className="relative mb-2 h-6 min-w-0 overflow-hidden rounded-full bg-gray-700">
|
||||||
<div
|
<div
|
||||||
className="h-8 transition-all duration-200 ease-in-out bg-indigo-600"
|
className="h-8 bg-indigo-600 transition-all duration-200 ease-in-out"
|
||||||
style={{
|
style={{
|
||||||
width: `${
|
width: `${
|
||||||
downloadItem.size
|
downloadItem.size
|
||||||
@@ -38,7 +38,7 @@ const DownloadBlock: React.FC<DownloadBlockProps> = ({
|
|||||||
}%`,
|
}%`,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<div className="absolute inset-0 flex items-center justify-center w-full h-6 text-xs">
|
<div className="absolute inset-0 flex h-6 w-full items-center justify-center text-xs">
|
||||||
<span>
|
<span>
|
||||||
{downloadItem.size
|
{downloadItem.size
|
||||||
? Math.round(
|
? Math.round(
|
||||||
|
|||||||
@@ -28,11 +28,11 @@ const ExternalLinkBlock: React.FC<ExternalLinkBlockProps> = ({
|
|||||||
const { locale } = useLocale();
|
const { locale } = useLocale();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center justify-center w-full space-x-5">
|
<div className="flex w-full items-center justify-center space-x-5">
|
||||||
{plexUrl && (
|
{plexUrl && (
|
||||||
<a
|
<a
|
||||||
href={plexUrl}
|
href={plexUrl}
|
||||||
className="w-12 transition duration-300 opacity-50 hover:opacity-100"
|
className="w-12 opacity-50 transition duration-300 hover:opacity-100"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
>
|
>
|
||||||
@@ -42,7 +42,7 @@ const ExternalLinkBlock: React.FC<ExternalLinkBlockProps> = ({
|
|||||||
{tmdbId && (
|
{tmdbId && (
|
||||||
<a
|
<a
|
||||||
href={`https://www.themoviedb.org/${mediaType}/${tmdbId}?language=${locale}`}
|
href={`https://www.themoviedb.org/${mediaType}/${tmdbId}?language=${locale}`}
|
||||||
className="w-8 transition duration-300 opacity-50 hover:opacity-100"
|
className="w-8 opacity-50 transition duration-300 hover:opacity-100"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
>
|
>
|
||||||
@@ -52,7 +52,7 @@ const ExternalLinkBlock: React.FC<ExternalLinkBlockProps> = ({
|
|||||||
{tvdbId && mediaType === MediaType.TV && (
|
{tvdbId && mediaType === MediaType.TV && (
|
||||||
<a
|
<a
|
||||||
href={`http://www.thetvdb.com/?tab=series&id=${tvdbId}`}
|
href={`http://www.thetvdb.com/?tab=series&id=${tvdbId}`}
|
||||||
className="transition duration-300 opacity-50 w-9 hover:opacity-100"
|
className="w-9 opacity-50 transition duration-300 hover:opacity-100"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
>
|
>
|
||||||
@@ -62,7 +62,7 @@ const ExternalLinkBlock: React.FC<ExternalLinkBlockProps> = ({
|
|||||||
{imdbId && (
|
{imdbId && (
|
||||||
<a
|
<a
|
||||||
href={`https://www.imdb.com/title/${imdbId}`}
|
href={`https://www.imdb.com/title/${imdbId}`}
|
||||||
className="w-8 transition duration-300 opacity-50 hover:opacity-100"
|
className="w-8 opacity-50 transition duration-300 hover:opacity-100"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
>
|
>
|
||||||
@@ -72,7 +72,7 @@ const ExternalLinkBlock: React.FC<ExternalLinkBlockProps> = ({
|
|||||||
{rtUrl && (
|
{rtUrl && (
|
||||||
<a
|
<a
|
||||||
href={`${rtUrl}`}
|
href={`${rtUrl}`}
|
||||||
className="transition duration-300 opacity-50 w-14 hover:opacity-100"
|
className="w-14 opacity-50 transition duration-300 hover:opacity-100"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
>
|
>
|
||||||
@@ -84,7 +84,7 @@ const ExternalLinkBlock: React.FC<ExternalLinkBlockProps> = ({
|
|||||||
href={`https://trakt.tv/search/tmdb/${tmdbId}?id_type=${
|
href={`https://trakt.tv/search/tmdb/${tmdbId}?id_type=${
|
||||||
mediaType === 'movie' ? 'movie' : 'show'
|
mediaType === 'movie' ? 'movie' : 'show'
|
||||||
}`}
|
}`}
|
||||||
className="w-8 transition duration-300 opacity-50 hover:opacity-100"
|
className="w-8 opacity-50 transition duration-300 hover:opacity-100"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -21,13 +21,13 @@ const GenreCard: React.FC<GenreCardProps> = ({
|
|||||||
return (
|
return (
|
||||||
<Link href={url}>
|
<Link href={url}>
|
||||||
<a
|
<a
|
||||||
className={`relative flex items-center justify-center h-32 sm:h-36 ${
|
className={`relative flex h-32 items-center justify-center sm:h-36 ${
|
||||||
canExpand ? 'w-full' : 'w-56 sm:w-72'
|
canExpand ? 'w-full' : 'w-56 sm:w-72'
|
||||||
} p-8 shadow transition ease-in-out duration-300 cursor-pointer transform-gpu ring-1 ${
|
} transform-gpu cursor-pointer p-8 shadow ring-1 transition duration-300 ease-in-out ${
|
||||||
isHovered
|
isHovered
|
||||||
? 'bg-gray-700 scale-105 ring-gray-500 bg-opacity-100'
|
? 'scale-105 bg-gray-700 bg-opacity-100 ring-gray-500'
|
||||||
: 'bg-gray-800 scale-100 ring-gray-700 bg-opacity-80'
|
: 'scale-100 bg-gray-800 bg-opacity-80 ring-gray-700'
|
||||||
} rounded-xl bg-cover bg-center overflow-hidden`}
|
} overflow-hidden rounded-xl bg-cover bg-center`}
|
||||||
onMouseEnter={() => {
|
onMouseEnter={() => {
|
||||||
setHovered(true);
|
setHovered(true);
|
||||||
}}
|
}}
|
||||||
@@ -42,11 +42,11 @@ const GenreCard: React.FC<GenreCardProps> = ({
|
|||||||
>
|
>
|
||||||
<CachedImage src={image} alt="" layout="fill" objectFit="cover" />
|
<CachedImage src={image} alt="" layout="fill" objectFit="cover" />
|
||||||
<div
|
<div
|
||||||
className={`absolute z-10 inset-0 w-full h-full transition duration-300 bg-gray-800 ${
|
className={`absolute inset-0 z-10 h-full w-full bg-gray-800 transition duration-300 ${
|
||||||
isHovered ? 'bg-opacity-10' : 'bg-opacity-30'
|
isHovered ? 'bg-opacity-10' : 'bg-opacity-30'
|
||||||
}`}
|
}`}
|
||||||
/>
|
/>
|
||||||
<div className="relative z-20 w-full text-2xl font-bold text-center text-white truncate whitespace-normal sm:text-3xl">
|
<div className="relative z-20 w-full truncate whitespace-normal text-center text-2xl font-bold text-white sm:text-3xl">
|
||||||
{name}
|
{name}
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
@@ -57,7 +57,7 @@ const GenreCard: React.FC<GenreCardProps> = ({
|
|||||||
const GenreCardPlaceholder: React.FC = () => {
|
const GenreCardPlaceholder: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`relative h-32 w-56 sm:h-40 sm:w-72 animate-pulse rounded-xl bg-gray-700`}
|
className={`relative h-32 w-56 animate-pulse rounded-xl bg-gray-700 sm:h-40 sm:w-72`}
|
||||||
></div>
|
></div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -30,15 +30,15 @@ const IssueBlock: React.FC<IssueBlockProps> = ({ issue }) => {
|
|||||||
return (
|
return (
|
||||||
<div className="px-4 py-3 text-gray-300">
|
<div className="px-4 py-3 text-gray-300">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex-col items-center flex-1 min-w-0 mr-6 text-sm leading-5">
|
<div className="mr-6 min-w-0 flex-1 flex-col items-center text-sm leading-5">
|
||||||
<div className="flex flex-nowrap">
|
<div className="flex flex-nowrap">
|
||||||
<ExclamationIcon className="flex-shrink-0 mr-1.5 h-5 w-5" />
|
<ExclamationIcon className="mr-1.5 h-5 w-5 flex-shrink-0" />
|
||||||
<span className="w-40 truncate md:w-auto">
|
<span className="w-40 truncate md:w-auto">
|
||||||
{intl.formatMessage(issueOption.name)}
|
{intl.formatMessage(issueOption.name)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex mb-1 flex-nowrap white">
|
<div className="white mb-1 flex flex-nowrap">
|
||||||
<UserIcon className="min-w-0 flex-shrink-0 mr-1.5 h-5 w-5" />
|
<UserIcon className="mr-1.5 h-5 w-5 min-w-0 flex-shrink-0" />
|
||||||
<span className="w-40 truncate md:w-auto">
|
<span className="w-40 truncate md:w-auto">
|
||||||
<Link
|
<Link
|
||||||
href={
|
href={
|
||||||
@@ -53,8 +53,8 @@ const IssueBlock: React.FC<IssueBlockProps> = ({ issue }) => {
|
|||||||
</Link>
|
</Link>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex mb-1 flex-nowrap white">
|
<div className="white mb-1 flex flex-nowrap">
|
||||||
<CalendarIcon className="min-w-0 flex-shrink-0 mr-1.5 h-5 w-5" />
|
<CalendarIcon className="mr-1.5 h-5 w-5 min-w-0 flex-shrink-0" />
|
||||||
<span className="w-40 truncate md:w-auto">
|
<span className="w-40 truncate md:w-auto">
|
||||||
{intl.formatDate(issue.createdAt, {
|
{intl.formatDate(issue.createdAt, {
|
||||||
year: 'numeric',
|
year: 'numeric',
|
||||||
@@ -64,7 +64,7 @@ const IssueBlock: React.FC<IssueBlockProps> = ({ issue }) => {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-wrap flex-shrink-0 ml-2">
|
<div className="ml-2 flex flex-shrink-0 flex-wrap">
|
||||||
<Link href={`/issues/${issue.id}`} passHref>
|
<Link href={`/issues/${issue.id}`} passHref>
|
||||||
<Button buttonType="primary" as="a">
|
<Button buttonType="primary" as="a">
|
||||||
<EyeIcon />
|
<EyeIcon />
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ const IssueComment: React.FC<IssueCommentProps> = ({
|
|||||||
<img
|
<img
|
||||||
src={comment.user.avatar}
|
src={comment.user.avatar}
|
||||||
alt=""
|
alt=""
|
||||||
className="w-10 h-10 transition duration-300 scale-100 rounded-full ring-1 ring-gray-500 transform-gpu hover:scale-105"
|
className="h-10 w-10 scale-100 transform-gpu rounded-full ring-1 ring-gray-500 transition duration-300 hover:scale-105"
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
@@ -99,15 +99,15 @@ const IssueComment: React.FC<IssueCommentProps> = ({
|
|||||||
{(isActiveUser || hasPermission(Permission.MANAGE_ISSUES)) && (
|
{(isActiveUser || hasPermission(Permission.MANAGE_ISSUES)) && (
|
||||||
<Menu
|
<Menu
|
||||||
as="div"
|
as="div"
|
||||||
className="absolute z-40 inline-block text-left top-2 right-1"
|
className="absolute top-2 right-1 z-40 inline-block text-left"
|
||||||
>
|
>
|
||||||
{({ open }) => (
|
{({ open }) => (
|
||||||
<>
|
<>
|
||||||
<div>
|
<div>
|
||||||
<Menu.Button className="flex items-center text-gray-400 rounded-full hover:text-gray-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-indigo-500">
|
<Menu.Button className="flex items-center rounded-full text-gray-400 hover:text-gray-200 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 focus:ring-offset-gray-100">
|
||||||
<span className="sr-only">Open options</span>
|
<span className="sr-only">Open options</span>
|
||||||
<DotsVerticalIcon
|
<DotsVerticalIcon
|
||||||
className="w-5 h-5"
|
className="h-5 w-5"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
</Menu.Button>
|
</Menu.Button>
|
||||||
@@ -124,7 +124,7 @@ const IssueComment: React.FC<IssueCommentProps> = ({
|
|||||||
>
|
>
|
||||||
<Menu.Items
|
<Menu.Items
|
||||||
static
|
static
|
||||||
className="absolute right-0 w-56 mt-2 origin-top-right bg-gray-700 rounded-md shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none"
|
className="absolute right-0 mt-2 w-56 origin-top-right rounded-md bg-gray-700 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none"
|
||||||
>
|
>
|
||||||
<div className="py-1">
|
<div className="py-1">
|
||||||
{isActiveUser && (
|
{isActiveUser && (
|
||||||
@@ -132,7 +132,7 @@ const IssueComment: React.FC<IssueCommentProps> = ({
|
|||||||
{({ active }) => (
|
{({ active }) => (
|
||||||
<button
|
<button
|
||||||
onClick={() => setIsEditing(true)}
|
onClick={() => setIsEditing(true)}
|
||||||
className={`block w-full text-left px-4 py-2 text-sm ${
|
className={`block w-full px-4 py-2 text-left text-sm ${
|
||||||
active
|
active
|
||||||
? 'bg-gray-600 text-white'
|
? 'bg-gray-600 text-white'
|
||||||
: 'text-gray-100'
|
: 'text-gray-100'
|
||||||
@@ -147,7 +147,7 @@ const IssueComment: React.FC<IssueCommentProps> = ({
|
|||||||
{({ active }) => (
|
{({ active }) => (
|
||||||
<button
|
<button
|
||||||
onClick={() => setShowDeleteModal(true)}
|
onClick={() => setShowDeleteModal(true)}
|
||||||
className={`block w-full text-left px-4 py-2 text-sm ${
|
className={`block w-full px-4 py-2 text-left text-sm ${
|
||||||
active
|
active
|
||||||
? 'bg-gray-600 text-white'
|
? 'bg-gray-600 text-white'
|
||||||
: 'text-gray-100'
|
: 'text-gray-100'
|
||||||
@@ -165,11 +165,11 @@ const IssueComment: React.FC<IssueCommentProps> = ({
|
|||||||
</Menu>
|
</Menu>
|
||||||
)}
|
)}
|
||||||
<div
|
<div
|
||||||
className={`absolute w-3 h-3 transform rotate-45 bg-gray-800 shadow top-3 z-10 ring-1 ring-gray-500 ${
|
className={`absolute top-3 z-10 h-3 w-3 rotate-45 transform bg-gray-800 shadow ring-1 ring-gray-500 ${
|
||||||
isReversed ? '-left-1' : '-right-1'
|
isReversed ? '-left-1' : '-right-1'
|
||||||
}`}
|
}`}
|
||||||
/>
|
/>
|
||||||
<div className="relative z-20 w-full py-4 pl-4 pr-8 bg-gray-800 rounded-md">
|
<div className="relative z-20 w-full rounded-md bg-gray-800 py-4 pl-4 pr-8">
|
||||||
{isEditing ? (
|
{isEditing ? (
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={{ newMessage: comment.message }}
|
initialValues={{ newMessage: comment.message }}
|
||||||
@@ -198,7 +198,7 @@ const IssueComment: React.FC<IssueCommentProps> = ({
|
|||||||
{errors.newMessage && touched.newMessage && (
|
{errors.newMessage && touched.newMessage && (
|
||||||
<div className="error">{errors.newMessage}</div>
|
<div className="error">{errors.newMessage}</div>
|
||||||
)}
|
)}
|
||||||
<div className="flex items-center justify-end mt-4 space-x-2">
|
<div className="mt-4 flex items-center justify-end space-x-2">
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setIsEditing(false)}
|
onClick={() => setIsEditing(false)}
|
||||||
@@ -217,7 +217,7 @@ const IssueComment: React.FC<IssueCommentProps> = ({
|
|||||||
}}
|
}}
|
||||||
</Formik>
|
</Formik>
|
||||||
) : (
|
) : (
|
||||||
<div className="w-full max-w-full prose">
|
<div className="prose w-full max-w-full">
|
||||||
<ReactMarkdown skipHtml allowedElements={['p', 'em', 'strong']}>
|
<ReactMarkdown skipHtml allowedElements={['p', 'em', 'strong']}>
|
||||||
{comment.message}
|
{comment.message}
|
||||||
</ReactMarkdown>
|
</ReactMarkdown>
|
||||||
@@ -226,7 +226,7 @@ const IssueComment: React.FC<IssueCommentProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={`flex justify-between items-center text-xs pt-2 ${
|
className={`flex items-center justify-between pt-2 text-xs ${
|
||||||
isReversed ? 'flex-row-reverse' : 'flex-row'
|
isReversed ? 'flex-row-reverse' : 'flex-row'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -44,9 +44,9 @@ const IssueDescription: React.FC<IssueDescriptionProps> = ({
|
|||||||
{({ open }) => (
|
{({ open }) => (
|
||||||
<>
|
<>
|
||||||
<div>
|
<div>
|
||||||
<Menu.Button className="flex items-center text-gray-400 rounded-full hover:text-gray-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-indigo-500">
|
<Menu.Button className="flex items-center rounded-full text-gray-400 hover:text-gray-200 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 focus:ring-offset-gray-100">
|
||||||
<span className="sr-only">Open options</span>
|
<span className="sr-only">Open options</span>
|
||||||
<DotsVerticalIcon className="w-5 h-5" aria-hidden="true" />
|
<DotsVerticalIcon className="h-5 w-5" aria-hidden="true" />
|
||||||
</Menu.Button>
|
</Menu.Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ const IssueDescription: React.FC<IssueDescriptionProps> = ({
|
|||||||
>
|
>
|
||||||
<Menu.Items
|
<Menu.Items
|
||||||
static
|
static
|
||||||
className="absolute right-0 w-56 mt-2 origin-top-right bg-gray-700 rounded-md shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none"
|
className="absolute right-0 mt-2 w-56 origin-top-right rounded-md bg-gray-700 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none"
|
||||||
>
|
>
|
||||||
<div className="py-1">
|
<div className="py-1">
|
||||||
{belongsToUser && (
|
{belongsToUser && (
|
||||||
@@ -70,7 +70,7 @@ const IssueDescription: React.FC<IssueDescriptionProps> = ({
|
|||||||
{({ active }) => (
|
{({ active }) => (
|
||||||
<button
|
<button
|
||||||
onClick={() => setIsEditing(true)}
|
onClick={() => setIsEditing(true)}
|
||||||
className={`block w-full text-left px-4 py-2 text-sm ${
|
className={`block w-full px-4 py-2 text-left text-sm ${
|
||||||
active
|
active
|
||||||
? 'bg-gray-600 text-white'
|
? 'bg-gray-600 text-white'
|
||||||
: 'text-gray-100'
|
: 'text-gray-100'
|
||||||
@@ -87,7 +87,7 @@ const IssueDescription: React.FC<IssueDescriptionProps> = ({
|
|||||||
{({ active }) => (
|
{({ active }) => (
|
||||||
<button
|
<button
|
||||||
onClick={() => onDelete()}
|
onClick={() => onDelete()}
|
||||||
className={`block w-full text-left px-4 py-2 text-sm ${
|
className={`block w-full px-4 py-2 text-left text-sm ${
|
||||||
active
|
active
|
||||||
? 'bg-gray-600 text-white'
|
? 'bg-gray-600 text-white'
|
||||||
: 'text-gray-100'
|
: 'text-gray-100'
|
||||||
@@ -123,7 +123,7 @@ const IssueDescription: React.FC<IssueDescriptionProps> = ({
|
|||||||
as="textarea"
|
as="textarea"
|
||||||
className="h-40"
|
className="h-40"
|
||||||
/>
|
/>
|
||||||
<div className="flex justify-end mt-2">
|
<div className="mt-2 flex justify-end">
|
||||||
<Button
|
<Button
|
||||||
buttonType="default"
|
buttonType="default"
|
||||||
className="mr-2"
|
className="mr-2"
|
||||||
@@ -141,7 +141,7 @@ const IssueDescription: React.FC<IssueDescriptionProps> = ({
|
|||||||
}}
|
}}
|
||||||
</Formik>
|
</Formik>
|
||||||
) : (
|
) : (
|
||||||
<div className="mt-4 prose">
|
<div className="prose mt-4">
|
||||||
<ReactMarkdown
|
<ReactMarkdown
|
||||||
allowedElements={['p', 'img', 'strong', 'em']}
|
allowedElements={['p', 'img', 'strong', 'em']}
|
||||||
skipHtml
|
skipHtml
|
||||||
|
|||||||
@@ -262,9 +262,9 @@ const IssueDetails: React.FC = () => {
|
|||||||
: `/users/${issueData.createdBy.id}`
|
: `/users/${issueData.createdBy.id}`
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<a className="inline-flex items-center h-full ml-1 xl:ml-1.5 group">
|
<a className="group ml-1 inline-flex h-full items-center xl:ml-1.5">
|
||||||
<img
|
<img
|
||||||
className="w-5 h-5 mr-0.5 transition duration-300 scale-100 rounded-full xl:w-6 xl:h-6 xl:mr-1 transform-gpu group-hover:scale-105"
|
className="mr-0.5 h-5 w-5 scale-100 transform-gpu rounded-full transition duration-300 group-hover:scale-105 xl:mr-1 xl:h-6 xl:w-6"
|
||||||
src={issueData.createdBy.avatar}
|
src={issueData.createdBy.avatar}
|
||||||
alt=""
|
alt=""
|
||||||
/>
|
/>
|
||||||
@@ -288,7 +288,7 @@ const IssueDetails: React.FC = () => {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="relative z-10 flex mt-6 text-gray-300">
|
<div className="relative z-10 mt-6 flex text-gray-300">
|
||||||
<div className="flex-1 lg:pr-4">
|
<div className="flex-1 lg:pr-4">
|
||||||
<IssueDescription
|
<IssueDescription
|
||||||
description={firstComment.message}
|
description={firstComment.message}
|
||||||
@@ -351,7 +351,7 @@ const IssueDetails: React.FC = () => {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col mt-4 mb-6 space-y-2">
|
<div className="mt-4 mb-6 flex flex-col space-y-2">
|
||||||
{issueData?.media.plexUrl && (
|
{issueData?.media.plexUrl && (
|
||||||
<Button
|
<Button
|
||||||
as="a"
|
as="a"
|
||||||
@@ -466,7 +466,7 @@ const IssueDetails: React.FC = () => {
|
|||||||
)}
|
)}
|
||||||
className="h-20"
|
className="h-20"
|
||||||
/>
|
/>
|
||||||
<div className="flex items-center justify-end mt-4 space-x-2">
|
<div className="mt-4 flex items-center justify-end space-x-2">
|
||||||
{hasPermission(Permission.MANAGE_ISSUES) && (
|
{hasPermission(Permission.MANAGE_ISSUES) && (
|
||||||
<>
|
<>
|
||||||
{issueData.status === IssueStatus.OPEN ? (
|
{issueData.status === IssueStatus.OPEN ? (
|
||||||
@@ -535,7 +535,7 @@ const IssueDetails: React.FC = () => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="hidden lg:block lg:pl-4 lg:w-80">
|
<div className="hidden lg:block lg:w-80 lg:pl-4">
|
||||||
<div className="media-facts">
|
<div className="media-facts">
|
||||||
<div className="media-fact">
|
<div className="media-fact">
|
||||||
<span>{intl.formatMessage(messages.issuetype)}</span>
|
<span>{intl.formatMessage(messages.issuetype)}</span>
|
||||||
@@ -587,7 +587,7 @@ const IssueDetails: React.FC = () => {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col mt-4 mb-6 space-y-2">
|
<div className="mt-4 mb-6 flex flex-col space-y-2">
|
||||||
{issueData?.media.plexUrl && (
|
{issueData?.media.plexUrl && (
|
||||||
<Button
|
<Button
|
||||||
as="a"
|
as="a"
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ const IssueItem: React.FC<IssueItemProps> = ({ issue }) => {
|
|||||||
if (!title && !error) {
|
if (!title && !error) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="w-full h-64 bg-gray-800 rounded-xl xl:h-28 animate-pulse"
|
className="h-64 w-full animate-pulse rounded-xl bg-gray-800 xl:h-28"
|
||||||
ref={ref}
|
ref={ref}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@@ -108,9 +108,9 @@ const IssueItem: React.FC<IssueItemProps> = ({ issue }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative flex flex-col justify-between w-full py-4 overflow-hidden text-gray-400 bg-gray-800 shadow-md ring-1 ring-gray-700 rounded-xl xl:h-28 xl:flex-row">
|
<div className="relative flex w-full flex-col justify-between overflow-hidden rounded-xl bg-gray-800 py-4 text-gray-400 shadow-md ring-1 ring-gray-700 xl:h-28 xl:flex-row">
|
||||||
{title.backdropPath && (
|
{title.backdropPath && (
|
||||||
<div className="absolute inset-0 z-0 w-full bg-center bg-cover xl:w-2/3">
|
<div className="absolute inset-0 z-0 w-full bg-cover bg-center xl:w-2/3">
|
||||||
<CachedImage
|
<CachedImage
|
||||||
src={`https://image.tmdb.org/t/p/w1920_and_h800_multi_faces/${title.backdropPath}`}
|
src={`https://image.tmdb.org/t/p/w1920_and_h800_multi_faces/${title.backdropPath}`}
|
||||||
alt=""
|
alt=""
|
||||||
@@ -126,8 +126,8 @@ const IssueItem: React.FC<IssueItemProps> = ({ issue }) => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="relative flex flex-col justify-between w-full overflow-hidden sm:flex-row">
|
<div className="relative flex w-full flex-col justify-between overflow-hidden sm:flex-row">
|
||||||
<div className="relative z-10 flex items-center w-full pl-4 pr-4 overflow-hidden xl:w-7/12 2xl:w-2/3 sm:pr-0">
|
<div className="relative z-10 flex w-full items-center overflow-hidden pl-4 pr-4 sm:pr-0 xl:w-7/12 2xl:w-2/3">
|
||||||
<Link
|
<Link
|
||||||
href={
|
href={
|
||||||
issue.media.mediaType === MediaType.MOVIE
|
issue.media.mediaType === MediaType.MOVIE
|
||||||
@@ -135,7 +135,7 @@ const IssueItem: React.FC<IssueItemProps> = ({ issue }) => {
|
|||||||
: `/tv/${issue.media.tmdbId}`
|
: `/tv/${issue.media.tmdbId}`
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<a className="relative flex-shrink-0 w-12 h-auto overflow-hidden transition duration-300 scale-100 rounded-md transform-gpu hover:scale-105">
|
<a className="relative h-auto w-12 flex-shrink-0 scale-100 transform-gpu overflow-hidden rounded-md transition duration-300 hover:scale-105">
|
||||||
<CachedImage
|
<CachedImage
|
||||||
src={
|
src={
|
||||||
title.posterPath
|
title.posterPath
|
||||||
@@ -150,8 +150,8 @@ const IssueItem: React.FC<IssueItemProps> = ({ issue }) => {
|
|||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
<div className="flex flex-col justify-center pl-2 overflow-hidden xl:pl-4">
|
<div className="flex flex-col justify-center overflow-hidden pl-2 xl:pl-4">
|
||||||
<div className="pt-0.5 sm:pt-1 text-xs text-white">
|
<div className="pt-0.5 text-xs text-white sm:pt-1">
|
||||||
{(isMovie(title) ? title.releaseDate : title.firstAirDate)?.slice(
|
{(isMovie(title) ? title.releaseDate : title.firstAirDate)?.slice(
|
||||||
0,
|
0,
|
||||||
4
|
4
|
||||||
@@ -164,7 +164,7 @@ const IssueItem: React.FC<IssueItemProps> = ({ issue }) => {
|
|||||||
: `/tv/${issue.media.tmdbId}`
|
: `/tv/${issue.media.tmdbId}`
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<a className="min-w-0 mr-2 text-lg font-bold text-white truncate xl:text-xl hover:underline">
|
<a className="mr-2 min-w-0 truncate text-lg font-bold text-white hover:underline xl:text-xl">
|
||||||
{isMovie(title) ? title.title : title.name}
|
{isMovie(title) ? title.title : title.name}
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
@@ -177,7 +177,7 @@ const IssueItem: React.FC<IssueItemProps> = ({ issue }) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="z-10 flex flex-col justify-center w-full pr-4 mt-4 ml-4 overflow-hidden text-sm sm:ml-2 sm:mt-0 xl:flex-1 xl:pr-0">
|
<div className="z-10 mt-4 ml-4 flex w-full flex-col justify-center overflow-hidden pr-4 text-sm sm:ml-2 sm:mt-0 xl:flex-1 xl:pr-0">
|
||||||
<div className="card-field">
|
<div className="card-field">
|
||||||
<span className="card-field-name">
|
<span className="card-field-name">
|
||||||
{intl.formatMessage(messages.issuestatus)}
|
{intl.formatMessage(messages.issuestatus)}
|
||||||
@@ -196,7 +196,7 @@ const IssueItem: React.FC<IssueItemProps> = ({ issue }) => {
|
|||||||
<span className="card-field-name">
|
<span className="card-field-name">
|
||||||
{intl.formatMessage(messages.issuetype)}
|
{intl.formatMessage(messages.issuetype)}
|
||||||
</span>
|
</span>
|
||||||
<span className="flex text-sm text-gray-300 truncate">
|
<span className="flex truncate text-sm text-gray-300">
|
||||||
{intl.formatMessage(
|
{intl.formatMessage(
|
||||||
issueOption?.name ?? messages.unknownissuetype
|
issueOption?.name ?? messages.unknownissuetype
|
||||||
)}
|
)}
|
||||||
@@ -210,7 +210,7 @@ const IssueItem: React.FC<IssueItemProps> = ({ issue }) => {
|
|||||||
<span className="card-field-name">
|
<span className="card-field-name">
|
||||||
{intl.formatMessage(messages.opened)}
|
{intl.formatMessage(messages.opened)}
|
||||||
</span>
|
</span>
|
||||||
<span className="flex text-sm text-gray-300 truncate">
|
<span className="flex truncate text-sm text-gray-300">
|
||||||
{intl.formatMessage(messages.openeduserdate, {
|
{intl.formatMessage(messages.openeduserdate, {
|
||||||
date: (
|
date: (
|
||||||
<FormattedRelativeTime
|
<FormattedRelativeTime
|
||||||
@@ -224,13 +224,13 @@ const IssueItem: React.FC<IssueItemProps> = ({ issue }) => {
|
|||||||
),
|
),
|
||||||
user: (
|
user: (
|
||||||
<Link href={`/users/${issue.createdBy.id}`}>
|
<Link href={`/users/${issue.createdBy.id}`}>
|
||||||
<a className="flex items-center truncate group">
|
<a className="group flex items-center truncate">
|
||||||
<img
|
<img
|
||||||
src={issue.createdBy.avatar}
|
src={issue.createdBy.avatar}
|
||||||
alt=""
|
alt=""
|
||||||
className="ml-1.5 avatar-sm"
|
className="avatar-sm ml-1.5"
|
||||||
/>
|
/>
|
||||||
<span className="text-sm font-semibold truncate group-hover:underline group-hover:text-white">
|
<span className="truncate text-sm font-semibold group-hover:text-white group-hover:underline">
|
||||||
{issue.createdBy.displayName}
|
{issue.createdBy.displayName}
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
@@ -244,7 +244,7 @@ const IssueItem: React.FC<IssueItemProps> = ({ issue }) => {
|
|||||||
<span className="card-field-name">
|
<span className="card-field-name">
|
||||||
{intl.formatMessage(messages.opened)}
|
{intl.formatMessage(messages.opened)}
|
||||||
</span>
|
</span>
|
||||||
<span className="flex text-sm text-gray-300 truncate">
|
<span className="flex truncate text-sm text-gray-300">
|
||||||
<FormattedRelativeTime
|
<FormattedRelativeTime
|
||||||
value={Math.floor(
|
value={Math.floor(
|
||||||
(new Date(issue.createdAt).getTime() - Date.now()) / 1000
|
(new Date(issue.createdAt).getTime() - Date.now()) / 1000
|
||||||
@@ -258,7 +258,7 @@ const IssueItem: React.FC<IssueItemProps> = ({ issue }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="z-10 flex flex-col justify-center w-full pl-4 pr-4 mt-4 xl:mt-0 xl:items-end xl:w-96 xl:pl-0">
|
<div className="z-10 mt-4 flex w-full flex-col justify-center pl-4 pr-4 xl:mt-0 xl:w-96 xl:items-end xl:pl-0">
|
||||||
<span className="w-full">
|
<span className="w-full">
|
||||||
<Link href={`/issues/${issue.id}`} passHref>
|
<Link href={`/issues/${issue.id}`} passHref>
|
||||||
<Button as="a" className="w-full" buttonType="primary">
|
<Button as="a" className="w-full" buttonType="primary">
|
||||||
|
|||||||
@@ -93,12 +93,12 @@ const IssueList: React.FC = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageTitle title={intl.formatMessage(messages.issues)} />
|
<PageTitle title={intl.formatMessage(messages.issues)} />
|
||||||
<div className="flex flex-col justify-between mb-4 lg:items-end lg:flex-row">
|
<div className="mb-4 flex flex-col justify-between lg:flex-row lg:items-end">
|
||||||
<Header>{intl.formatMessage(messages.issues)}</Header>
|
<Header>{intl.formatMessage(messages.issues)}</Header>
|
||||||
<div className="flex flex-col flex-grow mt-2 sm:flex-row lg:flex-grow-0">
|
<div className="mt-2 flex flex-grow flex-col sm:flex-row lg:flex-grow-0">
|
||||||
<div className="flex flex-grow mb-2 sm:mb-0 sm:mr-2 lg:flex-grow-0">
|
<div className="mb-2 flex flex-grow sm:mb-0 sm:mr-2 lg:flex-grow-0">
|
||||||
<span className="inline-flex items-center px-3 text-sm text-gray-100 bg-gray-800 border border-r-0 border-gray-500 cursor-default rounded-l-md">
|
<span className="inline-flex cursor-default items-center rounded-l-md border border-r-0 border-gray-500 bg-gray-800 px-3 text-sm text-gray-100">
|
||||||
<FilterIcon className="w-6 h-6" />
|
<FilterIcon className="h-6 w-6" />
|
||||||
</span>
|
</span>
|
||||||
<select
|
<select
|
||||||
id="filter"
|
id="filter"
|
||||||
@@ -126,9 +126,9 @@ const IssueList: React.FC = () => {
|
|||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-grow mb-2 sm:mb-0 lg:flex-grow-0">
|
<div className="mb-2 flex flex-grow sm:mb-0 lg:flex-grow-0">
|
||||||
<span className="inline-flex items-center px-3 text-gray-100 bg-gray-800 border border-r-0 border-gray-500 cursor-default sm:text-sm rounded-l-md">
|
<span className="inline-flex cursor-default items-center rounded-l-md border border-r-0 border-gray-500 bg-gray-800 px-3 text-gray-100 sm:text-sm">
|
||||||
<SortDescendingIcon className="w-6 h-6" />
|
<SortDescendingIcon className="h-6 w-6" />
|
||||||
</span>
|
</span>
|
||||||
<select
|
<select
|
||||||
id="sort"
|
id="sort"
|
||||||
@@ -163,7 +163,7 @@ const IssueList: React.FC = () => {
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
{data.results.length === 0 && (
|
{data.results.length === 0 && (
|
||||||
<div className="flex flex-col items-center justify-center w-full py-24 text-white">
|
<div className="flex w-full flex-col items-center justify-center py-24 text-white">
|
||||||
<span className="text-2xl text-gray-400">
|
<span className="text-2xl text-gray-400">
|
||||||
{intl.formatMessage(globalMessages.noresults)}
|
{intl.formatMessage(globalMessages.noresults)}
|
||||||
</span>
|
</span>
|
||||||
@@ -181,7 +181,7 @@ const IssueList: React.FC = () => {
|
|||||||
)}
|
)}
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<nav
|
<nav
|
||||||
className="flex flex-col items-center mb-3 space-y-3 sm:space-y-0 sm:flex-row"
|
className="mb-3 flex flex-col items-center space-y-3 sm:flex-row sm:space-y-0"
|
||||||
aria-label="Pagination"
|
aria-label="Pagination"
|
||||||
>
|
>
|
||||||
<div className="hidden lg:flex lg:flex-1">
|
<div className="hidden lg:flex lg:flex-1">
|
||||||
@@ -201,7 +201,7 @@ const IssueList: React.FC = () => {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-center sm:flex-1 sm:justify-start lg:justify-center">
|
<div className="flex justify-center sm:flex-1 sm:justify-start lg:justify-center">
|
||||||
<span className="items-center -mt-3 text-sm truncate sm:mt-0">
|
<span className="-mt-3 items-center truncate text-sm sm:mt-0">
|
||||||
{intl.formatMessage(globalMessages.resultsperpage, {
|
{intl.formatMessage(globalMessages.resultsperpage, {
|
||||||
pageSize: (
|
pageSize: (
|
||||||
<select
|
<select
|
||||||
@@ -219,7 +219,7 @@ const IssueList: React.FC = () => {
|
|||||||
.then(() => window.scrollTo(0, 0));
|
.then(() => window.scrollTo(0, 0));
|
||||||
}}
|
}}
|
||||||
value={currentPageSize}
|
value={currentPageSize}
|
||||||
className="inline short"
|
className="short inline"
|
||||||
>
|
>
|
||||||
<option value="5">5</option>
|
<option value="5">5</option>
|
||||||
<option value="10">10</option>
|
<option value="10">10</option>
|
||||||
@@ -231,7 +231,7 @@ const IssueList: React.FC = () => {
|
|||||||
})}
|
})}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-center flex-auto space-x-2 sm:justify-end sm:flex-1">
|
<div className="flex flex-auto justify-center space-x-2 sm:flex-1 sm:justify-end">
|
||||||
<Button
|
<Button
|
||||||
disabled={!hasPrevPage}
|
disabled={!hasPrevPage}
|
||||||
onClick={() => updateQueryParams('page', (page - 1).toString())}
|
onClick={() => updateQueryParams('page', (page - 1).toString())}
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ const CreateIssueModal: React.FC<CreateIssueModalProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{values.problemSeason > 0 && (
|
{values.problemSeason > 0 && (
|
||||||
<div className="mb-2 form-row">
|
<div className="form-row mb-2">
|
||||||
<label htmlFor="problemEpisode" className="text-label">
|
<label htmlFor="problemEpisode" className="text-label">
|
||||||
{intl.formatMessage(messages.problemepisode)}
|
{intl.formatMessage(messages.problemepisode)}
|
||||||
<span className="label-required">*</span>
|
<span className="label-required">*</span>
|
||||||
@@ -255,7 +255,7 @@ const CreateIssueModal: React.FC<CreateIssueModalProps> = ({
|
|||||||
<RadioGroup.Label className="sr-only">
|
<RadioGroup.Label className="sr-only">
|
||||||
Select an Issue
|
Select an Issue
|
||||||
</RadioGroup.Label>
|
</RadioGroup.Label>
|
||||||
<div className="-space-y-px overflow-hidden bg-gray-800 rounded-md bg-opacity-30">
|
<div className="-space-y-px overflow-hidden rounded-md bg-gray-800 bg-opacity-30">
|
||||||
{issueOptions.map((setting, index) => (
|
{issueOptions.map((setting, index) => (
|
||||||
<RadioGroup.Option
|
<RadioGroup.Option
|
||||||
key={`issue-type-${setting.issueType}`}
|
key={`issue-type-${setting.issueType}`}
|
||||||
@@ -267,9 +267,9 @@ const CreateIssueModal: React.FC<CreateIssueModalProps> = ({
|
|||||||
? 'rounded-bl-md rounded-br-md'
|
? 'rounded-bl-md rounded-br-md'
|
||||||
: '',
|
: '',
|
||||||
checked
|
checked
|
||||||
? 'bg-indigo-600 border-indigo-500 z-10'
|
? 'z-10 border-indigo-500 bg-indigo-600'
|
||||||
: 'border-gray-500',
|
: 'border-gray-500',
|
||||||
'relative border p-4 flex cursor-pointer focus:outline-none'
|
'relative flex cursor-pointer border p-4 focus:outline-none'
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@@ -278,16 +278,16 @@ const CreateIssueModal: React.FC<CreateIssueModalProps> = ({
|
|||||||
<span
|
<span
|
||||||
className={`${
|
className={`${
|
||||||
checked
|
checked
|
||||||
? 'bg-indigo-800 border-transparent'
|
? 'border-transparent bg-indigo-800'
|
||||||
: 'bg-white border-gray-300'
|
: 'border-gray-300 bg-white'
|
||||||
} ${
|
} ${
|
||||||
active ? 'ring-2 ring-offset-2 ring-indigo-300' : ''
|
active ? 'ring-2 ring-indigo-300 ring-offset-2' : ''
|
||||||
} h-4 w-4 mt-0.5 cursor-pointer rounded-full border flex items-center justify-center`}
|
} mt-0.5 flex h-4 w-4 cursor-pointer items-center justify-center rounded-full border`}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
>
|
>
|
||||||
<span className="rounded-full bg-white w-1.5 h-1.5" />
|
<span className="h-1.5 w-1.5 rounded-full bg-white" />
|
||||||
</span>
|
</span>
|
||||||
<div className="flex flex-col ml-3">
|
<div className="ml-3 flex flex-col">
|
||||||
<RadioGroup.Label
|
<RadioGroup.Label
|
||||||
as="span"
|
as="span"
|
||||||
className={`block text-sm font-medium ${
|
className={`block text-sm font-medium ${
|
||||||
@@ -303,7 +303,7 @@ const CreateIssueModal: React.FC<CreateIssueModalProps> = ({
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
<div className="flex-col mt-4 space-y-2">
|
<div className="mt-4 flex-col space-y-2">
|
||||||
<label htmlFor="message">
|
<label htmlFor="message">
|
||||||
{intl.formatMessage(messages.whatswrong)}
|
{intl.formatMessage(messages.whatswrong)}
|
||||||
<span className="label-required">*</span>
|
<span className="label-required">*</span>
|
||||||
|
|||||||
@@ -24,13 +24,13 @@ const LanguagePicker: React.FC = () => {
|
|||||||
<div className="relative">
|
<div className="relative">
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
className={`p-1 rounded-full sm:p-2 hover:bg-gray-600 hover:text-white focus:outline-none focus:bg-gray-600 focus:ring-1 focus:ring-gray-500 focus:text-white ${
|
className={`rounded-full p-1 hover:bg-gray-600 hover:text-white focus:bg-gray-600 focus:text-white focus:outline-none focus:ring-1 focus:ring-gray-500 sm:p-2 ${
|
||||||
isDropdownOpen ? 'bg-gray-600 text-white' : 'text-gray-400'
|
isDropdownOpen ? 'bg-gray-600 text-white' : 'text-gray-400'
|
||||||
}`}
|
}`}
|
||||||
aria-label="Language Picker"
|
aria-label="Language Picker"
|
||||||
onClick={() => setDropdownOpen(true)}
|
onClick={() => setDropdownOpen(true)}
|
||||||
>
|
>
|
||||||
<TranslateIcon className="w-6 h-6" />
|
<TranslateIcon className="h-6 w-6" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<Transition
|
<Transition
|
||||||
@@ -43,10 +43,10 @@ const LanguagePicker: React.FC = () => {
|
|||||||
leaveTo="transform opacity-0 scale-95"
|
leaveTo="transform opacity-0 scale-95"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="absolute right-0 w-56 mt-2 origin-top-right rounded-md shadow-lg"
|
className="absolute right-0 mt-2 w-56 origin-top-right rounded-md shadow-lg"
|
||||||
ref={dropdownRef}
|
ref={dropdownRef}
|
||||||
>
|
>
|
||||||
<div className="px-3 py-2 bg-gray-700 rounded-md ring-1 ring-black ring-opacity-5">
|
<div className="rounded-md bg-gray-700 px-3 py-2 ring-1 ring-black ring-opacity-5">
|
||||||
<div>
|
<div>
|
||||||
<label
|
<label
|
||||||
htmlFor="language"
|
htmlFor="language"
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import React from 'react';
|
|||||||
const Notifications: React.FC = () => {
|
const Notifications: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
className="p-1 text-gray-400 rounded-full hover:bg-gray-500 hover:text-white focus:outline-none focus:ring focus:text-white"
|
className="rounded-full p-1 text-gray-400 hover:bg-gray-500 hover:text-white focus:text-white focus:outline-none focus:ring"
|
||||||
aria-label="Notifications"
|
aria-label="Notifications"
|
||||||
>
|
>
|
||||||
<BellIcon className="w-6 h-6" />
|
<BellIcon className="h-6 w-6" />
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -17,14 +17,14 @@ const SearchInput: React.FC = () => {
|
|||||||
<label htmlFor="search_field" className="sr-only">
|
<label htmlFor="search_field" className="sr-only">
|
||||||
Search
|
Search
|
||||||
</label>
|
</label>
|
||||||
<div className="relative flex items-center w-full text-white focus-within:text-gray-200">
|
<div className="relative flex w-full items-center text-white focus-within:text-gray-200">
|
||||||
<div className="absolute inset-y-0 flex items-center pointer-events-none left-4">
|
<div className="pointer-events-none absolute inset-y-0 left-4 flex items-center">
|
||||||
<SearchIcon className="w-5 h-5" />
|
<SearchIcon className="h-5 w-5" />
|
||||||
</div>
|
</div>
|
||||||
<input
|
<input
|
||||||
id="search_field"
|
id="search_field"
|
||||||
style={{ paddingRight: searchValue.length > 0 ? '1.75rem' : '' }}
|
style={{ paddingRight: searchValue.length > 0 ? '1.75rem' : '' }}
|
||||||
className="block w-full py-2 pl-10 text-white placeholder-gray-300 bg-gray-900 border border-gray-600 rounded-full bg-opacity-80 focus:bg-opacity-100 focus:border-gray-500 hover:border-gray-500 focus:outline-none focus:ring-0 focus:placeholder-gray-400 sm:text-base"
|
className="block w-full rounded-full border border-gray-600 bg-gray-900 bg-opacity-80 py-2 pl-10 text-white placeholder-gray-300 hover:border-gray-500 focus:border-gray-500 focus:bg-opacity-100 focus:placeholder-gray-400 focus:outline-none focus:ring-0 sm:text-base"
|
||||||
placeholder={intl.formatMessage(messages.searchPlaceholder)}
|
placeholder={intl.formatMessage(messages.searchPlaceholder)}
|
||||||
type="search"
|
type="search"
|
||||||
value={searchValue}
|
value={searchValue}
|
||||||
@@ -44,10 +44,10 @@ const SearchInput: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
{searchValue.length > 0 && (
|
{searchValue.length > 0 && (
|
||||||
<button
|
<button
|
||||||
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 right-2 m-auto h-7 w-7 border-none p-1 text-gray-400 outline-none transition hover:text-white focus:border-none focus:outline-none"
|
||||||
onClick={() => clear()}
|
onClick={() => clear()}
|
||||||
>
|
>
|
||||||
<XCircleIcon className="w-5 h-5" />
|
<XCircleIcon className="h-5 w-5" />
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -42,20 +42,20 @@ const SidebarLinks: SidebarLinkProps[] = [
|
|||||||
{
|
{
|
||||||
href: '/',
|
href: '/',
|
||||||
messagesKey: 'dashboard',
|
messagesKey: 'dashboard',
|
||||||
svgIcon: <SparklesIcon className="w-6 h-6 mr-3" />,
|
svgIcon: <SparklesIcon className="mr-3 h-6 w-6" />,
|
||||||
activeRegExp: /^\/(discover\/?(movies|tv)?)?$/,
|
activeRegExp: /^\/(discover\/?(movies|tv)?)?$/,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
href: '/requests',
|
href: '/requests',
|
||||||
messagesKey: 'requests',
|
messagesKey: 'requests',
|
||||||
svgIcon: <ClockIcon className="w-6 h-6 mr-3" />,
|
svgIcon: <ClockIcon className="mr-3 h-6 w-6" />,
|
||||||
activeRegExp: /^\/requests/,
|
activeRegExp: /^\/requests/,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
href: '/issues',
|
href: '/issues',
|
||||||
messagesKey: 'issues',
|
messagesKey: 'issues',
|
||||||
svgIcon: (
|
svgIcon: (
|
||||||
<ExclamationIcon className="w-6 h-6 mr-3 text-gray-300 transition duration-150 ease-in-out group-hover:text-gray-100 group-focus:text-gray-300" />
|
<ExclamationIcon className="mr-3 h-6 w-6 text-gray-300 transition duration-150 ease-in-out group-hover:text-gray-100 group-focus:text-gray-300" />
|
||||||
),
|
),
|
||||||
activeRegExp: /^\/issues/,
|
activeRegExp: /^\/issues/,
|
||||||
requiredPermission: [
|
requiredPermission: [
|
||||||
@@ -68,14 +68,14 @@ const SidebarLinks: SidebarLinkProps[] = [
|
|||||||
{
|
{
|
||||||
href: '/users',
|
href: '/users',
|
||||||
messagesKey: 'users',
|
messagesKey: 'users',
|
||||||
svgIcon: <UsersIcon className="w-6 h-6 mr-3" />,
|
svgIcon: <UsersIcon className="mr-3 h-6 w-6" />,
|
||||||
activeRegExp: /^\/users/,
|
activeRegExp: /^\/users/,
|
||||||
requiredPermission: Permission.MANAGE_USERS,
|
requiredPermission: Permission.MANAGE_USERS,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
href: '/settings',
|
href: '/settings',
|
||||||
messagesKey: 'settings',
|
messagesKey: 'settings',
|
||||||
svgIcon: <CogIcon className="w-6 h-6 mr-3" />,
|
svgIcon: <CogIcon className="mr-3 h-6 w-6" />,
|
||||||
activeRegExp: /^\/settings/,
|
activeRegExp: /^\/settings/,
|
||||||
requiredPermission: Permission.MANAGE_SETTINGS,
|
requiredPermission: Permission.MANAGE_SETTINGS,
|
||||||
},
|
},
|
||||||
@@ -114,28 +114,28 @@ const Sidebar: React.FC<SidebarProps> = ({ open, setClosed }) => {
|
|||||||
leaveTo="-translate-x-full"
|
leaveTo="-translate-x-full"
|
||||||
>
|
>
|
||||||
<>
|
<>
|
||||||
<div className="relative flex flex-col flex-1 w-full max-w-xs bg-gray-800 sidebar">
|
<div className="sidebar relative flex w-full max-w-xs flex-1 flex-col bg-gray-800">
|
||||||
<div className="absolute top-0 right-0 p-1 sidebar-close-button -mr-14">
|
<div className="sidebar-close-button absolute top-0 right-0 -mr-14 p-1">
|
||||||
<button
|
<button
|
||||||
className="flex items-center justify-center w-12 h-12 rounded-full focus:outline-none focus:bg-gray-600"
|
className="flex h-12 w-12 items-center justify-center rounded-full focus:bg-gray-600 focus:outline-none"
|
||||||
aria-label="Close sidebar"
|
aria-label="Close sidebar"
|
||||||
onClick={() => setClosed()}
|
onClick={() => setClosed()}
|
||||||
>
|
>
|
||||||
<XIcon className="w-6 h-6 text-white" />
|
<XIcon className="h-6 w-6 text-white" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
ref={navRef}
|
ref={navRef}
|
||||||
className="flex flex-col flex-1 h-0 pt-8 pb-8 overflow-y-auto sm:pb-4"
|
className="flex h-0 flex-1 flex-col overflow-y-auto pt-8 pb-8 sm:pb-4"
|
||||||
>
|
>
|
||||||
<div className="flex items-center flex-shrink-0 px-2">
|
<div className="flex flex-shrink-0 items-center px-2">
|
||||||
<span className="px-4 text-xl text-gray-50">
|
<span className="px-4 text-xl text-gray-50">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
<img src="/logo_full.svg" alt="Logo" />
|
<img src="/logo_full.svg" alt="Logo" />
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<nav className="flex-1 px-4 mt-16 space-y-4">
|
<nav className="mt-16 flex-1 space-y-4 px-4">
|
||||||
{SidebarLinks.filter((link) =>
|
{SidebarLinks.filter((link) =>
|
||||||
link.requiredPermission
|
link.requiredPermission
|
||||||
? hasPermission(link.requiredPermission, {
|
? hasPermission(link.requiredPermission, {
|
||||||
@@ -158,7 +158,7 @@ const Sidebar: React.FC<SidebarProps> = ({ open, setClosed }) => {
|
|||||||
}}
|
}}
|
||||||
role="button"
|
role="button"
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
className={`flex items-center px-2 py-2 text-base leading-6 font-medium rounded-md text-white focus:outline-none transition ease-in-out duration-150
|
className={`flex items-center rounded-md px-2 py-2 text-base font-medium leading-6 text-white transition duration-150 ease-in-out focus:outline-none
|
||||||
${
|
${
|
||||||
router.pathname.match(
|
router.pathname.match(
|
||||||
sidebarLink.activeRegExp
|
sidebarLink.activeRegExp
|
||||||
@@ -184,7 +184,7 @@ const Sidebar: React.FC<SidebarProps> = ({ open, setClosed }) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-shrink-0 w-14">
|
<div className="w-14 flex-shrink-0">
|
||||||
{/* <!-- Force sidebar to shrink to fit close icon --> */}
|
{/* <!-- Force sidebar to shrink to fit close icon --> */}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
@@ -194,17 +194,17 @@ const Sidebar: React.FC<SidebarProps> = ({ open, setClosed }) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="fixed top-0 bottom-0 left-0 z-30 hidden lg:flex lg:flex-shrink-0">
|
<div className="fixed top-0 bottom-0 left-0 z-30 hidden lg:flex lg:flex-shrink-0">
|
||||||
<div className="flex flex-col w-64 sidebar">
|
<div className="sidebar flex w-64 flex-col">
|
||||||
<div className="flex flex-col flex-1 h-0">
|
<div className="flex h-0 flex-1 flex-col">
|
||||||
<div className="flex flex-col flex-1 pt-8 pb-4 overflow-y-auto">
|
<div className="flex flex-1 flex-col overflow-y-auto pt-8 pb-4">
|
||||||
<div className="flex items-center flex-shrink-0">
|
<div className="flex flex-shrink-0 items-center">
|
||||||
<span className="px-4 text-2xl text-gray-50">
|
<span className="px-4 text-2xl text-gray-50">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
<img src="/logo_full.svg" alt="Logo" />
|
<img src="/logo_full.svg" alt="Logo" />
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<nav className="flex-1 px-4 mt-16 space-y-4">
|
<nav className="mt-16 flex-1 space-y-4 px-4">
|
||||||
{SidebarLinks.filter((link) =>
|
{SidebarLinks.filter((link) =>
|
||||||
link.requiredPermission
|
link.requiredPermission
|
||||||
? hasPermission(link.requiredPermission, {
|
? hasPermission(link.requiredPermission, {
|
||||||
@@ -219,7 +219,7 @@ const Sidebar: React.FC<SidebarProps> = ({ open, setClosed }) => {
|
|||||||
as={sidebarLink.as}
|
as={sidebarLink.as}
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
className={`flex group items-center px-2 py-2 text-lg leading-6 font-medium rounded-md text-white focus:outline-none transition ease-in-out duration-150
|
className={`group flex items-center rounded-md px-2 py-2 text-lg font-medium leading-6 text-white transition duration-150 ease-in-out focus:outline-none
|
||||||
${
|
${
|
||||||
router.pathname.match(
|
router.pathname.match(
|
||||||
sidebarLink.activeRegExp
|
sidebarLink.activeRegExp
|
||||||
|
|||||||
@@ -33,14 +33,14 @@ const UserDropdown: React.FC = () => {
|
|||||||
<div className="relative ml-3">
|
<div className="relative ml-3">
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
className="flex items-center max-w-xs text-sm rounded-full ring-1 ring-gray-700 focus:outline-none focus:ring-gray-500 hover:ring-gray-500"
|
className="flex max-w-xs items-center rounded-full text-sm ring-1 ring-gray-700 hover:ring-gray-500 focus:outline-none focus:ring-gray-500"
|
||||||
id="user-menu"
|
id="user-menu"
|
||||||
aria-label="User menu"
|
aria-label="User menu"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
onClick={() => setDropdownOpen(true)}
|
onClick={() => setDropdownOpen(true)}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
className="w-8 h-8 rounded-full sm:w-10 sm:h-10"
|
className="h-8 w-8 rounded-full sm:h-10 sm:w-10"
|
||||||
src={user?.avatar}
|
src={user?.avatar}
|
||||||
alt=""
|
alt=""
|
||||||
/>
|
/>
|
||||||
@@ -56,11 +56,11 @@ const UserDropdown: React.FC = () => {
|
|||||||
leaveTo="transform opacity-0 scale-95"
|
leaveTo="transform opacity-0 scale-95"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="absolute right-0 w-48 mt-2 origin-top-right rounded-md shadow-lg"
|
className="absolute right-0 mt-2 w-48 origin-top-right rounded-md shadow-lg"
|
||||||
ref={dropdownRef}
|
ref={dropdownRef}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="py-1 bg-gray-700 rounded-md ring-1 ring-black ring-opacity-5"
|
className="rounded-md bg-gray-700 py-1 ring-1 ring-black ring-opacity-5"
|
||||||
role="menu"
|
role="menu"
|
||||||
aria-orientation="vertical"
|
aria-orientation="vertical"
|
||||||
aria-labelledby="user-menu"
|
aria-labelledby="user-menu"
|
||||||
@@ -77,7 +77,7 @@ const UserDropdown: React.FC = () => {
|
|||||||
}}
|
}}
|
||||||
onClick={() => setDropdownOpen(false)}
|
onClick={() => setDropdownOpen(false)}
|
||||||
>
|
>
|
||||||
<UserIcon className="inline w-5 h-5 mr-2" />
|
<UserIcon className="mr-2 inline h-5 w-5" />
|
||||||
<span>{intl.formatMessage(messages.myprofile)}</span>
|
<span>{intl.formatMessage(messages.myprofile)}</span>
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
@@ -93,7 +93,7 @@ const UserDropdown: React.FC = () => {
|
|||||||
}}
|
}}
|
||||||
onClick={() => setDropdownOpen(false)}
|
onClick={() => setDropdownOpen(false)}
|
||||||
>
|
>
|
||||||
<CogIcon className="inline w-5 h-5 mr-2" />
|
<CogIcon className="mr-2 inline h-5 w-5" />
|
||||||
<span>{intl.formatMessage(messages.settings)}</span>
|
<span>{intl.formatMessage(messages.settings)}</span>
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
@@ -103,7 +103,7 @@ const UserDropdown: React.FC = () => {
|
|||||||
role="menuitem"
|
role="menuitem"
|
||||||
onClick={() => logout()}
|
onClick={() => logout()}
|
||||||
>
|
>
|
||||||
<LogoutIcon className="inline w-5 h-5 mr-2" />
|
<LogoutIcon className="mr-2 inline h-5 w-5" />
|
||||||
<span>{intl.formatMessage(messages.signout)}</span>
|
<span>{intl.formatMessage(messages.signout)}</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -50,20 +50,20 @@ const VersionStatus: React.FC<VersionStatusProps> = ({ onClick }) => {
|
|||||||
}}
|
}}
|
||||||
role="button"
|
role="button"
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
className={`flex items-center p-2 mx-2 text-xs transition duration-300 rounded-lg ring-1 ring-gray-700 ${
|
className={`mx-2 flex items-center rounded-lg p-2 text-xs ring-1 ring-gray-700 transition duration-300 ${
|
||||||
data.updateAvailable
|
data.updateAvailable
|
||||||
? 'bg-yellow-500 text-white hover:bg-yellow-400'
|
? 'bg-yellow-500 text-white hover:bg-yellow-400'
|
||||||
: 'bg-gray-900 text-gray-300 hover:bg-gray-800'
|
: 'bg-gray-900 text-gray-300 hover:bg-gray-800'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{data.commitTag === 'local' ? (
|
{data.commitTag === 'local' ? (
|
||||||
<CodeIcon className="w-6 h-6" />
|
<CodeIcon className="h-6 w-6" />
|
||||||
) : data.version.startsWith('develop-') ? (
|
) : data.version.startsWith('develop-') ? (
|
||||||
<BeakerIcon className="w-6 h-6" />
|
<BeakerIcon className="h-6 w-6" />
|
||||||
) : (
|
) : (
|
||||||
<ServerIcon className="w-6 h-6" />
|
<ServerIcon className="h-6 w-6" />
|
||||||
)}
|
)}
|
||||||
<div className="flex flex-col flex-1 min-w-0 px-2 truncate last:pr-0">
|
<div className="flex min-w-0 flex-1 flex-col truncate px-2 last:pr-0">
|
||||||
<span className="font-bold">{versionStream}</span>
|
<span className="font-bold">{versionStream}</span>
|
||||||
<span className="truncate">
|
<span className="truncate">
|
||||||
{data.commitTag === 'local' ? (
|
{data.commitTag === 'local' ? (
|
||||||
@@ -75,13 +75,13 @@ const VersionStatus: React.FC<VersionStatusProps> = ({ onClick }) => {
|
|||||||
) : data.commitsBehind === -1 ? (
|
) : data.commitsBehind === -1 ? (
|
||||||
intl.formatMessage(messages.outofdate)
|
intl.formatMessage(messages.outofdate)
|
||||||
) : (
|
) : (
|
||||||
<code className="p-0 bg-transparent">
|
<code className="bg-transparent p-0">
|
||||||
{data.version.replace('develop-', '')}
|
{data.version.replace('develop-', '')}
|
||||||
</code>
|
</code>
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{data.updateAvailable && <ArrowCircleUpIcon className="w-6 h-6" />}
|
{data.updateAvailable && <ArrowCircleUpIcon className="h-6 w-6" />}
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -45,14 +45,14 @@ const Layout: React.FC = ({ children }) => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-full min-w-0 min-h-full bg-gray-900">
|
<div className="flex h-full min-h-full min-w-0 bg-gray-900">
|
||||||
<div className="fixed inset-0 z-20 w-full h-1 border-gray-700 md:border-t pwa-only" />
|
<div className="pwa-only fixed inset-0 z-20 h-1 w-full border-gray-700 md:border-t" />
|
||||||
<div className="absolute top-0 w-full h-64 from-gray-800 to-gray-900 bg-gradient-to-bl">
|
<div className="absolute top-0 h-64 w-full bg-gradient-to-bl from-gray-800 to-gray-900">
|
||||||
<div className="relative inset-0 w-full h-full from-gray-900 to-transparent bg-gradient-to-t" />
|
<div className="relative inset-0 h-full w-full bg-gradient-to-t from-gray-900 to-transparent" />
|
||||||
</div>
|
</div>
|
||||||
<Sidebar open={isSidebarOpen} setClosed={() => setSidebarOpen(false)} />
|
<Sidebar open={isSidebarOpen} setClosed={() => setSidebarOpen(false)} />
|
||||||
|
|
||||||
<div className="relative flex flex-col flex-1 w-0 min-w-0 mb-16 lg:ml-64">
|
<div className="relative mb-16 flex w-0 min-w-0 flex-1 flex-col lg:ml-64">
|
||||||
<div
|
<div
|
||||||
className={`searchbar fixed left-0 right-0 top-0 z-10 flex flex-shrink-0 bg-opacity-80 transition duration-300 ${
|
className={`searchbar fixed left-0 right-0 top-0 z-10 flex flex-shrink-0 bg-opacity-80 transition duration-300 ${
|
||||||
isScrolled ? 'bg-gray-700' : 'bg-transparent'
|
isScrolled ? 'bg-gray-700' : 'bg-transparent'
|
||||||
@@ -65,17 +65,17 @@ const Layout: React.FC = ({ children }) => {
|
|||||||
<button
|
<button
|
||||||
className={`px-4 text-white ${
|
className={`px-4 text-white ${
|
||||||
isScrolled ? 'opacity-90' : 'opacity-70'
|
isScrolled ? 'opacity-90' : 'opacity-70'
|
||||||
} focus:outline-none lg:hidden transition duration-300`}
|
} transition duration-300 focus:outline-none lg:hidden`}
|
||||||
aria-label="Open sidebar"
|
aria-label="Open sidebar"
|
||||||
onClick={() => setSidebarOpen(true)}
|
onClick={() => setSidebarOpen(true)}
|
||||||
>
|
>
|
||||||
<MenuAlt2Icon className="w-6 h-6" />
|
<MenuAlt2Icon className="h-6 w-6" />
|
||||||
</button>
|
</button>
|
||||||
<div className="flex items-center justify-between flex-1 pr-4 md:pr-4 md:pl-4">
|
<div className="flex flex-1 items-center justify-between pr-4 md:pr-4 md:pl-4">
|
||||||
<button
|
<button
|
||||||
className={`mr-2 text-white ${
|
className={`mr-2 text-white ${
|
||||||
isScrolled ? 'opacity-90' : 'opacity-70'
|
isScrolled ? 'opacity-90' : 'opacity-70'
|
||||||
} transition duration-300 hover:text-white pwa-only focus:outline-none focus:text-white`}
|
} pwa-only transition duration-300 hover:text-white focus:text-white focus:outline-none`}
|
||||||
onClick={() => router.back()}
|
onClick={() => router.back()}
|
||||||
>
|
>
|
||||||
<ArrowLeftIcon className="w-7" />
|
<ArrowLeftIcon className="w-7" />
|
||||||
@@ -87,9 +87,9 @@ const Layout: React.FC = ({ children }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<main className="relative z-0 top-16 focus:outline-none" tabIndex={0}>
|
<main className="relative top-16 z-0 focus:outline-none" tabIndex={0}>
|
||||||
<div className="mb-6">
|
<div className="mb-6">
|
||||||
<div className="px-4 mx-auto max-w-8xl">{children}</div>
|
<div className="max-w-8xl mx-auto px-4">{children}</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,12 +11,12 @@ interface BarProps {
|
|||||||
const Bar = ({ progress, isFinished }: BarProps) => {
|
const Bar = ({ progress, isFinished }: BarProps) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`fixed top-0 left-0 z-50 w-full transition-opacity ease-out duration-400 ${
|
className={`duration-400 fixed top-0 left-0 z-50 w-full transition-opacity ease-out ${
|
||||||
isFinished ? 'opacity-0' : 'opacity-100'
|
isFinished ? 'opacity-0' : 'opacity-100'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="duration-300 bg-indigo-400 transition-width"
|
className="bg-indigo-400 transition-width duration-300"
|
||||||
style={{
|
style={{
|
||||||
height: '3px',
|
height: '3px',
|
||||||
width: `${progress * 100}%`,
|
width: `${progress * 100}%`,
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ const LocalLogin: React.FC<LocalLoginProps> = ({ revalidate }) => {
|
|||||||
<label htmlFor="email" className="text-label">
|
<label htmlFor="email" className="text-label">
|
||||||
{intl.formatMessage(messages.email)}
|
{intl.formatMessage(messages.email)}
|
||||||
</label>
|
</label>
|
||||||
<div className="mt-1 mb-2 sm:mt-0 sm:col-span-2">
|
<div className="mt-1 mb-2 sm:col-span-2 sm:mt-0">
|
||||||
<div className="form-input-field">
|
<div className="form-input-field">
|
||||||
<Field
|
<Field
|
||||||
id="email"
|
id="email"
|
||||||
@@ -86,7 +86,7 @@ const LocalLogin: React.FC<LocalLoginProps> = ({ revalidate }) => {
|
|||||||
<label htmlFor="password" className="text-label">
|
<label htmlFor="password" className="text-label">
|
||||||
{intl.formatMessage(messages.password)}
|
{intl.formatMessage(messages.password)}
|
||||||
</label>
|
</label>
|
||||||
<div className="mt-1 mb-2 sm:mt-0 sm:col-span-2">
|
<div className="mt-1 mb-2 sm:col-span-2 sm:mt-0">
|
||||||
<div className="form-input-field">
|
<div className="form-input-field">
|
||||||
<SensitiveInput
|
<SensitiveInput
|
||||||
as="field"
|
as="field"
|
||||||
@@ -101,12 +101,12 @@ const LocalLogin: React.FC<LocalLoginProps> = ({ revalidate }) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{loginError && (
|
{loginError && (
|
||||||
<div className="mt-1 mb-2 sm:mt-0 sm:col-span-2">
|
<div className="mt-1 mb-2 sm:col-span-2 sm:mt-0">
|
||||||
<div className="error">{loginError}</div>
|
<div className="error">{loginError}</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="pt-5 mt-8 border-t border-gray-700">
|
<div className="mt-8 border-t border-gray-700 pt-5">
|
||||||
<div className="flex flex-row-reverse justify-between">
|
<div className="flex flex-row-reverse justify-between">
|
||||||
<span className="inline-flex rounded-md shadow-sm">
|
<span className="inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ const Login: React.FC = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative flex flex-col min-h-screen bg-gray-900 py-14">
|
<div className="relative flex min-h-screen flex-col bg-gray-900 py-14">
|
||||||
<PageTitle title={intl.formatMessage(messages.signin)} />
|
<PageTitle title={intl.formatMessage(messages.signin)} />
|
||||||
<ImageFader
|
<ImageFader
|
||||||
backgroundImages={
|
backgroundImages={
|
||||||
@@ -77,12 +77,12 @@ const Login: React.FC = () => {
|
|||||||
) ?? []
|
) ?? []
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<div className="absolute z-50 top-4 right-4">
|
<div className="absolute top-4 right-4 z-50">
|
||||||
<LanguagePicker />
|
<LanguagePicker />
|
||||||
</div>
|
</div>
|
||||||
<div className="relative z-40 flex flex-col items-center px-4 mt-10 sm:mx-auto sm:w-full sm:max-w-md">
|
<div className="relative z-40 mt-10 flex flex-col items-center px-4 sm:mx-auto sm:w-full sm:max-w-md">
|
||||||
<img src="/logo_stacked.svg" className="max-w-full mb-10" alt="Logo" />
|
<img src="/logo_stacked.svg" className="mb-10 max-w-full" alt="Logo" />
|
||||||
<h2 className="mt-2 text-3xl font-extrabold leading-9 text-center text-gray-100">
|
<h2 className="mt-2 text-center text-3xl font-extrabold leading-9 text-gray-100">
|
||||||
{intl.formatMessage(messages.signinheader)}
|
{intl.formatMessage(messages.signinheader)}
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
@@ -101,10 +101,10 @@ const Login: React.FC = () => {
|
|||||||
leaveFrom="opacity-100"
|
leaveFrom="opacity-100"
|
||||||
leaveTo="opacity-0"
|
leaveTo="opacity-0"
|
||||||
>
|
>
|
||||||
<div className="p-4 mb-4 bg-red-600 rounded-md">
|
<div className="mb-4 rounded-md bg-red-600 p-4">
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
<div className="flex-shrink-0">
|
<div className="flex-shrink-0">
|
||||||
<XCircleIcon className="w-5 h-5 text-red-300" />
|
<XCircleIcon className="h-5 w-5 text-red-300" />
|
||||||
</div>
|
</div>
|
||||||
<div className="ml-3">
|
<div className="ml-3">
|
||||||
<h3 className="text-sm font-medium text-red-300">
|
<h3 className="text-sm font-medium text-red-300">
|
||||||
@@ -118,11 +118,11 @@ const Login: React.FC = () => {
|
|||||||
{({ openIndexes, handleClick, AccordionContent }) => (
|
{({ openIndexes, handleClick, AccordionContent }) => (
|
||||||
<>
|
<>
|
||||||
<button
|
<button
|
||||||
className={`font-bold w-full py-2 text-sm text-center text-gray-400 transition-colors duration-200 bg-gray-800 cursor-default focus:outline-none bg-opacity-70 sm:rounded-t-lg ${
|
className={`w-full cursor-default bg-gray-800 bg-opacity-70 py-2 text-center text-sm font-bold text-gray-400 transition-colors duration-200 focus:outline-none sm:rounded-t-lg ${
|
||||||
openIndexes.includes(0) && 'text-indigo-500'
|
openIndexes.includes(0) && 'text-indigo-500'
|
||||||
} ${
|
} ${
|
||||||
settings.currentSettings.localLogin &&
|
settings.currentSettings.localLogin &&
|
||||||
'hover:bg-gray-700 hover:cursor-pointer'
|
'hover:cursor-pointer hover:bg-gray-700'
|
||||||
}`}
|
}`}
|
||||||
onClick={() => handleClick(0)}
|
onClick={() => handleClick(0)}
|
||||||
disabled={!settings.currentSettings.localLogin}
|
disabled={!settings.currentSettings.localLogin}
|
||||||
@@ -140,7 +140,7 @@ const Login: React.FC = () => {
|
|||||||
{settings.currentSettings.localLogin && (
|
{settings.currentSettings.localLogin && (
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
className={`font-bold w-full py-2 text-sm text-center text-gray-400 transition-colors duration-200 bg-gray-800 cursor-default focus:outline-none bg-opacity-70 hover:bg-gray-700 hover:cursor-pointer ${
|
className={`w-full cursor-default bg-gray-800 bg-opacity-70 py-2 text-center text-sm font-bold text-gray-400 transition-colors duration-200 hover:cursor-pointer hover:bg-gray-700 focus:outline-none ${
|
||||||
openIndexes.includes(1)
|
openIndexes.includes(1)
|
||||||
? 'text-indigo-500'
|
? 'text-indigo-500'
|
||||||
: 'sm:rounded-b-lg'
|
: 'sm:rounded-b-lg'
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ const ManageSlideOver: React.FC<
|
|||||||
<h3 className="mb-2 text-xl font-bold">
|
<h3 className="mb-2 text-xl font-bold">
|
||||||
{intl.formatMessage(messages.downloadstatus)}
|
{intl.formatMessage(messages.downloadstatus)}
|
||||||
</h3>
|
</h3>
|
||||||
<div className="overflow-hidden bg-gray-600 rounded-md shadow">
|
<div className="overflow-hidden rounded-md bg-gray-600 shadow">
|
||||||
<ul>
|
<ul>
|
||||||
{data.mediaInfo?.downloadStatus?.map((status, index) => (
|
{data.mediaInfo?.downloadStatus?.map((status, index) => (
|
||||||
<li
|
<li
|
||||||
@@ -171,7 +171,7 @@ const ManageSlideOver: React.FC<
|
|||||||
<h3 className="mb-2 text-xl font-bold">
|
<h3 className="mb-2 text-xl font-bold">
|
||||||
{intl.formatMessage(messages.manageModalIssues)}
|
{intl.formatMessage(messages.manageModalIssues)}
|
||||||
</h3>
|
</h3>
|
||||||
<div className="overflow-hidden bg-gray-600 rounded-md shadow">
|
<div className="overflow-hidden rounded-md bg-gray-600 shadow">
|
||||||
<ul>
|
<ul>
|
||||||
{openIssues.map((issue) => (
|
{openIssues.map((issue) => (
|
||||||
<li
|
<li
|
||||||
@@ -190,7 +190,7 @@ const ManageSlideOver: React.FC<
|
|||||||
<h3 className="mb-2 text-xl font-bold">
|
<h3 className="mb-2 text-xl font-bold">
|
||||||
{intl.formatMessage(messages.manageModalRequests)}
|
{intl.formatMessage(messages.manageModalRequests)}
|
||||||
</h3>
|
</h3>
|
||||||
<div className="overflow-hidden bg-gray-600 rounded-md shadow">
|
<div className="overflow-hidden rounded-md bg-gray-600 shadow">
|
||||||
<ul>
|
<ul>
|
||||||
{requests.map((request) => (
|
{requests.map((request) => (
|
||||||
<li
|
<li
|
||||||
@@ -219,7 +219,7 @@ const ManageSlideOver: React.FC<
|
|||||||
{!!watchData?.data && (
|
{!!watchData?.data && (
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
className={`grid grid-cols-1 divide-y divide-gray-500 overflow-hidden text-sm text-gray-300 bg-gray-600 shadow ${
|
className={`grid grid-cols-1 divide-y divide-gray-500 overflow-hidden bg-gray-600 text-sm text-gray-300 shadow ${
|
||||||
data.mediaInfo?.tautulliUrl
|
data.mediaInfo?.tautulliUrl
|
||||||
? 'rounded-t-md'
|
? 'rounded-t-md'
|
||||||
: 'rounded-md'
|
: 'rounded-md'
|
||||||
@@ -254,8 +254,8 @@ const ManageSlideOver: React.FC<
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{!!watchData.data.users.length && (
|
{!!watchData.data.users.length && (
|
||||||
<div className="flex flex-row px-4 pt-3 pb-2 space-x-2">
|
<div className="flex flex-row space-x-2 px-4 pt-3 pb-2">
|
||||||
<span className="font-bold leading-8 shrink-0">
|
<span className="shrink-0 font-bold leading-8">
|
||||||
{intl.formatMessage(messages.playedby)}
|
{intl.formatMessage(messages.playedby)}
|
||||||
</span>
|
</span>
|
||||||
<span className="flex flex-row flex-wrap">
|
<span className="flex flex-row flex-wrap">
|
||||||
@@ -268,11 +268,11 @@ const ManageSlideOver: React.FC<
|
|||||||
}
|
}
|
||||||
key={`watch-user-${user.id}`}
|
key={`watch-user-${user.id}`}
|
||||||
>
|
>
|
||||||
<a className="z-0 mb-1 -mr-2 hover:z-50 shrink-0">
|
<a className="z-0 mb-1 -mr-2 shrink-0 hover:z-50">
|
||||||
<img
|
<img
|
||||||
src={user.avatar}
|
src={user.avatar}
|
||||||
alt={user.displayName}
|
alt={user.displayName}
|
||||||
className="w-8 h-8 transition duration-300 scale-100 rounded-full ring-1 ring-gray-500 transform-gpu hover:scale-105"
|
className="h-8 w-8 scale-100 transform-gpu rounded-full ring-1 ring-gray-500 transition duration-300 hover:scale-105"
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
@@ -334,7 +334,7 @@ const ManageSlideOver: React.FC<
|
|||||||
{!!watchData?.data4k && (
|
{!!watchData?.data4k && (
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
className={`grid grid-cols-1 divide-y divide-gray-500 overflow-hidden text-sm text-gray-300 bg-gray-600 shadow ${
|
className={`grid grid-cols-1 divide-y divide-gray-500 overflow-hidden bg-gray-600 text-sm text-gray-300 shadow ${
|
||||||
data.mediaInfo?.tautulliUrl4k
|
data.mediaInfo?.tautulliUrl4k
|
||||||
? 'rounded-t-md'
|
? 'rounded-t-md'
|
||||||
: 'rounded-md'
|
: 'rounded-md'
|
||||||
@@ -369,8 +369,8 @@ const ManageSlideOver: React.FC<
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{!!watchData.data4k.users.length && (
|
{!!watchData.data4k.users.length && (
|
||||||
<div className="flex flex-row px-4 pt-3 pb-2 space-x-2">
|
<div className="flex flex-row space-x-2 px-4 pt-3 pb-2">
|
||||||
<span className="font-bold leading-8 shrink-0">
|
<span className="shrink-0 font-bold leading-8">
|
||||||
{intl.formatMessage(messages.playedby)}
|
{intl.formatMessage(messages.playedby)}
|
||||||
</span>
|
</span>
|
||||||
<span className="flex flex-row flex-wrap">
|
<span className="flex flex-row flex-wrap">
|
||||||
@@ -383,11 +383,11 @@ const ManageSlideOver: React.FC<
|
|||||||
}
|
}
|
||||||
key={`watch-user-${user.id}`}
|
key={`watch-user-${user.id}`}
|
||||||
>
|
>
|
||||||
<a className="z-0 mb-1 -mr-2 hover:z-50 shrink-0">
|
<a className="z-0 mb-1 -mr-2 shrink-0 hover:z-50">
|
||||||
<img
|
<img
|
||||||
src={user.avatar}
|
src={user.avatar}
|
||||||
alt={user.displayName}
|
alt={user.displayName}
|
||||||
className="w-8 h-8 transition duration-300 scale-100 rounded-full ring-1 ring-gray-500 transform-gpu hover:scale-105"
|
className="h-8 w-8 scale-100 transform-gpu rounded-full ring-1 ring-gray-500 transition duration-300 hover:scale-105"
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -32,16 +32,16 @@ const ShowMoreCard: React.FC<ShowMoreCardProps> = ({ url, posters }) => {
|
|||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={`relative w-36 sm:w-36 md:w-44
|
className={`relative w-36 transform-gpu cursor-pointer
|
||||||
rounded-xl text-white shadow-lg overflow-hidden transition ease-in-out duration-150 cursor-pointer transform-gpu ring-1 ${
|
overflow-hidden rounded-xl text-white shadow-lg ring-1 transition duration-150 ease-in-out sm:w-36 md:w-44 ${
|
||||||
isHovered
|
isHovered
|
||||||
? 'bg-gray-600 ring-gray-500 scale-105'
|
? 'scale-105 bg-gray-600 ring-gray-500'
|
||||||
: 'bg-gray-800 ring-gray-700 scale-100'
|
: 'scale-100 bg-gray-800 ring-gray-700'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div style={{ paddingBottom: '150%' }}>
|
<div style={{ paddingBottom: '150%' }}>
|
||||||
<div className="absolute inset-0 flex flex-col items-center w-full h-full p-2">
|
<div className="absolute inset-0 flex h-full w-full flex-col items-center p-2">
|
||||||
<div className="relative z-10 flex flex-wrap items-center justify-center h-full opacity-30">
|
<div className="relative z-10 flex h-full flex-wrap items-center justify-center opacity-30">
|
||||||
{posters[0] && (
|
{posters[0] && (
|
||||||
<div className="w-1/2 p-1">
|
<div className="w-1/2 p-1">
|
||||||
<img
|
<img
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
|||||||
const certification = releases?.find((r) => r.certification)?.certification;
|
const certification = releases?.find((r) => r.certification)?.certification;
|
||||||
if (certification) {
|
if (certification) {
|
||||||
movieAttributes.push(
|
movieAttributes.push(
|
||||||
<span className="p-0.5 py-0 border rounded-md">{certification}</span>
|
<span className="rounded-md border p-0.5 py-0">{certification}</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -372,8 +372,8 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
|||||||
) ?? []
|
) ?? []
|
||||||
).length > 0 && (
|
).length > 0 && (
|
||||||
<>
|
<>
|
||||||
<div className="absolute w-3 h-3 bg-red-600 rounded-full -right-1 -top-1" />
|
<div className="absolute -right-1 -top-1 h-3 w-3 rounded-full bg-red-600" />
|
||||||
<div className="absolute w-3 h-3 bg-red-600 rounded-full -right-1 -top-1 animate-ping" />
|
<div className="absolute -right-1 -top-1 h-3 w-3 animate-ping rounded-full bg-red-600" />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
@@ -401,11 +401,11 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
|||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
<div className="flex justify-end mt-4">
|
<div className="mt-4 flex justify-end">
|
||||||
<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.5" />
|
<ArrowCircleRightIcon className="ml-1.5 inline-block h-5 w-5" />
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
@@ -417,7 +417,7 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
|||||||
<div className="mb-6">
|
<div className="mb-6">
|
||||||
<Link href={`/collection/${data.collection.id}`}>
|
<Link href={`/collection/${data.collection.id}`}>
|
||||||
<a>
|
<a>
|
||||||
<div className="relative z-0 overflow-hidden transition duration-300 scale-100 bg-gray-800 bg-center bg-cover rounded-lg shadow-md cursor-pointer transform-gpu group hover:scale-105 ring-1 ring-gray-700 hover:ring-gray-500">
|
<div className="group relative z-0 scale-100 transform-gpu cursor-pointer overflow-hidden rounded-lg bg-gray-800 bg-cover bg-center shadow-md ring-1 ring-gray-700 transition duration-300 hover:scale-105 hover:ring-gray-500">
|
||||||
<div className="absolute inset-0 z-0">
|
<div className="absolute inset-0 z-0">
|
||||||
<CachedImage
|
<CachedImage
|
||||||
src={`https://image.tmdb.org/t/p/w1440_and_h320_multi_faces/${data.collection.backdropPath}`}
|
src={`https://image.tmdb.org/t/p/w1440_and_h320_multi_faces/${data.collection.backdropPath}`}
|
||||||
@@ -433,7 +433,7 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="relative z-10 flex items-center justify-between p-4 text-gray-200 transition duration-300 h-14 group-hover:text-white">
|
<div className="relative z-10 flex h-14 items-center justify-between p-4 text-gray-200 transition duration-300 group-hover:text-white">
|
||||||
<div>{data.collection.name}</div>
|
<div>{data.collection.name}</div>
|
||||||
<Button buttonSize="sm">
|
<Button buttonSize="sm">
|
||||||
{intl.formatMessage(globalMessages.view)}
|
{intl.formatMessage(globalMessages.view)}
|
||||||
@@ -453,9 +453,9 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
|||||||
<>
|
<>
|
||||||
<span className="media-rating">
|
<span className="media-rating">
|
||||||
{ratingData.criticsRating === 'Rotten' ? (
|
{ratingData.criticsRating === 'Rotten' ? (
|
||||||
<RTRotten className="w-6 mr-1" />
|
<RTRotten className="mr-1 w-6" />
|
||||||
) : (
|
) : (
|
||||||
<RTFresh className="w-6 mr-1" />
|
<RTFresh className="mr-1 w-6" />
|
||||||
)}
|
)}
|
||||||
{ratingData.criticsScore}%
|
{ratingData.criticsScore}%
|
||||||
</span>
|
</span>
|
||||||
@@ -465,9 +465,9 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
|||||||
<>
|
<>
|
||||||
<span className="media-rating">
|
<span className="media-rating">
|
||||||
{ratingData.audienceRating === 'Spilled' ? (
|
{ratingData.audienceRating === 'Spilled' ? (
|
||||||
<RTAudRotten className="w-6 mr-1" />
|
<RTAudRotten className="mr-1 w-6" />
|
||||||
) : (
|
) : (
|
||||||
<RTAudFresh className="w-6 mr-1" />
|
<RTAudFresh className="mr-1 w-6" />
|
||||||
)}
|
)}
|
||||||
{ratingData.audienceScore}%
|
{ratingData.audienceScore}%
|
||||||
</span>
|
</span>
|
||||||
@@ -476,7 +476,7 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
|||||||
{!!data.voteCount && (
|
{!!data.voteCount && (
|
||||||
<>
|
<>
|
||||||
<span className="media-rating">
|
<span className="media-rating">
|
||||||
<TmdbLogo className="w-6 mr-2" />
|
<TmdbLogo className="mr-2 w-6" />
|
||||||
{data.voteAverage}/10
|
{data.voteAverage}/10
|
||||||
</span>
|
</span>
|
||||||
</>
|
</>
|
||||||
@@ -509,14 +509,14 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
|||||||
>
|
>
|
||||||
{r.type === 3 ? (
|
{r.type === 3 ? (
|
||||||
// Theatrical
|
// Theatrical
|
||||||
<TicketIcon className="w-4 h-4" />
|
<TicketIcon className="h-4 w-4" />
|
||||||
) : r.type === 4 ? (
|
) : r.type === 4 ? (
|
||||||
// Digital
|
// Digital
|
||||||
<CloudIcon className="w-4 h-4" />
|
<CloudIcon className="h-4 w-4" />
|
||||||
) : (
|
) : (
|
||||||
// Physical
|
// Physical
|
||||||
<svg
|
<svg
|
||||||
className="w-4 h-4"
|
className="h-4 w-4"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
>
|
>
|
||||||
@@ -667,9 +667,9 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
|||||||
: messages.showless
|
: messages.showless
|
||||||
)}
|
)}
|
||||||
{!showMoreStudios ? (
|
{!showMoreStudios ? (
|
||||||
<ChevronDoubleDownIcon className="w-4 h-4 ml-1" />
|
<ChevronDoubleDownIcon className="ml-1 h-4 w-4" />
|
||||||
) : (
|
) : (
|
||||||
<ChevronDoubleUpIcon className="w-4 h-4 ml-1" />
|
<ChevronDoubleUpIcon className="ml-1 h-4 w-4" />
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -17,13 +17,13 @@ const NotificationType: React.FC<NotificationTypeProps> = ({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
className={`relative flex items-start first:mt-0 mt-4 ${
|
className={`relative mt-4 flex items-start first:mt-0 ${
|
||||||
!!parent?.value && hasNotificationType(parent.value, currentTypes)
|
!!parent?.value && hasNotificationType(parent.value, currentTypes)
|
||||||
? 'opacity-50'
|
? 'opacity-50'
|
||||||
: ''
|
: ''
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="flex items-center h-6">
|
<div className="flex h-6 items-center">
|
||||||
<input
|
<input
|
||||||
id={option.id}
|
id={option.id}
|
||||||
name="permissions"
|
name="permissions"
|
||||||
@@ -57,7 +57,7 @@ const NotificationType: React.FC<NotificationTypeProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{(option.children ?? []).map((child) => (
|
{(option.children ?? []).map((child) => (
|
||||||
<div key={`notification-type-child-${child.id}`} className="pl-6 mt-4">
|
<div key={`notification-type-child-${child.id}`} className="mt-4 pl-6">
|
||||||
<NotificationType
|
<NotificationType
|
||||||
option={child}
|
option={child}
|
||||||
currentTypes={currentTypes}
|
currentTypes={currentTypes}
|
||||||
|
|||||||
@@ -107,11 +107,11 @@ const PermissionOption: React.FC<PermissionOptionProps> = ({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
className={`relative flex items-start first:mt-0 mt-4 ${
|
className={`relative mt-4 flex items-start first:mt-0 ${
|
||||||
disabled ? 'opacity-50' : ''
|
disabled ? 'opacity-50' : ''
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="flex items-center h-6">
|
<div className="flex h-6 items-center">
|
||||||
<input
|
<input
|
||||||
id={option.id}
|
id={option.id}
|
||||||
name="permissions"
|
name="permissions"
|
||||||
@@ -139,7 +139,7 @@ const PermissionOption: React.FC<PermissionOptionProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{(option.children ?? []).map((child) => (
|
{(option.children ?? []).map((child) => (
|
||||||
<div key={`permission-child-${child.id}`} className="pl-10 mt-4">
|
<div key={`permission-child-${child.id}`} className="mt-4 pl-10">
|
||||||
<PermissionOption
|
<PermissionOption
|
||||||
option={child}
|
option={child}
|
||||||
currentPermission={currentPermission}
|
currentPermission={currentPermission}
|
||||||
|
|||||||
@@ -39,17 +39,17 @@ const PersonCard: React.FC<PersonCardProps> = ({
|
|||||||
<div
|
<div
|
||||||
className={`relative ${
|
className={`relative ${
|
||||||
canExpand ? 'w-full' : 'w-36 sm:w-36 md:w-44'
|
canExpand ? 'w-full' : 'w-36 sm:w-36 md:w-44'
|
||||||
} rounded-xl text-white shadow transition ease-in-out duration-150 cursor-pointer transform-gpu ring-1 ${
|
} transform-gpu cursor-pointer rounded-xl text-white shadow ring-1 transition duration-150 ease-in-out ${
|
||||||
isHovered
|
isHovered
|
||||||
? 'bg-gray-700 scale-105 ring-gray-500'
|
? 'scale-105 bg-gray-700 ring-gray-500'
|
||||||
: 'bg-gray-800 scale-100 ring-gray-700'
|
: 'scale-100 bg-gray-800 ring-gray-700'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div style={{ paddingBottom: '150%' }}>
|
<div style={{ paddingBottom: '150%' }}>
|
||||||
<div className="absolute inset-0 flex flex-col items-center w-full h-full p-2">
|
<div className="absolute inset-0 flex h-full w-full flex-col items-center p-2">
|
||||||
<div className="relative flex justify-center w-full mt-2 mb-4 h-1/2">
|
<div className="relative mt-2 mb-4 flex h-1/2 w-full justify-center">
|
||||||
{profilePath ? (
|
{profilePath ? (
|
||||||
<div className="relative w-3/4 h-full overflow-hidden rounded-full ring-1 ring-gray-700">
|
<div className="relative h-full w-3/4 overflow-hidden rounded-full ring-1 ring-gray-700">
|
||||||
<CachedImage
|
<CachedImage
|
||||||
src={`https://image.tmdb.org/t/p/w600_and_h900_bestv2${profilePath}`}
|
src={`https://image.tmdb.org/t/p/w600_and_h900_bestv2${profilePath}`}
|
||||||
alt=""
|
alt=""
|
||||||
@@ -61,12 +61,12 @@ const PersonCard: React.FC<PersonCardProps> = ({
|
|||||||
<UserCircleIcon className="h-full" />
|
<UserCircleIcon className="h-full" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full font-bold text-center truncate">
|
<div className="w-full truncate text-center font-bold">
|
||||||
{name}
|
{name}
|
||||||
</div>
|
</div>
|
||||||
{subName && (
|
{subName && (
|
||||||
<div
|
<div
|
||||||
className="overflow-hidden text-sm text-center text-gray-300 whitespace-normal"
|
className="overflow-hidden whitespace-normal text-center text-sm text-gray-300"
|
||||||
style={{
|
style={{
|
||||||
WebkitLineClamp: 2,
|
WebkitLineClamp: 2,
|
||||||
display: '-webkit-box',
|
display: '-webkit-box',
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ const PersonDetails: React.FC = () => {
|
|||||||
canExpand
|
canExpand
|
||||||
/>
|
/>
|
||||||
{media.character && (
|
{media.character && (
|
||||||
<div className="w-full mt-2 text-xs text-center text-gray-300 truncate">
|
<div className="mt-2 w-full truncate text-center text-xs text-gray-300">
|
||||||
{intl.formatMessage(messages.ascharacter, {
|
{intl.formatMessage(messages.ascharacter, {
|
||||||
character: media.character,
|
character: media.character,
|
||||||
})}
|
})}
|
||||||
@@ -185,7 +185,7 @@ const PersonDetails: React.FC = () => {
|
|||||||
canExpand
|
canExpand
|
||||||
/>
|
/>
|
||||||
{media.job && (
|
{media.job && (
|
||||||
<div className="w-full mt-2 text-xs text-center text-gray-300 truncate">
|
<div className="mt-2 w-full truncate text-center text-xs text-gray-300">
|
||||||
{media.job}
|
{media.job}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -214,12 +214,12 @@ const PersonDetails: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div
|
<div
|
||||||
className={`relative z-10 flex flex-col items-center mt-4 mb-8 lg:flex-row ${
|
className={`relative z-10 mt-4 mb-8 flex flex-col items-center lg:flex-row ${
|
||||||
data.biography ? 'lg:items-start' : ''
|
data.biography ? 'lg:items-start' : ''
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{data.profilePath && (
|
{data.profilePath && (
|
||||||
<div className="relative flex-shrink-0 mb-6 mr-0 overflow-hidden rounded-full w-36 h-36 lg:w-44 lg:h-44 lg:mb-0 lg:mr-6 ring-1 ring-gray-700">
|
<div className="relative mb-6 mr-0 h-36 w-36 flex-shrink-0 overflow-hidden rounded-full ring-1 ring-gray-700 lg:mb-0 lg:mr-6 lg:h-44 lg:w-44">
|
||||||
<CachedImage
|
<CachedImage
|
||||||
src={`https://image.tmdb.org/t/p/w600_and_h900_bestv2${data.profilePath}`}
|
src={`https://image.tmdb.org/t/p/w600_and_h900_bestv2${data.profilePath}`}
|
||||||
alt=""
|
alt=""
|
||||||
@@ -249,7 +249,7 @@ const PersonDetails: React.FC = () => {
|
|||||||
<div className="relative text-left">
|
<div className="relative text-left">
|
||||||
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */}
|
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */}
|
||||||
<div
|
<div
|
||||||
className="outline-none group ring-0"
|
className="group outline-none ring-0"
|
||||||
onClick={() => setShowBio((show) => !show)}
|
onClick={() => setShowBio((show) => !show)}
|
||||||
role="button"
|
role="button"
|
||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
@@ -257,7 +257,7 @@ const PersonDetails: React.FC = () => {
|
|||||||
<TruncateMarkup
|
<TruncateMarkup
|
||||||
lines={showBio ? 200 : 6}
|
lines={showBio ? 200 : 6}
|
||||||
ellipsis={
|
ellipsis={
|
||||||
<Ellipsis className="relative inline-block ml-2 -top-0.5 opacity-70 group-hover:opacity-100 transition duration-300" />
|
<Ellipsis className="relative -top-0.5 ml-2 inline-block opacity-70 transition duration-300 group-hover:opacity-100" />
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<p className="pt-2 text-sm lg:text-base">{data.biography}</p>
|
<p className="pt-2 text-sm lg:text-base">{data.biography}</p>
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ const QuotaSelector: React.FC<QuotaSelectorProps> = ({
|
|||||||
{
|
{
|
||||||
quotaLimit: (
|
quotaLimit: (
|
||||||
<select
|
<select
|
||||||
className="inline short"
|
className="short inline"
|
||||||
value={limitOverride ?? quotaLimit}
|
value={limitOverride ?? quotaLimit}
|
||||||
onChange={(e) => setQuotaLimit(Number(e.target.value))}
|
onChange={(e) => setQuotaLimit(Number(e.target.value))}
|
||||||
disabled={isDisabled}
|
disabled={isDisabled}
|
||||||
@@ -73,7 +73,7 @@ const QuotaSelector: React.FC<QuotaSelectorProps> = ({
|
|||||||
),
|
),
|
||||||
quotaDays: (
|
quotaDays: (
|
||||||
<select
|
<select
|
||||||
className="inline short"
|
className="short inline"
|
||||||
value={dayOverride ?? quotaDays}
|
value={dayOverride ?? quotaDays}
|
||||||
onChange={(e) => setQuotaDays(Number(e.target.value))}
|
onChange={(e) => setQuotaDays(Number(e.target.value))}
|
||||||
disabled={isDisabled}
|
disabled={isDisabled}
|
||||||
|
|||||||
@@ -81,13 +81,13 @@ const RegionSelector: React.FC<RegionSelectorProps> = ({
|
|||||||
{({ open }) => (
|
{({ open }) => (
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<span className="inline-block w-full rounded-md shadow-sm">
|
<span className="inline-block w-full rounded-md shadow-sm">
|
||||||
<Listbox.Button className="relative flex items-center w-full py-2 pl-3 pr-10 text-left text-white transition duration-150 ease-in-out bg-gray-700 border border-gray-500 rounded-md cursor-default focus:outline-none focus:shadow-outline-blue focus:border-blue-300 sm:text-sm sm:leading-5">
|
<Listbox.Button className="focus:shadow-outline-blue relative flex w-full cursor-default items-center rounded-md border border-gray-500 bg-gray-700 py-2 pl-3 pr-10 text-left text-white transition duration-150 ease-in-out focus:border-blue-300 focus:outline-none sm:text-sm sm:leading-5">
|
||||||
{((selectedRegion && hasFlag(selectedRegion?.iso_3166_1)) ||
|
{((selectedRegion && hasFlag(selectedRegion?.iso_3166_1)) ||
|
||||||
(isUserSetting &&
|
(isUserSetting &&
|
||||||
!selectedRegion &&
|
!selectedRegion &&
|
||||||
currentSettings.region &&
|
currentSettings.region &&
|
||||||
hasFlag(currentSettings.region))) && (
|
hasFlag(currentSettings.region))) && (
|
||||||
<span className="h-4 mr-2 overflow-hidden text-base leading-4">
|
<span className="mr-2 h-4 overflow-hidden text-base leading-4">
|
||||||
<span
|
<span
|
||||||
className={`flag:${
|
className={`flag:${
|
||||||
selectedRegion
|
selectedRegion
|
||||||
@@ -108,8 +108,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 text-gray-500 pointer-events-none">
|
<span className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2 text-gray-500">
|
||||||
<ChevronDownIcon className="w-5 h-5" />
|
<ChevronDownIcon className="h-5 w-5" />
|
||||||
</span>
|
</span>
|
||||||
</Listbox.Button>
|
</Listbox.Button>
|
||||||
</span>
|
</span>
|
||||||
@@ -119,19 +119,19 @@ const RegionSelector: React.FC<RegionSelectorProps> = ({
|
|||||||
leave="transition ease-in duration-100"
|
leave="transition ease-in duration-100"
|
||||||
leaveFrom="opacity-100"
|
leaveFrom="opacity-100"
|
||||||
leaveTo="opacity-0"
|
leaveTo="opacity-0"
|
||||||
className="absolute w-full mt-1 bg-gray-800 rounded-md shadow-lg"
|
className="absolute mt-1 w-full rounded-md bg-gray-800 shadow-lg"
|
||||||
>
|
>
|
||||||
<Listbox.Options
|
<Listbox.Options
|
||||||
static
|
static
|
||||||
className="py-1 overflow-auto text-base leading-6 rounded-md shadow-xs max-h-60 focus:outline-none sm:text-sm sm:leading-5"
|
className="shadow-xs max-h-60 overflow-auto rounded-md py-1 text-base leading-6 focus:outline-none sm:text-sm sm:leading-5"
|
||||||
>
|
>
|
||||||
{isUserSetting && (
|
{isUserSetting && (
|
||||||
<Listbox.Option value={null}>
|
<Listbox.Option value={null}>
|
||||||
{({ selected, active }) => (
|
{({ selected, active }) => (
|
||||||
<div
|
<div
|
||||||
className={`${
|
className={`${
|
||||||
active ? 'text-white bg-indigo-600' : 'text-gray-300'
|
active ? 'bg-indigo-600 text-white' : 'text-gray-300'
|
||||||
} cursor-default select-none relative py-2 pl-8 pr-4 flex items-center`}
|
} relative flex cursor-default select-none items-center py-2 pl-8 pr-4`}
|
||||||
>
|
>
|
||||||
<span className="mr-2 text-base">
|
<span className="mr-2 text-base">
|
||||||
<span
|
<span
|
||||||
@@ -159,7 +159,7 @@ const RegionSelector: React.FC<RegionSelectorProps> = ({
|
|||||||
active ? 'text-white' : 'text-indigo-600'
|
active ? 'text-white' : 'text-indigo-600'
|
||||||
} absolute inset-y-0 left-0 flex items-center pl-1.5`}
|
} absolute inset-y-0 left-0 flex items-center pl-1.5`}
|
||||||
>
|
>
|
||||||
<CheckIcon className="w-5 h-5" />
|
<CheckIcon className="h-5 w-5" />
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -170,8 +170,8 @@ const RegionSelector: React.FC<RegionSelectorProps> = ({
|
|||||||
{({ selected, active }) => (
|
{({ selected, active }) => (
|
||||||
<div
|
<div
|
||||||
className={`${
|
className={`${
|
||||||
active ? 'text-white bg-indigo-600' : 'text-gray-300'
|
active ? 'bg-indigo-600 text-white' : 'text-gray-300'
|
||||||
} cursor-default select-none relative py-2 pl-8 pr-4`}
|
} relative cursor-default select-none py-2 pl-8 pr-4`}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className={`${
|
className={`${
|
||||||
@@ -186,7 +186,7 @@ const RegionSelector: React.FC<RegionSelectorProps> = ({
|
|||||||
active ? 'text-white' : 'text-indigo-600'
|
active ? 'text-white' : 'text-indigo-600'
|
||||||
} absolute inset-y-0 left-0 flex items-center pl-1.5`}
|
} absolute inset-y-0 left-0 flex items-center pl-1.5`}
|
||||||
>
|
>
|
||||||
<CheckIcon className="w-5 h-5" />
|
<CheckIcon className="h-5 w-5" />
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -197,8 +197,8 @@ const RegionSelector: React.FC<RegionSelectorProps> = ({
|
|||||||
{({ selected, active }) => (
|
{({ selected, active }) => (
|
||||||
<div
|
<div
|
||||||
className={`${
|
className={`${
|
||||||
active ? 'text-white bg-indigo-600' : 'text-gray-300'
|
active ? 'bg-indigo-600 text-white' : 'text-gray-300'
|
||||||
} cursor-default select-none relative py-2 pl-8 pr-4 flex items-center`}
|
} relative flex cursor-default select-none items-center py-2 pl-8 pr-4`}
|
||||||
>
|
>
|
||||||
<span className="mr-2 text-base">
|
<span className="mr-2 text-base">
|
||||||
<span
|
<span
|
||||||
@@ -222,7 +222,7 @@ const RegionSelector: React.FC<RegionSelectorProps> = ({
|
|||||||
active ? 'text-white' : 'text-indigo-600'
|
active ? 'text-white' : 'text-indigo-600'
|
||||||
} absolute inset-y-0 left-0 flex items-center pl-1.5`}
|
} absolute inset-y-0 left-0 flex items-center pl-1.5`}
|
||||||
>
|
>
|
||||||
<CheckIcon className="w-5 h-5" />
|
<CheckIcon className="h-5 w-5" />
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -79,9 +79,9 @@ const RequestBlock: React.FC<RequestBlockProps> = ({ request, onUpdate }) => {
|
|||||||
/>
|
/>
|
||||||
<div className="px-4 py-3 text-gray-300">
|
<div className="px-4 py-3 text-gray-300">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex-col items-center flex-1 min-w-0 mr-6 text-sm leading-5">
|
<div className="mr-6 min-w-0 flex-1 flex-col items-center text-sm leading-5">
|
||||||
<div className="flex mb-1 flex-nowrap white">
|
<div className="white mb-1 flex flex-nowrap">
|
||||||
<UserIcon className="min-w-0 flex-shrink-0 mr-1.5 h-5 w-5" />
|
<UserIcon className="mr-1.5 h-5 w-5 min-w-0 flex-shrink-0" />
|
||||||
<span className="w-40 truncate md:w-auto">
|
<span className="w-40 truncate md:w-auto">
|
||||||
<Link
|
<Link
|
||||||
href={
|
href={
|
||||||
@@ -98,7 +98,7 @@ const RequestBlock: React.FC<RequestBlockProps> = ({ request, onUpdate }) => {
|
|||||||
</div>
|
</div>
|
||||||
{request.modifiedBy && (
|
{request.modifiedBy && (
|
||||||
<div className="flex flex-nowrap">
|
<div className="flex flex-nowrap">
|
||||||
<EyeIcon className="flex-shrink-0 mr-1.5 h-5 w-5" />
|
<EyeIcon className="mr-1.5 h-5 w-5 flex-shrink-0" />
|
||||||
<span className="w-40 truncate md:w-auto">
|
<span className="w-40 truncate md:w-auto">
|
||||||
<Link
|
<Link
|
||||||
href={
|
href={
|
||||||
@@ -115,7 +115,7 @@ const RequestBlock: React.FC<RequestBlockProps> = ({ request, onUpdate }) => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-wrap flex-shrink-0 ml-2">
|
<div className="ml-2 flex flex-shrink-0 flex-wrap">
|
||||||
{request.status === MediaRequestStatus.PENDING && (
|
{request.status === MediaRequestStatus.PENDING && (
|
||||||
<>
|
<>
|
||||||
<Button
|
<Button
|
||||||
@@ -156,7 +156,7 @@ const RequestBlock: React.FC<RequestBlockProps> = ({ request, onUpdate }) => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="mt-2 sm:flex sm:justify-between">
|
<div className="mt-2 sm:flex sm:justify-between">
|
||||||
<div className="sm:flex">
|
<div className="sm:flex">
|
||||||
<div className="flex items-center mr-6 text-sm leading-5">
|
<div className="mr-6 flex items-center text-sm leading-5">
|
||||||
{request.is4k && (
|
{request.is4k && (
|
||||||
<span className="mr-1">
|
<span className="mr-1">
|
||||||
<Badge badgeType="warning">4K</Badge>
|
<Badge badgeType="warning">4K</Badge>
|
||||||
@@ -179,8 +179,8 @@ const RequestBlock: React.FC<RequestBlockProps> = ({ request, onUpdate }) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center mt-2 text-sm leading-5 sm:mt-0">
|
<div className="mt-2 flex items-center text-sm leading-5 sm:mt-0">
|
||||||
<CalendarIcon className="flex-shrink-0 mr-1.5 h-5 w-5" />
|
<CalendarIcon className="mr-1.5 h-5 w-5 flex-shrink-0" />
|
||||||
<span>
|
<span>
|
||||||
{intl.formatDate(request.createdAt, {
|
{intl.formatDate(request.createdAt, {
|
||||||
year: 'numeric',
|
year: 'numeric',
|
||||||
@@ -191,7 +191,7 @@ const RequestBlock: React.FC<RequestBlockProps> = ({ request, onUpdate }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{(request.seasons ?? []).length > 0 && (
|
{(request.seasons ?? []).length > 0 && (
|
||||||
<div className="flex flex-col mt-2 text-sm">
|
<div className="mt-2 flex flex-col text-sm">
|
||||||
<div className="mb-1 font-medium">
|
<div className="mb-1 font-medium">
|
||||||
{intl.formatMessage(messages.seasons, {
|
{intl.formatMessage(messages.seasons, {
|
||||||
seasonCount: request.seasons.length,
|
seasonCount: request.seasons.length,
|
||||||
@@ -201,7 +201,7 @@ const RequestBlock: React.FC<RequestBlockProps> = ({ request, onUpdate }) => {
|
|||||||
{request.seasons.map((season) => (
|
{request.seasons.map((season) => (
|
||||||
<span
|
<span
|
||||||
key={`season-${season.id}`}
|
key={`season-${season.id}`}
|
||||||
className="inline-block mb-1 mr-2"
|
className="mb-1 mr-2 inline-block"
|
||||||
>
|
>
|
||||||
<Badge>{season.seasonNumber}</Badge>
|
<Badge>{season.seasonNumber}</Badge>
|
||||||
</span>
|
</span>
|
||||||
@@ -214,7 +214,7 @@ const RequestBlock: React.FC<RequestBlockProps> = ({ request, onUpdate }) => {
|
|||||||
<div className="mt-4 mb-1 text-sm">
|
<div className="mt-4 mb-1 text-sm">
|
||||||
{intl.formatMessage(messages.requestoverrides)}
|
{intl.formatMessage(messages.requestoverrides)}
|
||||||
</div>
|
</div>
|
||||||
<ul className="px-2 text-xs bg-gray-800 divide-y divide-gray-700 rounded-md">
|
<ul className="divide-y divide-gray-700 rounded-md bg-gray-800 px-2 text-xs">
|
||||||
{server && (
|
{server && (
|
||||||
<li className="flex justify-between px-1 py-2">
|
<li className="flex justify-between px-1 py-2">
|
||||||
<span className="font-bold">
|
<span className="font-bold">
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ const isMovie = (movie: MovieDetails | TvDetails): movie is MovieDetails => {
|
|||||||
|
|
||||||
const RequestCardPlaceholder: React.FC = () => {
|
const RequestCardPlaceholder: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
<div className="relative p-4 bg-gray-700 rounded-xl w-72 sm:w-96 animate-pulse">
|
<div className="relative w-72 animate-pulse rounded-xl bg-gray-700 p-4 sm:w-96">
|
||||||
<div className="w-20 sm:w-28">
|
<div className="w-20 sm:w-28">
|
||||||
<div className="w-full" style={{ paddingBottom: '150%' }} />
|
<div className="w-full" style={{ paddingBottom: '150%' }} />
|
||||||
</div>
|
</div>
|
||||||
@@ -63,11 +63,11 @@ const RequestCardError: React.FC<RequestCardErrorProps> = ({ mediaId }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative p-4 bg-gray-800 ring-1 ring-red-500 rounded-xl w-72 sm:w-96">
|
<div className="relative w-72 rounded-xl bg-gray-800 p-4 ring-1 ring-red-500 sm:w-96">
|
||||||
<div className="w-20 sm:w-28">
|
<div className="w-20 sm:w-28">
|
||||||
<div className="w-full" style={{ paddingBottom: '150%' }}>
|
<div className="w-full" style={{ paddingBottom: '150%' }}>
|
||||||
<div className="absolute inset-0 flex flex-col items-center justify-center w-full h-full px-10">
|
<div className="absolute inset-0 flex h-full w-full flex-col items-center justify-center px-10">
|
||||||
<div className="w-full text-xs text-center text-gray-300 whitespace-normal sm:text-sm">
|
<div className="w-full whitespace-normal text-center text-xs text-gray-300 sm:text-sm">
|
||||||
{intl.formatMessage(messages.mediaerror)}
|
{intl.formatMessage(messages.mediaerror)}
|
||||||
</div>
|
</div>
|
||||||
{hasPermission(Permission.MANAGE_REQUESTS) && mediaId && (
|
{hasPermission(Permission.MANAGE_REQUESTS) && mediaId && (
|
||||||
@@ -185,7 +185,7 @@ const RequestCard: React.FC<RequestCardProps> = ({ request, onTitleData }) => {
|
|||||||
setShowEditModal(false);
|
setShowEditModal(false);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<div className="relative flex p-4 overflow-hidden text-gray-400 bg-gray-800 bg-center bg-cover shadow rounded-xl w-72 sm:w-96 ring-1 ring-gray-700">
|
<div className="relative flex w-72 overflow-hidden rounded-xl bg-gray-800 bg-cover bg-center p-4 text-gray-400 shadow ring-1 ring-gray-700 sm:w-96">
|
||||||
{title.backdropPath && (
|
{title.backdropPath && (
|
||||||
<div className="absolute inset-0 z-0">
|
<div className="absolute inset-0 z-0">
|
||||||
<CachedImage
|
<CachedImage
|
||||||
@@ -203,7 +203,7 @@ const RequestCard: React.FC<RequestCardProps> = ({ request, onTitleData }) => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="relative z-10 flex flex-col flex-1 min-w-0 pr-4">
|
<div className="relative z-10 flex min-w-0 flex-1 flex-col pr-4">
|
||||||
<div className="hidden text-xs font-medium text-white sm:flex">
|
<div className="hidden text-xs font-medium text-white sm:flex">
|
||||||
{(isMovie(title) ? title.releaseDate : title.firstAirDate)?.slice(
|
{(isMovie(title) ? title.releaseDate : title.firstAirDate)?.slice(
|
||||||
0,
|
0,
|
||||||
@@ -217,7 +217,7 @@ const RequestCard: React.FC<RequestCardProps> = ({ request, onTitleData }) => {
|
|||||||
: `/tv/${requestData.media.tmdbId}`
|
: `/tv/${requestData.media.tmdbId}`
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<a className="overflow-hidden text-base font-bold text-white sm:text-lg overflow-ellipsis whitespace-nowrap hover:underline">
|
<a className="overflow-hidden overflow-ellipsis whitespace-nowrap text-base font-bold text-white hover:underline sm:text-lg">
|
||||||
{isMovie(title) ? title.title : title.name}
|
{isMovie(title) ? title.title : title.name}
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
@@ -227,13 +227,13 @@ const RequestCard: React.FC<RequestCardProps> = ({ request, onTitleData }) => {
|
|||||||
) && (
|
) && (
|
||||||
<div className="card-field">
|
<div className="card-field">
|
||||||
<Link href={`/users/${requestData.requestedBy.id}`}>
|
<Link href={`/users/${requestData.requestedBy.id}`}>
|
||||||
<a className="flex items-center group">
|
<a className="group flex items-center">
|
||||||
<img
|
<img
|
||||||
src={requestData.requestedBy.avatar}
|
src={requestData.requestedBy.avatar}
|
||||||
alt=""
|
alt=""
|
||||||
className="avatar-sm"
|
className="avatar-sm"
|
||||||
/>
|
/>
|
||||||
<span className="font-semibold truncate group-hover:underline group-hover:text-white">
|
<span className="truncate font-semibold group-hover:text-white group-hover:underline">
|
||||||
{requestData.requestedBy.displayName}
|
{requestData.requestedBy.displayName}
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
@@ -241,7 +241,7 @@ const RequestCard: React.FC<RequestCardProps> = ({ request, onTitleData }) => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{!isMovie(title) && request.seasons.length > 0 && (
|
{!isMovie(title) && request.seasons.length > 0 && (
|
||||||
<div className="items-center my-0.5 sm:my-1 text-sm hidden sm:flex">
|
<div className="my-0.5 hidden items-center text-sm sm:my-1 sm:flex">
|
||||||
<span className="mr-2 font-bold ">
|
<span className="mr-2 font-bold ">
|
||||||
{intl.formatMessage(messages.seasons, {
|
{intl.formatMessage(messages.seasons, {
|
||||||
seasonCount:
|
seasonCount:
|
||||||
@@ -257,7 +257,7 @@ const RequestCard: React.FC<RequestCardProps> = ({ request, onTitleData }) => {
|
|||||||
<Badge>{intl.formatMessage(globalMessages.all)}</Badge>
|
<Badge>{intl.formatMessage(globalMessages.all)}</Badge>
|
||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
<div className="overflow-x-scroll hide-scrollbar">
|
<div className="hide-scrollbar overflow-x-scroll">
|
||||||
{request.seasons.map((season) => (
|
{request.seasons.map((season) => (
|
||||||
<span key={`season-${season.id}`} className="mr-2">
|
<span key={`season-${season.id}`} className="mr-2">
|
||||||
<Badge>{season.seasonNumber}</Badge>
|
<Badge>{season.seasonNumber}</Badge>
|
||||||
@@ -267,8 +267,8 @@ const RequestCard: React.FC<RequestCardProps> = ({ request, onTitleData }) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="flex items-center mt-2 text-sm sm:mt-1">
|
<div className="mt-2 flex items-center text-sm sm:mt-1">
|
||||||
<span className="hidden mr-2 font-bold sm:block">
|
<span className="mr-2 hidden font-bold sm:block">
|
||||||
{intl.formatMessage(globalMessages.status)}
|
{intl.formatMessage(globalMessages.status)}
|
||||||
</span>
|
</span>
|
||||||
{requestData.status === MediaRequestStatus.DECLINED ? (
|
{requestData.status === MediaRequestStatus.DECLINED ? (
|
||||||
@@ -304,7 +304,7 @@ const RequestCard: React.FC<RequestCardProps> = ({ request, onTitleData }) => {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-end flex-1 space-x-2">
|
<div className="flex flex-1 items-end space-x-2">
|
||||||
{requestData.media[requestData.is4k ? 'status4k' : 'status'] ===
|
{requestData.media[requestData.is4k ? 'status4k' : 'status'] ===
|
||||||
MediaStatus.UNKNOWN &&
|
MediaStatus.UNKNOWN &&
|
||||||
requestData.status !== MediaRequestStatus.DECLINED &&
|
requestData.status !== MediaRequestStatus.DECLINED &&
|
||||||
@@ -319,7 +319,7 @@ const RequestCard: React.FC<RequestCardProps> = ({ request, onTitleData }) => {
|
|||||||
className={isRetrying ? 'animate-spin' : ''}
|
className={isRetrying ? 'animate-spin' : ''}
|
||||||
style={{ marginRight: '0', animationDirection: 'reverse' }}
|
style={{ marginRight: '0', animationDirection: 'reverse' }}
|
||||||
/>
|
/>
|
||||||
<span className="hidden ml-1.5 sm:block">
|
<span className="ml-1.5 hidden sm:block">
|
||||||
{intl.formatMessage(globalMessages.retry)}
|
{intl.formatMessage(globalMessages.retry)}
|
||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
@@ -333,7 +333,7 @@ const RequestCard: React.FC<RequestCardProps> = ({ request, onTitleData }) => {
|
|||||||
onClick={() => modifyRequest('approve')}
|
onClick={() => modifyRequest('approve')}
|
||||||
>
|
>
|
||||||
<CheckIcon style={{ marginRight: '0' }} />
|
<CheckIcon style={{ marginRight: '0' }} />
|
||||||
<span className="hidden ml-1.5 sm:block">
|
<span className="ml-1.5 hidden sm:block">
|
||||||
{intl.formatMessage(globalMessages.approve)}
|
{intl.formatMessage(globalMessages.approve)}
|
||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
@@ -343,7 +343,7 @@ const RequestCard: React.FC<RequestCardProps> = ({ request, onTitleData }) => {
|
|||||||
onClick={() => modifyRequest('decline')}
|
onClick={() => modifyRequest('decline')}
|
||||||
>
|
>
|
||||||
<XIcon style={{ marginRight: '0' }} />
|
<XIcon style={{ marginRight: '0' }} />
|
||||||
<span className="hidden ml-1.5 sm:block">
|
<span className="ml-1.5 hidden sm:block">
|
||||||
{intl.formatMessage(globalMessages.decline)}
|
{intl.formatMessage(globalMessages.decline)}
|
||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
@@ -363,7 +363,7 @@ const RequestCard: React.FC<RequestCardProps> = ({ request, onTitleData }) => {
|
|||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<PencilIcon style={{ marginRight: '0' }} />
|
<PencilIcon style={{ marginRight: '0' }} />
|
||||||
<span className="hidden ml-1.5 sm:block">
|
<span className="ml-1.5 hidden sm:block">
|
||||||
{intl.formatMessage(globalMessages.edit)}
|
{intl.formatMessage(globalMessages.edit)}
|
||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
@@ -377,7 +377,7 @@ const RequestCard: React.FC<RequestCardProps> = ({ request, onTitleData }) => {
|
|||||||
onClick={() => deleteRequest()}
|
onClick={() => deleteRequest()}
|
||||||
>
|
>
|
||||||
<XIcon style={{ marginRight: '0' }} />
|
<XIcon style={{ marginRight: '0' }} />
|
||||||
<span className="hidden ml-1.5 sm:block">
|
<span className="ml-1.5 hidden sm:block">
|
||||||
{intl.formatMessage(globalMessages.cancel)}
|
{intl.formatMessage(globalMessages.cancel)}
|
||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
@@ -391,7 +391,7 @@ const RequestCard: React.FC<RequestCardProps> = ({ request, onTitleData }) => {
|
|||||||
: `/tv/${requestData.media.tmdbId}`
|
: `/tv/${requestData.media.tmdbId}`
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<a className="flex-shrink-0 w-20 overflow-hidden transition duration-300 scale-100 rounded-md shadow-sm cursor-pointer sm:w-28 transform-gpu hover:scale-105 hover:shadow-md">
|
<a className="w-20 flex-shrink-0 scale-100 transform-gpu cursor-pointer overflow-hidden rounded-md shadow-sm transition duration-300 hover:scale-105 hover:shadow-md sm:w-28">
|
||||||
<CachedImage
|
<CachedImage
|
||||||
src={
|
src={
|
||||||
title.posterPath
|
title.posterPath
|
||||||
|
|||||||
@@ -63,8 +63,8 @@ const RequestItemError: React.FC<RequestItemErroProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center justify-center w-full h-64 px-10 bg-gray-800 lg:flex-row ring-1 ring-red-500 rounded-xl xl:h-28">
|
<div className="flex h-64 w-full flex-col items-center justify-center rounded-xl bg-gray-800 px-10 ring-1 ring-red-500 lg:flex-row xl:h-28">
|
||||||
<span className="text-sm text-center text-gray-300 lg:text-left">
|
<span className="text-center text-sm text-gray-300 lg:text-left">
|
||||||
{intl.formatMessage(messages.mediaerror)}
|
{intl.formatMessage(messages.mediaerror)}
|
||||||
</span>
|
</span>
|
||||||
{hasPermission(Permission.MANAGE_REQUESTS) && mediaId && (
|
{hasPermission(Permission.MANAGE_REQUESTS) && mediaId && (
|
||||||
@@ -148,7 +148,7 @@ const RequestItem: React.FC<RequestItemProps> = ({
|
|||||||
if (!title && !error) {
|
if (!title && !error) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="w-full h-64 bg-gray-800 rounded-xl xl:h-28 animate-pulse"
|
className="h-64 w-full animate-pulse rounded-xl bg-gray-800 xl:h-28"
|
||||||
ref={ref}
|
ref={ref}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@@ -177,9 +177,9 @@ const RequestItem: React.FC<RequestItemProps> = ({
|
|||||||
setShowEditModal(false);
|
setShowEditModal(false);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<div className="relative flex flex-col justify-between w-full py-4 overflow-hidden text-gray-400 bg-gray-800 shadow-md ring-1 ring-gray-700 rounded-xl xl:h-28 xl:flex-row">
|
<div className="relative flex w-full flex-col justify-between overflow-hidden rounded-xl bg-gray-800 py-4 text-gray-400 shadow-md ring-1 ring-gray-700 xl:h-28 xl:flex-row">
|
||||||
{title.backdropPath && (
|
{title.backdropPath && (
|
||||||
<div className="absolute inset-0 z-0 w-full bg-center bg-cover xl:w-2/3">
|
<div className="absolute inset-0 z-0 w-full bg-cover bg-center xl:w-2/3">
|
||||||
<CachedImage
|
<CachedImage
|
||||||
src={`https://image.tmdb.org/t/p/w1920_and_h800_multi_faces/${title.backdropPath}`}
|
src={`https://image.tmdb.org/t/p/w1920_and_h800_multi_faces/${title.backdropPath}`}
|
||||||
alt=""
|
alt=""
|
||||||
@@ -195,8 +195,8 @@ const RequestItem: React.FC<RequestItemProps> = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="relative flex flex-col justify-between w-full overflow-hidden sm:flex-row">
|
<div className="relative flex w-full flex-col justify-between overflow-hidden sm:flex-row">
|
||||||
<div className="relative z-10 flex items-center w-full pl-4 pr-4 overflow-hidden xl:w-7/12 2xl:w-2/3 sm:pr-0">
|
<div className="relative z-10 flex w-full items-center overflow-hidden pl-4 pr-4 sm:pr-0 xl:w-7/12 2xl:w-2/3">
|
||||||
<Link
|
<Link
|
||||||
href={
|
href={
|
||||||
requestData.type === 'movie'
|
requestData.type === 'movie'
|
||||||
@@ -204,7 +204,7 @@ const RequestItem: React.FC<RequestItemProps> = ({
|
|||||||
: `/tv/${requestData.media.tmdbId}`
|
: `/tv/${requestData.media.tmdbId}`
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<a className="relative flex-shrink-0 w-12 h-auto overflow-hidden transition duration-300 scale-100 rounded-md transform-gpu hover:scale-105">
|
<a className="relative h-auto w-12 flex-shrink-0 scale-100 transform-gpu overflow-hidden rounded-md transition duration-300 hover:scale-105">
|
||||||
<CachedImage
|
<CachedImage
|
||||||
src={
|
src={
|
||||||
title.posterPath
|
title.posterPath
|
||||||
@@ -219,8 +219,8 @@ const RequestItem: React.FC<RequestItemProps> = ({
|
|||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
<div className="flex flex-col justify-center pl-2 overflow-hidden xl:pl-4">
|
<div className="flex flex-col justify-center overflow-hidden pl-2 xl:pl-4">
|
||||||
<div className="font-medium pt-0.5 sm:pt-1 text-xs text-white">
|
<div className="pt-0.5 text-xs font-medium text-white sm:pt-1">
|
||||||
{(isMovie(title)
|
{(isMovie(title)
|
||||||
? title.releaseDate
|
? title.releaseDate
|
||||||
: title.firstAirDate
|
: title.firstAirDate
|
||||||
@@ -233,7 +233,7 @@ const RequestItem: React.FC<RequestItemProps> = ({
|
|||||||
: `/tv/${requestData.media.tmdbId}`
|
: `/tv/${requestData.media.tmdbId}`
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<a className="min-w-0 mr-2 text-lg font-bold text-white truncate xl:text-xl hover:underline">
|
<a className="mr-2 min-w-0 truncate text-lg font-bold text-white hover:underline xl:text-xl">
|
||||||
{isMovie(title) ? title.title : title.name}
|
{isMovie(title) ? title.title : title.name}
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
@@ -255,7 +255,7 @@ const RequestItem: React.FC<RequestItemProps> = ({
|
|||||||
<Badge>{intl.formatMessage(globalMessages.all)}</Badge>
|
<Badge>{intl.formatMessage(globalMessages.all)}</Badge>
|
||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex overflow-x-scroll hide-scrollbar flex-nowrap">
|
<div className="hide-scrollbar flex flex-nowrap overflow-x-scroll">
|
||||||
{request.seasons.map((season) => (
|
{request.seasons.map((season) => (
|
||||||
<span key={`season-${season.id}`} className="mr-2">
|
<span key={`season-${season.id}`} className="mr-2">
|
||||||
<Badge>{season.seasonNumber}</Badge>
|
<Badge>{season.seasonNumber}</Badge>
|
||||||
@@ -267,7 +267,7 @@ const RequestItem: React.FC<RequestItemProps> = ({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="z-10 flex flex-col justify-center w-full pr-4 mt-4 ml-4 overflow-hidden text-sm sm:ml-2 sm:mt-0 xl:flex-1 xl:pr-0">
|
<div className="z-10 mt-4 ml-4 flex w-full flex-col justify-center overflow-hidden pr-4 text-sm sm:ml-2 sm:mt-0 xl:flex-1 xl:pr-0">
|
||||||
<div className="card-field">
|
<div className="card-field">
|
||||||
<span className="card-field-name">
|
<span className="card-field-name">
|
||||||
{intl.formatMessage(globalMessages.status)}
|
{intl.formatMessage(globalMessages.status)}
|
||||||
@@ -317,7 +317,7 @@ const RequestItem: React.FC<RequestItemProps> = ({
|
|||||||
<span className="card-field-name">
|
<span className="card-field-name">
|
||||||
{intl.formatMessage(messages.requested)}
|
{intl.formatMessage(messages.requested)}
|
||||||
</span>
|
</span>
|
||||||
<span className="flex text-sm text-gray-300 truncate">
|
<span className="flex truncate text-sm text-gray-300">
|
||||||
{intl.formatMessage(messages.modifieduserdate, {
|
{intl.formatMessage(messages.modifieduserdate, {
|
||||||
date: (
|
date: (
|
||||||
<FormattedRelativeTime
|
<FormattedRelativeTime
|
||||||
@@ -332,13 +332,13 @@ const RequestItem: React.FC<RequestItemProps> = ({
|
|||||||
),
|
),
|
||||||
user: (
|
user: (
|
||||||
<Link href={`/users/${requestData.requestedBy.id}`}>
|
<Link href={`/users/${requestData.requestedBy.id}`}>
|
||||||
<a className="flex items-center truncate group">
|
<a className="group flex items-center truncate">
|
||||||
<img
|
<img
|
||||||
src={requestData.requestedBy.avatar}
|
src={requestData.requestedBy.avatar}
|
||||||
alt=""
|
alt=""
|
||||||
className="ml-1.5 avatar-sm"
|
className="avatar-sm ml-1.5"
|
||||||
/>
|
/>
|
||||||
<span className="text-sm font-semibold truncate group-hover:underline group-hover:text-white">
|
<span className="truncate text-sm font-semibold group-hover:text-white group-hover:underline">
|
||||||
{requestData.requestedBy.displayName}
|
{requestData.requestedBy.displayName}
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
@@ -352,7 +352,7 @@ const RequestItem: React.FC<RequestItemProps> = ({
|
|||||||
<span className="card-field-name">
|
<span className="card-field-name">
|
||||||
{intl.formatMessage(messages.requesteddate)}
|
{intl.formatMessage(messages.requesteddate)}
|
||||||
</span>
|
</span>
|
||||||
<span className="flex text-sm text-gray-300 truncate">
|
<span className="flex truncate text-sm text-gray-300">
|
||||||
<FormattedRelativeTime
|
<FormattedRelativeTime
|
||||||
value={Math.floor(
|
value={Math.floor(
|
||||||
(new Date(requestData.createdAt).getTime() -
|
(new Date(requestData.createdAt).getTime() -
|
||||||
@@ -371,7 +371,7 @@ const RequestItem: React.FC<RequestItemProps> = ({
|
|||||||
<span className="card-field-name">
|
<span className="card-field-name">
|
||||||
{intl.formatMessage(messages.modified)}
|
{intl.formatMessage(messages.modified)}
|
||||||
</span>
|
</span>
|
||||||
<span className="flex text-sm text-gray-300 truncate">
|
<span className="flex truncate text-sm text-gray-300">
|
||||||
{intl.formatMessage(messages.modifieduserdate, {
|
{intl.formatMessage(messages.modifieduserdate, {
|
||||||
date: (
|
date: (
|
||||||
<FormattedRelativeTime
|
<FormattedRelativeTime
|
||||||
@@ -386,13 +386,13 @@ const RequestItem: React.FC<RequestItemProps> = ({
|
|||||||
),
|
),
|
||||||
user: (
|
user: (
|
||||||
<Link href={`/users/${requestData.modifiedBy.id}`}>
|
<Link href={`/users/${requestData.modifiedBy.id}`}>
|
||||||
<a className="flex items-center truncate group">
|
<a className="group flex items-center truncate">
|
||||||
<img
|
<img
|
||||||
src={requestData.modifiedBy.avatar}
|
src={requestData.modifiedBy.avatar}
|
||||||
alt=""
|
alt=""
|
||||||
className="ml-1.5 avatar-sm"
|
className="avatar-sm ml-1.5"
|
||||||
/>
|
/>
|
||||||
<span className="text-sm font-semibold truncate group-hover:underline group-hover:text-white">
|
<span className="truncate text-sm font-semibold group-hover:text-white group-hover:underline">
|
||||||
{requestData.modifiedBy.displayName}
|
{requestData.modifiedBy.displayName}
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
@@ -404,7 +404,7 @@ const RequestItem: React.FC<RequestItemProps> = ({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="z-10 flex flex-col justify-center w-full pl-4 pr-4 mt-4 space-y-2 xl:mt-0 xl:items-end xl:w-96 xl:pl-0">
|
<div className="z-10 mt-4 flex w-full flex-col justify-center space-y-2 pl-4 pr-4 xl:mt-0 xl:w-96 xl:items-end xl:pl-0">
|
||||||
{requestData.media[requestData.is4k ? 'status4k' : 'status'] ===
|
{requestData.media[requestData.is4k ? 'status4k' : 'status'] ===
|
||||||
MediaStatus.UNKNOWN &&
|
MediaStatus.UNKNOWN &&
|
||||||
requestData.status !== MediaRequestStatus.DECLINED &&
|
requestData.status !== MediaRequestStatus.DECLINED &&
|
||||||
@@ -439,7 +439,7 @@ const RequestItem: React.FC<RequestItemProps> = ({
|
|||||||
)}
|
)}
|
||||||
{requestData.status === MediaRequestStatus.PENDING &&
|
{requestData.status === MediaRequestStatus.PENDING &&
|
||||||
hasPermission(Permission.MANAGE_REQUESTS) && (
|
hasPermission(Permission.MANAGE_REQUESTS) && (
|
||||||
<div className="flex flex-row w-full space-x-2">
|
<div className="flex w-full flex-row space-x-2">
|
||||||
<span className="w-full">
|
<span className="w-full">
|
||||||
<Button
|
<Button
|
||||||
className="w-full"
|
className="w-full"
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ const RequestList: React.FC = () => {
|
|||||||
router.query.userId ? user?.displayName : '',
|
router.query.userId ? user?.displayName : '',
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<div className="flex flex-col justify-between mb-4 lg:items-end lg:flex-row">
|
<div className="mb-4 flex flex-col justify-between lg:flex-row lg:items-end">
|
||||||
<Header
|
<Header
|
||||||
subtext={
|
subtext={
|
||||||
router.query.userId ? (
|
router.query.userId ? (
|
||||||
@@ -126,10 +126,10 @@ const RequestList: React.FC = () => {
|
|||||||
>
|
>
|
||||||
{intl.formatMessage(messages.requests)}
|
{intl.formatMessage(messages.requests)}
|
||||||
</Header>
|
</Header>
|
||||||
<div className="flex flex-col flex-grow mt-2 sm:flex-row lg:flex-grow-0">
|
<div className="mt-2 flex flex-grow flex-col sm:flex-row lg:flex-grow-0">
|
||||||
<div className="flex flex-grow mb-2 sm:mb-0 sm:mr-2 lg:flex-grow-0">
|
<div className="mb-2 flex flex-grow sm:mb-0 sm:mr-2 lg:flex-grow-0">
|
||||||
<span className="inline-flex items-center px-3 text-sm text-gray-100 bg-gray-800 border border-r-0 border-gray-500 cursor-default rounded-l-md">
|
<span className="inline-flex cursor-default items-center rounded-l-md border border-r-0 border-gray-500 bg-gray-800 px-3 text-sm text-gray-100">
|
||||||
<FilterIcon className="w-6 h-6" />
|
<FilterIcon className="h-6 w-6" />
|
||||||
</span>
|
</span>
|
||||||
<select
|
<select
|
||||||
id="filter"
|
id="filter"
|
||||||
@@ -166,9 +166,9 @@ const RequestList: React.FC = () => {
|
|||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-grow mb-2 sm:mb-0 lg:flex-grow-0">
|
<div className="mb-2 flex flex-grow sm:mb-0 lg:flex-grow-0">
|
||||||
<span className="inline-flex items-center px-3 text-gray-100 bg-gray-800 border border-r-0 border-gray-500 cursor-default sm:text-sm rounded-l-md">
|
<span className="inline-flex cursor-default items-center rounded-l-md border border-r-0 border-gray-500 bg-gray-800 px-3 text-gray-100 sm:text-sm">
|
||||||
<SortDescendingIcon className="w-6 h-6" />
|
<SortDescendingIcon className="h-6 w-6" />
|
||||||
</span>
|
</span>
|
||||||
<select
|
<select
|
||||||
id="sort"
|
id="sort"
|
||||||
@@ -207,7 +207,7 @@ const RequestList: React.FC = () => {
|
|||||||
})}
|
})}
|
||||||
|
|
||||||
{data.results.length === 0 && (
|
{data.results.length === 0 && (
|
||||||
<div className="flex flex-col items-center justify-center w-full py-24 text-white">
|
<div className="flex w-full flex-col items-center justify-center py-24 text-white">
|
||||||
<span className="text-2xl text-gray-400">
|
<span className="text-2xl text-gray-400">
|
||||||
{intl.formatMessage(globalMessages.noresults)}
|
{intl.formatMessage(globalMessages.noresults)}
|
||||||
</span>
|
</span>
|
||||||
@@ -225,7 +225,7 @@ const RequestList: React.FC = () => {
|
|||||||
)}
|
)}
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<nav
|
<nav
|
||||||
className="flex flex-col items-center mb-3 space-y-3 sm:space-y-0 sm:flex-row"
|
className="mb-3 flex flex-col items-center space-y-3 sm:flex-row sm:space-y-0"
|
||||||
aria-label="Pagination"
|
aria-label="Pagination"
|
||||||
>
|
>
|
||||||
<div className="hidden lg:flex lg:flex-1">
|
<div className="hidden lg:flex lg:flex-1">
|
||||||
@@ -245,7 +245,7 @@ const RequestList: React.FC = () => {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-center sm:flex-1 sm:justify-start lg:justify-center">
|
<div className="flex justify-center sm:flex-1 sm:justify-start lg:justify-center">
|
||||||
<span className="items-center -mt-3 text-sm truncate sm:mt-0">
|
<span className="-mt-3 items-center truncate text-sm sm:mt-0">
|
||||||
{intl.formatMessage(globalMessages.resultsperpage, {
|
{intl.formatMessage(globalMessages.resultsperpage, {
|
||||||
pageSize: (
|
pageSize: (
|
||||||
<select
|
<select
|
||||||
@@ -263,7 +263,7 @@ const RequestList: React.FC = () => {
|
|||||||
.then(() => window.scrollTo(0, 0));
|
.then(() => window.scrollTo(0, 0));
|
||||||
}}
|
}}
|
||||||
value={currentPageSize}
|
value={currentPageSize}
|
||||||
className="inline short"
|
className="short inline"
|
||||||
>
|
>
|
||||||
<option value="5">5</option>
|
<option value="5">5</option>
|
||||||
<option value="10">10</option>
|
<option value="10">10</option>
|
||||||
@@ -275,7 +275,7 @@ const RequestList: React.FC = () => {
|
|||||||
})}
|
})}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-center flex-auto space-x-2 sm:justify-end sm:flex-1">
|
<div className="flex flex-auto justify-center space-x-2 sm:flex-1 sm:justify-end">
|
||||||
<Button
|
<Button
|
||||||
disabled={!hasPrevPage}
|
disabled={!hasPrevPage}
|
||||||
onClick={() => updateQueryParams('page', (page - 1).toString())}
|
onClick={() => updateQueryParams('page', (page - 1).toString())}
|
||||||
|
|||||||
@@ -258,7 +258,7 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
|||||||
|
|
||||||
if (!data && !error) {
|
if (!data && !error) {
|
||||||
return (
|
return (
|
||||||
<div className="w-full mb-2">
|
<div className="mb-2 w-full">
|
||||||
<SmallLoadingSpinner />
|
<SmallLoadingSpinner />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -280,15 +280,15 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="flex items-center mt-4 mb-2 font-bold tracking-wider">
|
<div className="mt-4 mb-2 flex items-center font-bold tracking-wider">
|
||||||
<AdjustmentsIcon className="w-5 h-5 mr-1.5" />
|
<AdjustmentsIcon className="mr-1.5 h-5 w-5" />
|
||||||
{intl.formatMessage(messages.advancedoptions)}
|
{intl.formatMessage(messages.advancedoptions)}
|
||||||
</div>
|
</div>
|
||||||
<div className="p-4 bg-gray-600 rounded-md shadow">
|
<div className="rounded-md bg-gray-600 p-4 shadow">
|
||||||
{!!data && selectedServer !== null && (
|
{!!data && selectedServer !== null && (
|
||||||
<div className="flex flex-col md:flex-row">
|
<div className="flex flex-col md:flex-row">
|
||||||
{data.filter((server) => server.is4k === is4k).length > 1 && (
|
{data.filter((server) => server.is4k === is4k).length > 1 && (
|
||||||
<div className="flex-grow flex-shrink-0 w-full mb-3 md:w-1/4 md:pr-4 last:pr-0">
|
<div className="mb-3 w-full flex-shrink-0 flex-grow last:pr-0 md:w-1/4 md:pr-4">
|
||||||
<label htmlFor="server">
|
<label htmlFor="server">
|
||||||
{intl.formatMessage(messages.destinationserver)}
|
{intl.formatMessage(messages.destinationserver)}
|
||||||
</label>
|
</label>
|
||||||
@@ -298,7 +298,7 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
|||||||
value={selectedServer}
|
value={selectedServer}
|
||||||
onChange={(e) => setSelectedServer(Number(e.target.value))}
|
onChange={(e) => setSelectedServer(Number(e.target.value))}
|
||||||
onBlur={(e) => setSelectedServer(Number(e.target.value))}
|
onBlur={(e) => setSelectedServer(Number(e.target.value))}
|
||||||
className="bg-gray-800 border-gray-700"
|
className="border-gray-700 bg-gray-800"
|
||||||
>
|
>
|
||||||
{data
|
{data
|
||||||
.filter((server) => server.is4k === is4k)
|
.filter((server) => server.is4k === is4k)
|
||||||
@@ -320,7 +320,7 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
|||||||
{(isValidating ||
|
{(isValidating ||
|
||||||
!serverData ||
|
!serverData ||
|
||||||
serverData.profiles.length > 1) && (
|
serverData.profiles.length > 1) && (
|
||||||
<div className="flex-grow flex-shrink-0 w-full mb-3 md:w-1/4 md:pr-4 last:pr-0">
|
<div className="mb-3 w-full flex-shrink-0 flex-grow last:pr-0 md:w-1/4 md:pr-4">
|
||||||
<label htmlFor="profile">
|
<label htmlFor="profile">
|
||||||
{intl.formatMessage(messages.qualityprofile)}
|
{intl.formatMessage(messages.qualityprofile)}
|
||||||
</label>
|
</label>
|
||||||
@@ -330,7 +330,7 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
|||||||
value={selectedProfile}
|
value={selectedProfile}
|
||||||
onChange={(e) => setSelectedProfile(Number(e.target.value))}
|
onChange={(e) => setSelectedProfile(Number(e.target.value))}
|
||||||
onBlur={(e) => setSelectedProfile(Number(e.target.value))}
|
onBlur={(e) => setSelectedProfile(Number(e.target.value))}
|
||||||
className="bg-gray-800 border-gray-700"
|
className="border-gray-700 bg-gray-800"
|
||||||
disabled={isValidating || !serverData}
|
disabled={isValidating || !serverData}
|
||||||
>
|
>
|
||||||
{(isValidating || !serverData) && (
|
{(isValidating || !serverData) && (
|
||||||
@@ -364,7 +364,7 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
|||||||
{(isValidating ||
|
{(isValidating ||
|
||||||
!serverData ||
|
!serverData ||
|
||||||
serverData.rootFolders.length > 1) && (
|
serverData.rootFolders.length > 1) && (
|
||||||
<div className="flex-grow flex-shrink-0 w-full mb-3 md:w-1/4 md:pr-4 last:pr-0">
|
<div className="mb-3 w-full flex-shrink-0 flex-grow last:pr-0 md:w-1/4 md:pr-4">
|
||||||
<label htmlFor="folder">
|
<label htmlFor="folder">
|
||||||
{intl.formatMessage(messages.rootfolder)}
|
{intl.formatMessage(messages.rootfolder)}
|
||||||
</label>
|
</label>
|
||||||
@@ -374,7 +374,7 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
|||||||
value={selectedFolder}
|
value={selectedFolder}
|
||||||
onChange={(e) => setSelectedFolder(e.target.value)}
|
onChange={(e) => setSelectedFolder(e.target.value)}
|
||||||
onBlur={(e) => setSelectedFolder(e.target.value)}
|
onBlur={(e) => setSelectedFolder(e.target.value)}
|
||||||
className="bg-gray-800 border-gray-700"
|
className="border-gray-700 bg-gray-800"
|
||||||
disabled={isValidating || !serverData}
|
disabled={isValidating || !serverData}
|
||||||
>
|
>
|
||||||
{(isValidating || !serverData) && (
|
{(isValidating || !serverData) && (
|
||||||
@@ -418,7 +418,7 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
|||||||
(isValidating ||
|
(isValidating ||
|
||||||
!serverData ||
|
!serverData ||
|
||||||
(serverData.languageProfiles ?? []).length > 1) && (
|
(serverData.languageProfiles ?? []).length > 1) && (
|
||||||
<div className="flex-grow flex-shrink-0 w-full mb-3 md:w-1/4 md:pr-4 last:pr-0">
|
<div className="mb-3 w-full flex-shrink-0 flex-grow last:pr-0 md:w-1/4 md:pr-4">
|
||||||
<label htmlFor="language">
|
<label htmlFor="language">
|
||||||
{intl.formatMessage(messages.languageprofile)}
|
{intl.formatMessage(messages.languageprofile)}
|
||||||
</label>
|
</label>
|
||||||
@@ -432,7 +432,7 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
|||||||
onBlur={(e) =>
|
onBlur={(e) =>
|
||||||
setSelectedLanguage(parseInt(e.target.value))
|
setSelectedLanguage(parseInt(e.target.value))
|
||||||
}
|
}
|
||||||
className="bg-gray-800 border-gray-700"
|
className="border-gray-700 bg-gray-800"
|
||||||
disabled={isValidating || !serverData}
|
disabled={isValidating || !serverData}
|
||||||
>
|
>
|
||||||
{(isValidating || !serverData) && (
|
{(isValidating || !serverData) && (
|
||||||
@@ -529,25 +529,25 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
|||||||
</Listbox.Label>
|
</Listbox.Label>
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<span className="inline-block w-full rounded-md shadow-sm">
|
<span className="inline-block w-full rounded-md shadow-sm">
|
||||||
<Listbox.Button className="relative w-full py-2 pl-3 pr-10 text-left text-white transition duration-150 ease-in-out bg-gray-800 border border-gray-700 rounded-md cursor-default focus:outline-none focus:shadow-outline-blue focus:border-blue-300 sm:text-sm sm:leading-5">
|
<Listbox.Button className="focus:shadow-outline-blue relative w-full cursor-default rounded-md border border-gray-700 bg-gray-800 py-2 pl-3 pr-10 text-left text-white transition duration-150 ease-in-out focus:border-blue-300 focus:outline-none sm:text-sm sm:leading-5">
|
||||||
<span className="flex items-center">
|
<span className="flex items-center">
|
||||||
<img
|
<img
|
||||||
src={selectedUser.avatar}
|
src={selectedUser.avatar}
|
||||||
alt=""
|
alt=""
|
||||||
className="flex-shrink-0 w-6 h-6 rounded-full"
|
className="h-6 w-6 flex-shrink-0 rounded-full"
|
||||||
/>
|
/>
|
||||||
<span className="block ml-3">
|
<span className="ml-3 block">
|
||||||
{selectedUser.displayName}
|
{selectedUser.displayName}
|
||||||
</span>
|
</span>
|
||||||
{selectedUser.displayName.toLowerCase() !==
|
{selectedUser.displayName.toLowerCase() !==
|
||||||
selectedUser.email && (
|
selectedUser.email && (
|
||||||
<span className="ml-1 text-gray-400 truncate">
|
<span className="ml-1 truncate text-gray-400">
|
||||||
({selectedUser.email})
|
({selectedUser.email})
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
<span className="absolute inset-y-0 right-0 flex items-center pr-2 text-gray-500 pointer-events-none">
|
<span className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2 text-gray-500">
|
||||||
<ChevronDownIcon className="w-5 h-5" />
|
<ChevronDownIcon className="h-5 w-5" />
|
||||||
</span>
|
</span>
|
||||||
</Listbox.Button>
|
</Listbox.Button>
|
||||||
</span>
|
</span>
|
||||||
@@ -560,11 +560,11 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
|||||||
leave="transition ease-in duration-100"
|
leave="transition ease-in duration-100"
|
||||||
leaveFrom="opacity-100"
|
leaveFrom="opacity-100"
|
||||||
leaveTo="opacity-0"
|
leaveTo="opacity-0"
|
||||||
className="w-full mt-1 bg-gray-800 rounded-md shadow-lg"
|
className="mt-1 w-full rounded-md bg-gray-800 shadow-lg"
|
||||||
>
|
>
|
||||||
<Listbox.Options
|
<Listbox.Options
|
||||||
static
|
static
|
||||||
className="py-1 overflow-auto text-base leading-6 rounded-md shadow-xs max-h-60 focus:outline-none sm:text-sm sm:leading-5"
|
className="shadow-xs max-h-60 overflow-auto rounded-md py-1 text-base leading-6 focus:outline-none sm:text-sm sm:leading-5"
|
||||||
>
|
>
|
||||||
{userData?.results.map((user) => (
|
{userData?.results.map((user) => (
|
||||||
<Listbox.Option key={user.id} value={user}>
|
<Listbox.Option key={user.id} value={user}>
|
||||||
@@ -572,9 +572,9 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
|||||||
<div
|
<div
|
||||||
className={`${
|
className={`${
|
||||||
active
|
active
|
||||||
? 'text-white bg-indigo-600'
|
? 'bg-indigo-600 text-white'
|
||||||
: 'text-gray-300'
|
: 'text-gray-300'
|
||||||
} cursor-default select-none relative py-2 pl-8 pr-4`}
|
} relative cursor-default select-none py-2 pl-8 pr-4`}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className={`${
|
className={`${
|
||||||
@@ -584,14 +584,14 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
|||||||
<img
|
<img
|
||||||
src={user.avatar}
|
src={user.avatar}
|
||||||
alt=""
|
alt=""
|
||||||
className="flex-shrink-0 w-6 h-6 rounded-full"
|
className="h-6 w-6 flex-shrink-0 rounded-full"
|
||||||
/>
|
/>
|
||||||
<span className="flex-shrink-0 block ml-3">
|
<span className="ml-3 block flex-shrink-0">
|
||||||
{user.displayName}
|
{user.displayName}
|
||||||
</span>
|
</span>
|
||||||
{user.displayName.toLowerCase() !==
|
{user.displayName.toLowerCase() !==
|
||||||
user.email && (
|
user.email && (
|
||||||
<span className="ml-1 text-gray-400 truncate">
|
<span className="ml-1 truncate text-gray-400">
|
||||||
({user.email})
|
({user.email})
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
@@ -602,7 +602,7 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
|||||||
active ? 'text-white' : 'text-indigo-600'
|
active ? 'text-white' : 'text-indigo-600'
|
||||||
} absolute inset-y-0 left-0 flex items-center pl-1.5`}
|
} absolute inset-y-0 left-0 flex items-center pl-1.5`}
|
||||||
>
|
>
|
||||||
<CheckIcon className="w-5 h-5" />
|
<CheckIcon className="h-5 w-5" />
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -300,7 +300,7 @@ const CollectionRequestModal: React.FC<RequestModalProps> = ({
|
|||||||
<table className="min-w-full">
|
<table className="min-w-full">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th className="w-16 px-4 py-3 bg-gray-500">
|
<th className="w-16 bg-gray-500 px-4 py-3">
|
||||||
<span
|
<span
|
||||||
role="checkbox"
|
role="checkbox"
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
@@ -311,7 +311,7 @@ const CollectionRequestModal: React.FC<RequestModalProps> = ({
|
|||||||
toggleAllParts();
|
toggleAllParts();
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
className={`relative inline-flex items-center justify-center flex-shrink-0 w-10 h-5 pt-2 cursor-pointer focus:outline-none ${
|
className={`relative inline-flex h-5 w-10 flex-shrink-0 cursor-pointer items-center justify-center pt-2 focus:outline-none ${
|
||||||
quota?.movie.limit &&
|
quota?.movie.limit &&
|
||||||
(quota.movie.remaining ?? 0) < unrequestedParts.length
|
(quota.movie.remaining ?? 0) < unrequestedParts.length
|
||||||
? 'opacity-50'
|
? 'opacity-50'
|
||||||
@@ -322,25 +322,25 @@ const CollectionRequestModal: React.FC<RequestModalProps> = ({
|
|||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
className={`${
|
className={`${
|
||||||
isAllParts() ? 'bg-indigo-500' : 'bg-gray-800'
|
isAllParts() ? 'bg-indigo-500' : 'bg-gray-800'
|
||||||
} absolute h-4 w-9 mx-auto rounded-full transition-colors ease-in-out duration-200`}
|
} absolute mx-auto h-4 w-9 rounded-full transition-colors duration-200 ease-in-out`}
|
||||||
></span>
|
></span>
|
||||||
<span
|
<span
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
className={`${
|
className={`${
|
||||||
isAllParts() ? 'translate-x-5' : 'translate-x-0'
|
isAllParts() ? 'translate-x-5' : 'translate-x-0'
|
||||||
} absolute left-0 inline-block h-5 w-5 border border-gray-200 rounded-full bg-white shadow transform group-focus:ring group-focus:border-blue-300 transition-transform ease-in-out duration-200`}
|
} absolute left-0 inline-block h-5 w-5 transform rounded-full border border-gray-200 bg-white shadow transition-transform duration-200 ease-in-out group-focus:border-blue-300 group-focus:ring`}
|
||||||
></span>
|
></span>
|
||||||
</span>
|
</span>
|
||||||
</th>
|
</th>
|
||||||
<th className="px-1 py-3 text-xs font-medium leading-4 tracking-wider text-left text-gray-200 uppercase bg-gray-500 md:px-6">
|
<th className="bg-gray-500 px-1 py-3 text-left text-xs font-medium uppercase leading-4 tracking-wider text-gray-200 md:px-6">
|
||||||
{intl.formatMessage(globalMessages.movie)}
|
{intl.formatMessage(globalMessages.movie)}
|
||||||
</th>
|
</th>
|
||||||
<th className="px-2 py-3 text-xs font-medium leading-4 tracking-wider text-left text-gray-200 uppercase bg-gray-500 md:px-6">
|
<th className="bg-gray-500 px-2 py-3 text-left text-xs font-medium uppercase leading-4 tracking-wider text-gray-200 md:px-6">
|
||||||
{intl.formatMessage(globalMessages.status)}
|
{intl.formatMessage(globalMessages.status)}
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody className="bg-gray-600 divide-y divide-gray-700">
|
<tbody className="divide-y divide-gray-700 bg-gray-600">
|
||||||
{data?.parts.map((part) => {
|
{data?.parts.map((part) => {
|
||||||
const partRequest = getPartRequest(part.id);
|
const partRequest = getPartRequest(part.id);
|
||||||
const partMedia =
|
const partMedia =
|
||||||
@@ -352,7 +352,7 @@ const CollectionRequestModal: React.FC<RequestModalProps> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<tr key={`part-${part.id}`}>
|
<tr key={`part-${part.id}`}>
|
||||||
<td className="px-4 py-4 text-sm font-medium leading-5 text-gray-100 whitespace-nowrap">
|
<td className="whitespace-nowrap px-4 py-4 text-sm font-medium leading-5 text-gray-100">
|
||||||
<span
|
<span
|
||||||
role="checkbox"
|
role="checkbox"
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
@@ -365,7 +365,7 @@ const CollectionRequestModal: React.FC<RequestModalProps> = ({
|
|||||||
togglePart(part.id);
|
togglePart(part.id);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
className={`pt-2 relative inline-flex items-center justify-center flex-shrink-0 h-5 w-10 cursor-pointer focus:outline-none ${
|
className={`relative inline-flex h-5 w-10 flex-shrink-0 cursor-pointer items-center justify-center pt-2 focus:outline-none ${
|
||||||
!!partMedia ||
|
!!partMedia ||
|
||||||
partRequest ||
|
partRequest ||
|
||||||
(quota?.movie.limit &&
|
(quota?.movie.limit &&
|
||||||
@@ -383,7 +383,7 @@ const CollectionRequestModal: React.FC<RequestModalProps> = ({
|
|||||||
isSelectedPart(part.id)
|
isSelectedPart(part.id)
|
||||||
? 'bg-indigo-500'
|
? 'bg-indigo-500'
|
||||||
: 'bg-gray-800'
|
: 'bg-gray-800'
|
||||||
} absolute h-4 w-9 mx-auto rounded-full transition-colors ease-in-out duration-200`}
|
} absolute mx-auto h-4 w-9 rounded-full transition-colors duration-200 ease-in-out`}
|
||||||
></span>
|
></span>
|
||||||
<span
|
<span
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@@ -393,12 +393,12 @@ const CollectionRequestModal: React.FC<RequestModalProps> = ({
|
|||||||
isSelectedPart(part.id)
|
isSelectedPart(part.id)
|
||||||
? 'translate-x-5'
|
? 'translate-x-5'
|
||||||
: 'translate-x-0'
|
: 'translate-x-0'
|
||||||
} absolute left-0 inline-block h-5 w-5 border border-gray-200 rounded-full bg-white shadow transform group-focus:ring group-focus:border-blue-300 transition-transform ease-in-out duration-200`}
|
} absolute left-0 inline-block h-5 w-5 transform rounded-full border border-gray-200 bg-white shadow transition-transform duration-200 ease-in-out group-focus:border-blue-300 group-focus:ring`}
|
||||||
></span>
|
></span>
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td className="flex items-center px-1 py-4 text-sm font-medium leading-5 text-gray-100 md:px-6">
|
<td className="flex items-center px-1 py-4 text-sm font-medium leading-5 text-gray-100 md:px-6">
|
||||||
<div className="relative flex-shrink-0 w-10 h-auto overflow-hidden rounded-md">
|
<div className="relative h-auto w-10 flex-shrink-0 overflow-hidden rounded-md">
|
||||||
<CachedImage
|
<CachedImage
|
||||||
src={
|
src={
|
||||||
part.posterPath
|
part.posterPath
|
||||||
@@ -421,7 +421,7 @@ const CollectionRequestModal: React.FC<RequestModalProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className="py-4 pr-2 text-sm leading-5 text-gray-200 md:px-6 whitespace-nowrap">
|
<td className="whitespace-nowrap py-4 pr-2 text-sm leading-5 text-gray-200 md:px-6">
|
||||||
{!partMedia && !partRequest && (
|
{!partMedia && !partRequest && (
|
||||||
<Badge>
|
<Badge>
|
||||||
{intl.formatMessage(globalMessages.notrequested)}
|
{intl.formatMessage(globalMessages.notrequested)}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ const QuotaDisplay: React.FC<QuotaDisplayProps> = ({
|
|||||||
const [showDetails, setShowDetails] = useState(false);
|
const [showDetails, setShowDetails] = useState(false);
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="flex flex-col p-4 my-4 bg-gray-800 rounded-md"
|
className="my-4 flex flex-col rounded-md bg-gray-800 p-4"
|
||||||
onClick={() => setShowDetails((s) => !s)}
|
onClick={() => setShowDetails((s) => !s)}
|
||||||
onKeyDown={(e) => {
|
onKeyDown={(e) => {
|
||||||
if (e.key === 'Enter') {
|
if (e.key === 'Enter') {
|
||||||
@@ -58,7 +58,7 @@ const QuotaDisplay: React.FC<QuotaDisplayProps> = ({
|
|||||||
>
|
>
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<ProgressCircle
|
<ProgressCircle
|
||||||
className="w-8 h-8"
|
className="h-8 w-8"
|
||||||
progress={Math.round(
|
progress={Math.round(
|
||||||
((remaining ?? quota?.remaining ?? 0) / (quota?.limit ?? 1)) * 100
|
((remaining ?? quota?.remaining ?? 0) / (quota?.limit ?? 1)) * 100
|
||||||
)}
|
)}
|
||||||
@@ -85,11 +85,11 @@ const QuotaDisplay: React.FC<QuotaDisplayProps> = ({
|
|||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-end flex-1">
|
<div className="flex flex-1 justify-end">
|
||||||
{showDetails ? (
|
{showDetails ? (
|
||||||
<ChevronUpIcon className="w-6 h-6" />
|
<ChevronUpIcon className="h-6 w-6" />
|
||||||
) : (
|
) : (
|
||||||
<ChevronDownIcon className="w-6 h-6" />
|
<ChevronDownIcon className="h-6 w-6" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -63,26 +63,26 @@ const SearchByNameModal: React.FC<SearchByNameModalProps> = ({
|
|||||||
{data?.slice(0, 6).map((item) => (
|
{data?.slice(0, 6).map((item) => (
|
||||||
<button
|
<button
|
||||||
key={item.tvdbId}
|
key={item.tvdbId}
|
||||||
className="container flex flex-col items-center justify-center h-40 mx-auto space-y-4 transition scale-100 outline-none cursor-pointer focus:ring focus:ring-indigo-500 focus:ring-opacity-70 focus:outline-none rounded-xl transform-gpu hover:scale-105"
|
className="container mx-auto flex h-40 scale-100 transform-gpu cursor-pointer flex-col items-center justify-center space-y-4 rounded-xl outline-none transition hover:scale-105 focus:outline-none focus:ring focus:ring-indigo-500 focus:ring-opacity-70"
|
||||||
onClick={() => handleClick(item.tvdbId)}
|
onClick={() => handleClick(item.tvdbId)}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={`bg-gray-600 h-40 overflow-hidden w-full flex items-center p-2 rounded-xl shadow transition ${
|
className={`flex h-40 w-full items-center overflow-hidden rounded-xl bg-gray-600 p-2 shadow transition ${
|
||||||
tvdbId === item.tvdbId ? 'ring ring-indigo-500' : ''
|
tvdbId === item.tvdbId ? 'ring ring-indigo-500' : ''
|
||||||
} `}
|
} `}
|
||||||
>
|
>
|
||||||
<div className="flex items-center flex-none w-24 space-x-4">
|
<div className="flex w-24 flex-none items-center space-x-4">
|
||||||
<img
|
<img
|
||||||
src={
|
src={
|
||||||
item.remotePoster ??
|
item.remotePoster ??
|
||||||
'/images/overseerr_poster_not_found.png'
|
'/images/overseerr_poster_not_found.png'
|
||||||
}
|
}
|
||||||
alt={item.title}
|
alt={item.title}
|
||||||
className="w-auto rounded-md h-100"
|
className="h-100 w-auto rounded-md"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="self-start flex-grow p-3 text-left">
|
<div className="flex-grow self-start p-3 text-left">
|
||||||
<div className="text-sm font-medium text-grey-200">
|
<div className="text-grey-200 text-sm font-medium">
|
||||||
{item.title}
|
{item.title}
|
||||||
</div>
|
</div>
|
||||||
<div className="h-24 overflow-hidden text-sm text-gray-400">
|
<div className="h-24 overflow-hidden text-sm text-gray-400">
|
||||||
|
|||||||
@@ -513,7 +513,7 @@ const TvRequestModal: React.FC<RequestModalProps> = ({
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th
|
<th
|
||||||
className={`w-16 px-4 py-3 bg-gray-500 ${
|
className={`w-16 bg-gray-500 px-4 py-3 ${
|
||||||
!settings.currentSettings.partialRequestsEnabled &&
|
!settings.currentSettings.partialRequestsEnabled &&
|
||||||
'hidden'
|
'hidden'
|
||||||
}`}
|
}`}
|
||||||
@@ -528,7 +528,7 @@ const TvRequestModal: React.FC<RequestModalProps> = ({
|
|||||||
toggleAllSeasons();
|
toggleAllSeasons();
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
className={`relative inline-flex items-center justify-center flex-shrink-0 w-10 h-5 pt-2 cursor-pointer focus:outline-none ${
|
className={`relative inline-flex h-5 w-10 flex-shrink-0 cursor-pointer items-center justify-center pt-2 focus:outline-none ${
|
||||||
quota?.tv.remaining &&
|
quota?.tv.remaining &&
|
||||||
quota.tv.limit &&
|
quota.tv.limit &&
|
||||||
quota.tv.remaining < unrequestedSeasons.length
|
quota.tv.remaining < unrequestedSeasons.length
|
||||||
@@ -540,28 +540,28 @@ const TvRequestModal: React.FC<RequestModalProps> = ({
|
|||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
className={`${
|
className={`${
|
||||||
isAllSeasons() ? 'bg-indigo-500' : 'bg-gray-800'
|
isAllSeasons() ? 'bg-indigo-500' : 'bg-gray-800'
|
||||||
} absolute h-4 w-9 mx-auto rounded-full transition-colors ease-in-out duration-200`}
|
} absolute mx-auto h-4 w-9 rounded-full transition-colors duration-200 ease-in-out`}
|
||||||
></span>
|
></span>
|
||||||
<span
|
<span
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
className={`${
|
className={`${
|
||||||
isAllSeasons() ? 'translate-x-5' : 'translate-x-0'
|
isAllSeasons() ? 'translate-x-5' : 'translate-x-0'
|
||||||
} absolute left-0 inline-block h-5 w-5 border border-gray-200 rounded-full bg-white shadow transform group-focus:ring group-focus:border-blue-300 transition-transform ease-in-out duration-200`}
|
} absolute left-0 inline-block h-5 w-5 transform rounded-full border border-gray-200 bg-white shadow transition-transform duration-200 ease-in-out group-focus:border-blue-300 group-focus:ring`}
|
||||||
></span>
|
></span>
|
||||||
</span>
|
</span>
|
||||||
</th>
|
</th>
|
||||||
<th className="px-1 py-3 text-xs font-medium leading-4 tracking-wider text-left text-gray-200 uppercase bg-gray-500 md:px-6">
|
<th className="bg-gray-500 px-1 py-3 text-left text-xs font-medium uppercase leading-4 tracking-wider text-gray-200 md:px-6">
|
||||||
{intl.formatMessage(messages.season)}
|
{intl.formatMessage(messages.season)}
|
||||||
</th>
|
</th>
|
||||||
<th className="px-5 py-3 text-xs font-medium leading-4 tracking-wider text-left text-gray-200 uppercase bg-gray-500 md:px-6">
|
<th className="bg-gray-500 px-5 py-3 text-left text-xs font-medium uppercase leading-4 tracking-wider text-gray-200 md:px-6">
|
||||||
{intl.formatMessage(messages.numberofepisodes)}
|
{intl.formatMessage(messages.numberofepisodes)}
|
||||||
</th>
|
</th>
|
||||||
<th className="px-2 py-3 text-xs font-medium leading-4 tracking-wider text-left text-gray-200 uppercase bg-gray-500 md:px-6">
|
<th className="bg-gray-500 px-2 py-3 text-left text-xs font-medium uppercase leading-4 tracking-wider text-gray-200 md:px-6">
|
||||||
{intl.formatMessage(globalMessages.status)}
|
{intl.formatMessage(globalMessages.status)}
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody className="bg-gray-600 divide-y divide-gray-700">
|
<tbody className="divide-y divide-gray-700 bg-gray-600">
|
||||||
{data?.seasons
|
{data?.seasons
|
||||||
.filter((season) => season.seasonNumber !== 0)
|
.filter((season) => season.seasonNumber !== 0)
|
||||||
.map((season) => {
|
.map((season) => {
|
||||||
@@ -577,7 +577,7 @@ const TvRequestModal: React.FC<RequestModalProps> = ({
|
|||||||
return (
|
return (
|
||||||
<tr key={`season-${season.id}`}>
|
<tr key={`season-${season.id}`}>
|
||||||
<td
|
<td
|
||||||
className={`px-4 py-4 text-sm font-medium leading-5 text-gray-100 whitespace-nowrap ${
|
className={`whitespace-nowrap px-4 py-4 text-sm font-medium leading-5 text-gray-100 ${
|
||||||
!settings.currentSettings
|
!settings.currentSettings
|
||||||
.partialRequestsEnabled && 'hidden'
|
.partialRequestsEnabled && 'hidden'
|
||||||
}`}
|
}`}
|
||||||
@@ -599,7 +599,7 @@ const TvRequestModal: React.FC<RequestModalProps> = ({
|
|||||||
toggleSeason(season.seasonNumber);
|
toggleSeason(season.seasonNumber);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
className={`pt-2 relative inline-flex items-center justify-center flex-shrink-0 h-5 w-10 cursor-pointer focus:outline-none ${
|
className={`relative inline-flex h-5 w-10 flex-shrink-0 cursor-pointer items-center justify-center pt-2 focus:outline-none ${
|
||||||
mediaSeason ||
|
mediaSeason ||
|
||||||
(quota?.tv.limit &&
|
(quota?.tv.limit &&
|
||||||
currentlyRemaining <= 0 &&
|
currentlyRemaining <= 0 &&
|
||||||
@@ -621,7 +621,7 @@ const TvRequestModal: React.FC<RequestModalProps> = ({
|
|||||||
isSelectedSeason(season.seasonNumber)
|
isSelectedSeason(season.seasonNumber)
|
||||||
? 'bg-indigo-500'
|
? 'bg-indigo-500'
|
||||||
: 'bg-gray-800'
|
: 'bg-gray-800'
|
||||||
} absolute h-4 w-9 mx-auto rounded-full transition-colors ease-in-out duration-200`}
|
} absolute mx-auto h-4 w-9 rounded-full transition-colors duration-200 ease-in-out`}
|
||||||
></span>
|
></span>
|
||||||
<span
|
<span
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@@ -634,21 +634,21 @@ const TvRequestModal: React.FC<RequestModalProps> = ({
|
|||||||
isSelectedSeason(season.seasonNumber)
|
isSelectedSeason(season.seasonNumber)
|
||||||
? 'translate-x-5'
|
? 'translate-x-5'
|
||||||
: 'translate-x-0'
|
: 'translate-x-0'
|
||||||
} absolute left-0 inline-block h-5 w-5 border border-gray-200 rounded-full bg-white shadow transform group-focus:ring group-focus:border-blue-300 transition-transform ease-in-out duration-200`}
|
} absolute left-0 inline-block h-5 w-5 transform rounded-full border border-gray-200 bg-white shadow transition-transform duration-200 ease-in-out group-focus:border-blue-300 group-focus:ring`}
|
||||||
></span>
|
></span>
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td className="px-1 py-4 text-sm font-medium leading-5 text-gray-100 md:px-6 whitespace-nowrap">
|
<td className="whitespace-nowrap px-1 py-4 text-sm font-medium leading-5 text-gray-100 md:px-6">
|
||||||
{season.seasonNumber === 0
|
{season.seasonNumber === 0
|
||||||
? intl.formatMessage(messages.extras)
|
? intl.formatMessage(messages.extras)
|
||||||
: intl.formatMessage(messages.seasonnumber, {
|
: intl.formatMessage(messages.seasonnumber, {
|
||||||
number: season.seasonNumber,
|
number: season.seasonNumber,
|
||||||
})}
|
})}
|
||||||
</td>
|
</td>
|
||||||
<td className="px-5 py-4 text-sm leading-5 text-gray-200 md:px-6 whitespace-nowrap">
|
<td className="whitespace-nowrap px-5 py-4 text-sm leading-5 text-gray-200 md:px-6">
|
||||||
{season.episodeCount}
|
{season.episodeCount}
|
||||||
</td>
|
</td>
|
||||||
<td className="py-4 pr-2 text-sm leading-5 text-gray-200 md:px-6 whitespace-nowrap">
|
<td className="whitespace-nowrap py-4 pr-2 text-sm leading-5 text-gray-200 md:px-6">
|
||||||
{!seasonRequest && !mediaSeason && (
|
{!seasonRequest && !mediaSeason && (
|
||||||
<Badge>
|
<Badge>
|
||||||
{intl.formatMessage(
|
{intl.formatMessage(
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ const ResetPassword: React.FC = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative flex flex-col min-h-screen bg-gray-900 py-14">
|
<div className="relative flex min-h-screen flex-col bg-gray-900 py-14">
|
||||||
<PageTitle title={intl.formatMessage(messages.passwordreset)} />
|
<PageTitle title={intl.formatMessage(messages.passwordreset)} />
|
||||||
<ImageFader
|
<ImageFader
|
||||||
forceOptimize
|
forceOptimize
|
||||||
@@ -45,12 +45,12 @@ const ResetPassword: React.FC = () => {
|
|||||||
'/images/rotate6.jpg',
|
'/images/rotate6.jpg',
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<div className="absolute z-50 top-4 right-4">
|
<div className="absolute top-4 right-4 z-50">
|
||||||
<LanguagePicker />
|
<LanguagePicker />
|
||||||
</div>
|
</div>
|
||||||
<div className="relative z-40 flex flex-col items-center px-4 mt-10 sm:mx-auto sm:w-full sm:max-w-md">
|
<div className="relative z-40 mt-10 flex flex-col items-center px-4 sm:mx-auto sm:w-full sm:max-w-md">
|
||||||
<img src="/logo_stacked.svg" className="max-w-full mb-10" alt="Logo" />
|
<img src="/logo_stacked.svg" className="mb-10 max-w-full" alt="Logo" />
|
||||||
<h2 className="mt-2 text-3xl font-extrabold leading-9 text-center text-gray-100">
|
<h2 className="mt-2 text-center text-3xl font-extrabold leading-9 text-gray-100">
|
||||||
{intl.formatMessage(messages.resetpassword)}
|
{intl.formatMessage(messages.resetpassword)}
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
@@ -62,10 +62,10 @@ const ResetPassword: React.FC = () => {
|
|||||||
<div className="px-10 py-8">
|
<div className="px-10 py-8">
|
||||||
{hasSubmitted ? (
|
{hasSubmitted ? (
|
||||||
<>
|
<>
|
||||||
<p className="text-gray-300 text-md">
|
<p className="text-md text-gray-300">
|
||||||
{intl.formatMessage(messages.requestresetlinksuccessmessage)}
|
{intl.formatMessage(messages.requestresetlinksuccessmessage)}
|
||||||
</p>
|
</p>
|
||||||
<span className="flex justify-center mt-4 rounded-md shadow-sm">
|
<span className="mt-4 flex justify-center rounded-md shadow-sm">
|
||||||
<Link href="/login" passHref>
|
<Link href="/login" passHref>
|
||||||
<Button as="a" buttonType="ghost">
|
<Button as="a" buttonType="ghost">
|
||||||
<ArrowLeftIcon />
|
<ArrowLeftIcon />
|
||||||
@@ -99,18 +99,18 @@ const ResetPassword: React.FC = () => {
|
|||||||
<div>
|
<div>
|
||||||
<label
|
<label
|
||||||
htmlFor="email"
|
htmlFor="email"
|
||||||
className="block my-1 text-sm font-medium leading-5 text-gray-400 sm:mt-px"
|
className="my-1 block text-sm font-medium leading-5 text-gray-400 sm:mt-px"
|
||||||
>
|
>
|
||||||
{intl.formatMessage(messages.email)}
|
{intl.formatMessage(messages.email)}
|
||||||
</label>
|
</label>
|
||||||
<div className="mt-1 mb-2 sm:mt-0 sm:col-span-2">
|
<div className="mt-1 mb-2 sm:col-span-2 sm:mt-0">
|
||||||
<div className="form-input-field">
|
<div className="form-input-field">
|
||||||
<Field
|
<Field
|
||||||
id="email"
|
id="email"
|
||||||
name="email"
|
name="email"
|
||||||
type="text"
|
type="text"
|
||||||
inputMode="email"
|
inputMode="email"
|
||||||
className="flex-1 block w-full min-w-0 text-white transition duration-150 ease-in-out bg-gray-700 border border-gray-500 rounded-md form-input sm:text-sm sm:leading-5"
|
className="form-input block w-full min-w-0 flex-1 rounded-md border border-gray-500 bg-gray-700 text-white transition duration-150 ease-in-out sm:text-sm sm:leading-5"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{errors.email && touched.email && (
|
{errors.email && touched.email && (
|
||||||
@@ -118,7 +118,7 @@ const ResetPassword: React.FC = () => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="pt-5 mt-4 border-t border-gray-700">
|
<div className="mt-4 border-t border-gray-700 pt-5">
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<span className="inline-flex rounded-md shadow-sm">
|
<span className="inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ const ResetPassword: React.FC = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative flex flex-col min-h-screen bg-gray-900 py-14">
|
<div className="relative flex min-h-screen flex-col bg-gray-900 py-14">
|
||||||
<ImageFader
|
<ImageFader
|
||||||
forceOptimize
|
forceOptimize
|
||||||
backgroundImages={[
|
backgroundImages={[
|
||||||
@@ -60,12 +60,12 @@ const ResetPassword: React.FC = () => {
|
|||||||
'/images/rotate6.jpg',
|
'/images/rotate6.jpg',
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<div className="absolute z-50 top-4 right-4">
|
<div className="absolute top-4 right-4 z-50">
|
||||||
<LanguagePicker />
|
<LanguagePicker />
|
||||||
</div>
|
</div>
|
||||||
<div className="relative z-40 flex flex-col items-center px-4 mt-10 sm:mx-auto sm:w-full sm:max-w-md">
|
<div className="relative z-40 mt-10 flex flex-col items-center px-4 sm:mx-auto sm:w-full sm:max-w-md">
|
||||||
<img src="/logo_stacked.svg" className="max-w-full mb-10" alt="Logo" />
|
<img src="/logo_stacked.svg" className="mb-10 max-w-full" alt="Logo" />
|
||||||
<h2 className="mt-2 text-3xl font-extrabold leading-9 text-center text-gray-100">
|
<h2 className="mt-2 text-center text-3xl font-extrabold leading-9 text-gray-100">
|
||||||
{intl.formatMessage(messages.resetpassword)}
|
{intl.formatMessage(messages.resetpassword)}
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
@@ -77,10 +77,10 @@ const ResetPassword: React.FC = () => {
|
|||||||
<div className="px-10 py-8">
|
<div className="px-10 py-8">
|
||||||
{hasSubmitted ? (
|
{hasSubmitted ? (
|
||||||
<>
|
<>
|
||||||
<p className="text-gray-300 text-md">
|
<p className="text-md text-gray-300">
|
||||||
{intl.formatMessage(messages.resetpasswordsuccessmessage)}
|
{intl.formatMessage(messages.resetpasswordsuccessmessage)}
|
||||||
</p>
|
</p>
|
||||||
<span className="flex justify-center mt-4 rounded-md shadow-sm">
|
<span className="mt-4 flex justify-center rounded-md shadow-sm">
|
||||||
<Link href="/login" passHref>
|
<Link href="/login" passHref>
|
||||||
<Button as="a" buttonType="ghost">
|
<Button as="a" buttonType="ghost">
|
||||||
{intl.formatMessage(messages.gobacklogin)}
|
{intl.formatMessage(messages.gobacklogin)}
|
||||||
@@ -114,11 +114,11 @@ const ResetPassword: React.FC = () => {
|
|||||||
<div>
|
<div>
|
||||||
<label
|
<label
|
||||||
htmlFor="password"
|
htmlFor="password"
|
||||||
className="block my-1 text-sm font-medium leading-5 text-gray-400 sm:mt-px"
|
className="my-1 block text-sm font-medium leading-5 text-gray-400 sm:mt-px"
|
||||||
>
|
>
|
||||||
{intl.formatMessage(messages.password)}
|
{intl.formatMessage(messages.password)}
|
||||||
</label>
|
</label>
|
||||||
<div className="mt-1 mb-2 sm:mt-0 sm:col-span-2">
|
<div className="mt-1 mb-2 sm:col-span-2 sm:mt-0">
|
||||||
<div className="form-input-field">
|
<div className="form-input-field">
|
||||||
<SensitiveInput
|
<SensitiveInput
|
||||||
as="field"
|
as="field"
|
||||||
@@ -126,7 +126,7 @@ const ResetPassword: React.FC = () => {
|
|||||||
name="password"
|
name="password"
|
||||||
type="password"
|
type="password"
|
||||||
autoComplete="new-password"
|
autoComplete="new-password"
|
||||||
className="flex-1 block w-full min-w-0 text-white transition duration-150 ease-in-out bg-gray-700 border border-gray-500 rounded-md form-input sm:text-sm sm:leading-5"
|
className="form-input block w-full min-w-0 flex-1 rounded-md border border-gray-500 bg-gray-700 text-white transition duration-150 ease-in-out sm:text-sm sm:leading-5"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{errors.password && touched.password && (
|
{errors.password && touched.password && (
|
||||||
@@ -135,11 +135,11 @@ const ResetPassword: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
<label
|
<label
|
||||||
htmlFor="confirmPassword"
|
htmlFor="confirmPassword"
|
||||||
className="block my-1 text-sm font-medium leading-5 text-gray-400 sm:mt-px"
|
className="my-1 block text-sm font-medium leading-5 text-gray-400 sm:mt-px"
|
||||||
>
|
>
|
||||||
{intl.formatMessage(messages.confirmpassword)}
|
{intl.formatMessage(messages.confirmpassword)}
|
||||||
</label>
|
</label>
|
||||||
<div className="mt-1 mb-2 sm:mt-0 sm:col-span-2">
|
<div className="mt-1 mb-2 sm:col-span-2 sm:mt-0">
|
||||||
<div className="form-input-field">
|
<div className="form-input-field">
|
||||||
<SensitiveInput
|
<SensitiveInput
|
||||||
as="field"
|
as="field"
|
||||||
@@ -147,7 +147,7 @@ const ResetPassword: React.FC = () => {
|
|||||||
name="confirmPassword"
|
name="confirmPassword"
|
||||||
type="password"
|
type="password"
|
||||||
autoComplete="new-password"
|
autoComplete="new-password"
|
||||||
className="flex-1 block w-full min-w-0 text-white transition duration-150 ease-in-out bg-gray-700 border border-gray-500 rounded-md form-input sm:text-sm sm:leading-5"
|
className="form-input block w-full min-w-0 flex-1 rounded-md border border-gray-500 bg-gray-700 text-white transition duration-150 ease-in-out sm:text-sm sm:leading-5"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{errors.confirmPassword &&
|
{errors.confirmPassword &&
|
||||||
@@ -158,7 +158,7 @@ const ResetPassword: React.FC = () => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="pt-5 mt-4 border-t border-gray-700">
|
<div className="mt-4 border-t border-gray-700 pt-5">
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<span className="inline-flex rounded-md shadow-sm">
|
<span className="inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ const LibraryItem: React.FC<LibraryItemProps> = ({
|
|||||||
onToggle,
|
onToggle,
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<li className="flex col-span-1 rounded-md shadow-sm">
|
<li className="col-span-1 flex rounded-md shadow-sm">
|
||||||
<div className="flex items-center justify-between flex-1 truncate bg-gray-600 border-t border-b border-r border-gray-700 rounded-md">
|
<div className="flex flex-1 items-center justify-between truncate rounded-md border-t border-b border-r border-gray-700 bg-gray-600">
|
||||||
<div className="flex-1 px-4 py-6 text-sm leading-5 truncate cursor-default">
|
<div className="flex-1 cursor-default truncate px-4 py-6 text-sm leading-5">
|
||||||
{name}
|
{name}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-shrink-0 pr-2">
|
<div className="flex-shrink-0 pr-2">
|
||||||
@@ -31,31 +31,31 @@ const LibraryItem: React.FC<LibraryItemProps> = ({
|
|||||||
}}
|
}}
|
||||||
className={`${
|
className={`${
|
||||||
isEnabled ? 'bg-indigo-600' : 'bg-gray-700'
|
isEnabled ? 'bg-indigo-600' : 'bg-gray-700'
|
||||||
} relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:ring`}
|
} relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring`}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
className={`${
|
className={`${
|
||||||
isEnabled ? 'translate-x-5' : 'translate-x-0'
|
isEnabled ? 'translate-x-5' : 'translate-x-0'
|
||||||
} relative inline-block h-5 w-5 rounded-full bg-white shadow transform transition ease-in-out duration-200`}
|
} relative inline-block h-5 w-5 transform rounded-full bg-white shadow transition duration-200 ease-in-out`}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className={`${
|
className={`${
|
||||||
isEnabled
|
isEnabled
|
||||||
? 'opacity-0 ease-out duration-100'
|
? 'opacity-0 duration-100 ease-out'
|
||||||
: 'opacity-100 ease-in duration-200'
|
: 'opacity-100 duration-200 ease-in'
|
||||||
} absolute inset-0 h-full w-full flex items-center justify-center transition-opacity`}
|
} absolute inset-0 flex h-full w-full items-center justify-center transition-opacity`}
|
||||||
>
|
>
|
||||||
<XIcon className="w-3 h-3 text-gray-400" />
|
<XIcon className="h-3 w-3 text-gray-400" />
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
className={`${
|
className={`${
|
||||||
isEnabled
|
isEnabled
|
||||||
? 'opacity-100 ease-in duration-200'
|
? 'opacity-100 duration-200 ease-in'
|
||||||
: 'opacity-0 ease-out duration-100'
|
: 'opacity-0 duration-100 ease-out'
|
||||||
} absolute inset-0 h-full w-full flex items-center justify-center transition-opacity`}
|
} absolute inset-0 flex h-full w-full items-center justify-center transition-opacity`}
|
||||||
>
|
>
|
||||||
<CheckIcon className="w-3 h-3 text-indigo-600" />
|
<CheckIcon className="h-3 w-3 text-indigo-600" />
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -263,7 +263,7 @@ const NotificationsDiscord: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="warning"
|
buttonType="warning"
|
||||||
disabled={isSubmitting || !isValid || isTesting}
|
disabled={isSubmitting || !isValid || isTesting}
|
||||||
@@ -280,7 +280,7 @@ const NotificationsDiscord: React.FC = () => {
|
|||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
</span>
|
</span>
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
type="submit"
|
type="submit"
|
||||||
|
|||||||
@@ -431,7 +431,7 @@ const NotificationsEmail: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="warning"
|
buttonType="warning"
|
||||||
disabled={isSubmitting || !isValid || isTesting}
|
disabled={isSubmitting || !isValid || isTesting}
|
||||||
@@ -448,7 +448,7 @@ const NotificationsEmail: React.FC = () => {
|
|||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
</span>
|
</span>
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
type="submit"
|
type="submit"
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ const NotificationsGotify: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="warning"
|
buttonType="warning"
|
||||||
disabled={isSubmitting || !isValid || isTesting}
|
disabled={isSubmitting || !isValid || isTesting}
|
||||||
@@ -227,7 +227,7 @@ const NotificationsGotify: React.FC = () => {
|
|||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
</span>
|
</span>
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
type="submit"
|
type="submit"
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ const NotificationsLunaSea: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="warning"
|
buttonType="warning"
|
||||||
disabled={isSubmitting || !isValid || isTesting}
|
disabled={isSubmitting || !isValid || isTesting}
|
||||||
@@ -236,7 +236,7 @@ const NotificationsLunaSea: React.FC = () => {
|
|||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
</span>
|
</span>
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
type="submit"
|
type="submit"
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ const NotificationsPushbullet: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="warning"
|
buttonType="warning"
|
||||||
disabled={isSubmitting || !isValid || isTesting}
|
disabled={isSubmitting || !isValid || isTesting}
|
||||||
@@ -230,7 +230,7 @@ const NotificationsPushbullet: React.FC = () => {
|
|||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
</span>
|
</span>
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
type="submit"
|
type="submit"
|
||||||
|
|||||||
@@ -245,7 +245,7 @@ const NotificationsPushover: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="warning"
|
buttonType="warning"
|
||||||
disabled={isSubmitting || !isValid || isTesting}
|
disabled={isSubmitting || !isValid || isTesting}
|
||||||
@@ -262,7 +262,7 @@ const NotificationsPushover: React.FC = () => {
|
|||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
</span>
|
</span>
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
type="submit"
|
type="submit"
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ const NotificationsSlack: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="warning"
|
buttonType="warning"
|
||||||
disabled={isSubmitting || !isValid || isTesting}
|
disabled={isSubmitting || !isValid || isTesting}
|
||||||
@@ -214,7 +214,7 @@ const NotificationsSlack: React.FC = () => {
|
|||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
</span>
|
</span>
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
type="submit"
|
type="submit"
|
||||||
|
|||||||
@@ -300,7 +300,7 @@ const NotificationsTelegram: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="warning"
|
buttonType="warning"
|
||||||
disabled={isSubmitting || !isValid || isTesting}
|
disabled={isSubmitting || !isValid || isTesting}
|
||||||
@@ -317,7 +317,7 @@ const NotificationsTelegram: React.FC = () => {
|
|||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
</span>
|
</span>
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
type="submit"
|
type="submit"
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ const NotificationsWebPush: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="warning"
|
buttonType="warning"
|
||||||
disabled={isSubmitting || isTesting}
|
disabled={isSubmitting || isTesting}
|
||||||
@@ -143,7 +143,7 @@ const NotificationsWebPush: React.FC = () => {
|
|||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
</span>
|
</span>
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
type="submit"
|
type="submit"
|
||||||
|
|||||||
@@ -325,7 +325,7 @@ const NotificationsWebhook: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="warning"
|
buttonType="warning"
|
||||||
disabled={isSubmitting || !isValid || isTesting}
|
disabled={isSubmitting || !isValid || isTesting}
|
||||||
@@ -342,7 +342,7 @@ const NotificationsWebhook: React.FC = () => {
|
|||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
</span>
|
</span>
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
type="submit"
|
type="submit"
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ const Release: React.FC<ReleaseProps> = ({
|
|||||||
const [isModalOpen, setModalOpen] = useState(false);
|
const [isModalOpen, setModalOpen] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col w-full px-4 py-2 space-y-3 bg-gray-800 rounded-md shadow-md sm:space-y-0 sm:space-x-3 sm:flex-row ring-1 ring-gray-700">
|
<div className="flex w-full flex-col space-y-3 rounded-md bg-gray-800 px-4 py-2 shadow-md ring-1 ring-gray-700 sm:flex-row sm:space-y-0 sm:space-x-3">
|
||||||
<Transition
|
<Transition
|
||||||
enter="opacity-0 transition duration-300"
|
enter="opacity-0 transition duration-300"
|
||||||
enterFrom="opacity-0"
|
enterFrom="opacity-0"
|
||||||
@@ -84,9 +84,9 @@ const Release: React.FC<ReleaseProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
</Transition>
|
</Transition>
|
||||||
<div className="flex items-center justify-center flex-grow w-full space-x-2 truncate sm:justify-start">
|
<div className="flex w-full flex-grow items-center justify-center space-x-2 truncate sm:justify-start">
|
||||||
<span className="text-lg font-bold truncate">
|
<span className="truncate text-lg font-bold">
|
||||||
<span className="mr-2 text-xs font-normal whitespace-nowrap">
|
<span className="mr-2 whitespace-nowrap text-xs font-normal">
|
||||||
<FormattedRelativeTime
|
<FormattedRelativeTime
|
||||||
value={Math.floor(
|
value={Math.floor(
|
||||||
(new Date(release.created_at).getTime() - Date.now()) / 1000
|
(new Date(release.created_at).getTime() - Date.now()) / 1000
|
||||||
@@ -139,7 +139,7 @@ const Releases: React.FC<ReleasesProps> = ({ currentVersion }) => {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h3 className="heading">{intl.formatMessage(messages.releases)}</h3>
|
<h3 className="heading">{intl.formatMessage(messages.releases)}</h3>
|
||||||
<div className="space-y-3 section">
|
<div className="section space-y-3">
|
||||||
{data.map((release, index) => {
|
{data.map((release, index) => {
|
||||||
return (
|
return (
|
||||||
<div key={`release-${release.id}`}>
|
<div key={`release-${release.id}`}>
|
||||||
|
|||||||
@@ -60,19 +60,19 @@ const SettingsAbout: React.FC = () => {
|
|||||||
intl.formatMessage(globalMessages.settings),
|
intl.formatMessage(globalMessages.settings),
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<div className="p-4 mt-6 bg-indigo-700 rounded-md">
|
<div className="mt-6 rounded-md bg-indigo-700 p-4">
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
<div className="flex-shrink-0">
|
<div className="flex-shrink-0">
|
||||||
<InformationCircleIcon className="w-5 h-5 text-white" />
|
<InformationCircleIcon className="h-5 w-5 text-white" />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-1 ml-3 md:flex md:justify-between">
|
<div className="ml-3 flex-1 md:flex md:justify-between">
|
||||||
<p className="text-sm leading-5 text-white">
|
<p className="text-sm leading-5 text-white">
|
||||||
{intl.formatMessage(messages.betawarning)}
|
{intl.formatMessage(messages.betawarning)}
|
||||||
</p>
|
</p>
|
||||||
<p className="mt-3 text-sm leading-5 md:mt-0 md:ml-6">
|
<p className="mt-3 text-sm leading-5 md:mt-0 md:ml-6">
|
||||||
<a
|
<a
|
||||||
href="http://github.com/sct/overseerr"
|
href="http://github.com/sct/overseerr"
|
||||||
className="font-medium text-indigo-100 transition duration-150 ease-in-out whitespace-nowrap hover:text-white"
|
className="whitespace-nowrap font-medium text-indigo-100 transition duration-150 ease-in-out hover:text-white"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
>
|
>
|
||||||
@@ -113,7 +113,7 @@ const SettingsAbout: React.FC = () => {
|
|||||||
>
|
>
|
||||||
<Badge
|
<Badge
|
||||||
badgeType="warning"
|
badgeType="warning"
|
||||||
className="ml-2 transition !cursor-pointer hover:bg-yellow-400"
|
className="ml-2 !cursor-pointer transition hover:bg-yellow-400"
|
||||||
>
|
>
|
||||||
{intl.formatMessage(messages.outofdate)}
|
{intl.formatMessage(messages.outofdate)}
|
||||||
</Badge>
|
</Badge>
|
||||||
@@ -130,7 +130,7 @@ const SettingsAbout: React.FC = () => {
|
|||||||
>
|
>
|
||||||
<Badge
|
<Badge
|
||||||
badgeType="success"
|
badgeType="success"
|
||||||
className="ml-2 transition !cursor-pointer hover:bg-green-400"
|
className="ml-2 !cursor-pointer transition hover:bg-green-400"
|
||||||
>
|
>
|
||||||
{intl.formatMessage(messages.uptodate)}
|
{intl.formatMessage(messages.uptodate)}
|
||||||
</Badge>
|
</Badge>
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ const SettingsJobs: React.FC = () => {
|
|||||||
>
|
>
|
||||||
<div className="section">
|
<div className="section">
|
||||||
<form>
|
<form>
|
||||||
<div className="pb-6 form-row">
|
<div className="form-row pb-6">
|
||||||
<label htmlFor="jobSchedule" className="text-label">
|
<label htmlFor="jobSchedule" className="text-label">
|
||||||
{intl.formatMessage(messages.editJobSchedulePrompt)}
|
{intl.formatMessage(messages.editJobSchedulePrompt)}
|
||||||
</label>
|
</label>
|
||||||
@@ -291,7 +291,7 @@ const SettingsJobs: React.FC = () => {
|
|||||||
messages[job.id] ?? messages.unknownJob
|
messages[job.id] ?? messages.unknownJob
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
{job.running && <Spinner className="w-5 h-5 ml-2" />}
|
{job.running && <Spinner className="ml-2 h-5 w-5" />}
|
||||||
</div>
|
</div>
|
||||||
</Table.TD>
|
</Table.TD>
|
||||||
<Table.TD>
|
<Table.TD>
|
||||||
@@ -337,7 +337,7 @@ const SettingsJobs: React.FC = () => {
|
|||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<Button buttonType="primary" onClick={() => runJob(job)}>
|
<Button buttonType="primary" onClick={() => runJob(job)}>
|
||||||
<PlayIcon className="w-5 h-5 mr-1" />
|
<PlayIcon className="mr-1 h-5 w-5" />
|
||||||
<span>{intl.formatMessage(messages.runnow)}</span>
|
<span>{intl.formatMessage(messages.runnow)}</span>
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ const SettingsLogs: React.FC = () => {
|
|||||||
{intl.formatMessage(messages.time)}
|
{intl.formatMessage(messages.time)}
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-1 text-sm font-medium leading-5 text-gray-400 sm:mt-2">
|
<div className="mb-1 text-sm font-medium leading-5 text-gray-400 sm:mt-2">
|
||||||
<div className="flex items-center max-w-lg">
|
<div className="flex max-w-lg items-center">
|
||||||
{intl.formatDate(activeLog.timestamp, {
|
{intl.formatDate(activeLog.timestamp, {
|
||||||
year: 'numeric',
|
year: 'numeric',
|
||||||
month: 'short',
|
month: 'short',
|
||||||
@@ -175,7 +175,7 @@ const SettingsLogs: React.FC = () => {
|
|||||||
{intl.formatMessage(messages.level)}
|
{intl.formatMessage(messages.level)}
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-1 text-sm font-medium leading-5 text-gray-400 sm:mt-2">
|
<div className="mb-1 text-sm font-medium leading-5 text-gray-400 sm:mt-2">
|
||||||
<div className="flex items-center max-w-lg">
|
<div className="flex max-w-lg items-center">
|
||||||
<Badge
|
<Badge
|
||||||
badgeType={
|
badgeType={
|
||||||
activeLog.level === 'error'
|
activeLog.level === 'error'
|
||||||
@@ -197,7 +197,7 @@ const SettingsLogs: React.FC = () => {
|
|||||||
{intl.formatMessage(messages.label)}
|
{intl.formatMessage(messages.label)}
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-1 text-sm font-medium leading-5 text-gray-400 sm:mt-2">
|
<div className="mb-1 text-sm font-medium leading-5 text-gray-400 sm:mt-2">
|
||||||
<div className="flex items-center max-w-lg">
|
<div className="flex max-w-lg items-center">
|
||||||
{activeLog.label}
|
{activeLog.label}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -207,7 +207,7 @@ const SettingsLogs: React.FC = () => {
|
|||||||
{intl.formatMessage(messages.message)}
|
{intl.formatMessage(messages.message)}
|
||||||
</div>
|
</div>
|
||||||
<div className="col-span-2 mb-1 text-sm font-medium leading-5 text-gray-400 sm:mt-2">
|
<div className="col-span-2 mb-1 text-sm font-medium leading-5 text-gray-400 sm:mt-2">
|
||||||
<div className="flex items-center max-w-lg">
|
<div className="flex max-w-lg items-center">
|
||||||
{activeLog.message}
|
{activeLog.message}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -218,7 +218,7 @@ const SettingsLogs: React.FC = () => {
|
|||||||
{intl.formatMessage(messages.extraData)}
|
{intl.formatMessage(messages.extraData)}
|
||||||
</div>
|
</div>
|
||||||
<div className="col-span-2 mb-1 text-sm font-medium leading-5 text-gray-400 sm:mt-2">
|
<div className="col-span-2 mb-1 text-sm font-medium leading-5 text-gray-400 sm:mt-2">
|
||||||
<code className="block w-full px-6 py-4 overflow-auto whitespace-pre bg-gray-800 ring-1 ring-gray-700 max-h-64">
|
<code className="block max-h-64 w-full overflow-auto whitespace-pre bg-gray-800 px-6 py-4 ring-1 ring-gray-700">
|
||||||
{JSON.stringify(activeLog.data, null, ' ')}
|
{JSON.stringify(activeLog.data, null, ' ')}
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
@@ -238,10 +238,10 @@ const SettingsLogs: React.FC = () => {
|
|||||||
configDir: appData ? appData.appDataPath : '/app/config',
|
configDir: appData ? appData.appDataPath : '/app/config',
|
||||||
})}
|
})}
|
||||||
</p>
|
</p>
|
||||||
<div className="flex flex-row flex-grow mt-2 sm:flex-grow-0 sm:justify-end">
|
<div className="mt-2 flex flex-grow flex-row sm:flex-grow-0 sm:justify-end">
|
||||||
<div className="flex flex-row justify-between flex-1 mb-2 sm:mb-0 sm:flex-none">
|
<div className="mb-2 flex flex-1 flex-row justify-between sm:mb-0 sm:flex-none">
|
||||||
<Button
|
<Button
|
||||||
className="flex-grow w-full mr-2"
|
className="mr-2 w-full flex-grow"
|
||||||
buttonType={refreshInterval ? 'default' : 'primary'}
|
buttonType={refreshInterval ? 'default' : 'primary'}
|
||||||
onClick={() => toggleLogs()}
|
onClick={() => toggleLogs()}
|
||||||
>
|
>
|
||||||
@@ -253,9 +253,9 @@ const SettingsLogs: React.FC = () => {
|
|||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-1 mb-2 sm:mb-0 sm:flex-none">
|
<div className="mb-2 flex flex-1 sm:mb-0 sm:flex-none">
|
||||||
<span className="inline-flex items-center px-3 text-sm text-gray-100 bg-gray-800 border border-r-0 border-gray-500 cursor-default rounded-l-md">
|
<span className="inline-flex cursor-default items-center rounded-l-md border border-r-0 border-gray-500 bg-gray-800 px-3 text-sm text-gray-100">
|
||||||
<FilterIcon className="w-6 h-6" />
|
<FilterIcon className="h-6 w-6" />
|
||||||
</span>
|
</span>
|
||||||
<select
|
<select
|
||||||
id="filter"
|
id="filter"
|
||||||
@@ -325,7 +325,7 @@ const SettingsLogs: React.FC = () => {
|
|||||||
{row.label ?? ''}
|
{row.label ?? ''}
|
||||||
</Table.TD>
|
</Table.TD>
|
||||||
<Table.TD className="text-gray-300">{row.message}</Table.TD>
|
<Table.TD className="text-gray-300">{row.message}</Table.TD>
|
||||||
<Table.TD className="flex flex-wrap items-center justify-end -m-1">
|
<Table.TD className="-m-1 flex flex-wrap items-center justify-end">
|
||||||
{row.data && (
|
{row.data && (
|
||||||
<Button
|
<Button
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
@@ -352,7 +352,7 @@ const SettingsLogs: React.FC = () => {
|
|||||||
{data.results.length === 0 && (
|
{data.results.length === 0 && (
|
||||||
<tr className="relative h-24 p-2 text-white">
|
<tr className="relative h-24 p-2 text-white">
|
||||||
<Table.TD colSpan={5} noPadding>
|
<Table.TD colSpan={5} noPadding>
|
||||||
<div className="flex flex-col items-center justify-center w-screen p-6 md:w-full">
|
<div className="flex w-screen flex-col items-center justify-center p-6 md:w-full">
|
||||||
<span className="text-base">
|
<span className="text-base">
|
||||||
{intl.formatMessage(globalMessages.noresults)}
|
{intl.formatMessage(globalMessages.noresults)}
|
||||||
</span>
|
</span>
|
||||||
@@ -374,7 +374,7 @@ const SettingsLogs: React.FC = () => {
|
|||||||
<tr className="bg-gray-700">
|
<tr className="bg-gray-700">
|
||||||
<Table.TD colSpan={5} noPadding>
|
<Table.TD colSpan={5} noPadding>
|
||||||
<nav
|
<nav
|
||||||
className="flex flex-col items-center w-screen px-6 py-3 space-x-4 space-y-3 sm:space-y-0 sm:flex-row md:w-full"
|
className="flex w-screen flex-col items-center space-x-4 space-y-3 px-6 py-3 sm:flex-row sm:space-y-0 md:w-full"
|
||||||
aria-label="Pagination"
|
aria-label="Pagination"
|
||||||
>
|
>
|
||||||
<div className="hidden lg:flex lg:flex-1">
|
<div className="hidden lg:flex lg:flex-1">
|
||||||
@@ -395,7 +395,7 @@ const SettingsLogs: React.FC = () => {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-center sm:flex-1 sm:justify-start md:justify-center">
|
<div className="flex justify-center sm:flex-1 sm:justify-start md:justify-center">
|
||||||
<span className="items-center -mt-3 text-sm sm:-ml-4 md:ml-0 sm:mt-0">
|
<span className="-mt-3 items-center text-sm sm:-ml-4 sm:mt-0 md:ml-0">
|
||||||
{intl.formatMessage(globalMessages.resultsperpage, {
|
{intl.formatMessage(globalMessages.resultsperpage, {
|
||||||
pageSize: (
|
pageSize: (
|
||||||
<select
|
<select
|
||||||
@@ -408,7 +408,7 @@ const SettingsLogs: React.FC = () => {
|
|||||||
.then(() => window.scrollTo(0, 0));
|
.then(() => window.scrollTo(0, 0));
|
||||||
}}
|
}}
|
||||||
value={currentPageSize}
|
value={currentPageSize}
|
||||||
className="inline short"
|
className="short inline"
|
||||||
>
|
>
|
||||||
<option value="10">10</option>
|
<option value="10">10</option>
|
||||||
<option value="25">25</option>
|
<option value="25">25</option>
|
||||||
@@ -419,7 +419,7 @@ const SettingsLogs: React.FC = () => {
|
|||||||
})}
|
})}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-center flex-auto space-x-2 sm:justify-end sm:flex-1">
|
<div className="flex flex-auto justify-center space-x-2 sm:flex-1 sm:justify-end">
|
||||||
<Button
|
<Button
|
||||||
disabled={!hasPrevPage}
|
disabled={!hasPrevPage}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
|
|||||||
@@ -398,7 +398,7 @@ const SettingsMain: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
type="submit"
|
type="submit"
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ const SettingsNotifications: React.FC = ({ children }) => {
|
|||||||
text: intl.formatMessage(messages.email),
|
text: intl.formatMessage(messages.email),
|
||||||
content: (
|
content: (
|
||||||
<span className="flex items-center">
|
<span className="flex items-center">
|
||||||
<MailIcon className="h-4 mr-2" />
|
<MailIcon className="mr-2 h-4" />
|
||||||
{intl.formatMessage(messages.email)}
|
{intl.formatMessage(messages.email)}
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
@@ -41,7 +41,7 @@ const SettingsNotifications: React.FC = ({ children }) => {
|
|||||||
text: intl.formatMessage(messages.webpush),
|
text: intl.formatMessage(messages.webpush),
|
||||||
content: (
|
content: (
|
||||||
<span className="flex items-center">
|
<span className="flex items-center">
|
||||||
<CloudIcon className="h-4 mr-2" />
|
<CloudIcon className="mr-2 h-4" />
|
||||||
{intl.formatMessage(messages.webpush)}
|
{intl.formatMessage(messages.webpush)}
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
@@ -52,7 +52,7 @@ const SettingsNotifications: React.FC = ({ children }) => {
|
|||||||
text: 'Discord',
|
text: 'Discord',
|
||||||
content: (
|
content: (
|
||||||
<span className="flex items-center">
|
<span className="flex items-center">
|
||||||
<DiscordLogo className="h-4 mr-2" />
|
<DiscordLogo className="mr-2 h-4" />
|
||||||
Discord
|
Discord
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
@@ -63,7 +63,7 @@ const SettingsNotifications: React.FC = ({ children }) => {
|
|||||||
text: 'Gotify',
|
text: 'Gotify',
|
||||||
content: (
|
content: (
|
||||||
<span className="flex items-center">
|
<span className="flex items-center">
|
||||||
<GotifyLogo className="h-4 mr-2" />
|
<GotifyLogo className="mr-2 h-4" />
|
||||||
Gotify
|
Gotify
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
@@ -74,7 +74,7 @@ const SettingsNotifications: React.FC = ({ children }) => {
|
|||||||
text: 'LunaSea',
|
text: 'LunaSea',
|
||||||
content: (
|
content: (
|
||||||
<span className="flex items-center">
|
<span className="flex items-center">
|
||||||
<LunaSeaLogo className="h-4 mr-2" />
|
<LunaSeaLogo className="mr-2 h-4" />
|
||||||
LunaSea
|
LunaSea
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
@@ -85,7 +85,7 @@ const SettingsNotifications: React.FC = ({ children }) => {
|
|||||||
text: 'Pushbullet',
|
text: 'Pushbullet',
|
||||||
content: (
|
content: (
|
||||||
<span className="flex items-center">
|
<span className="flex items-center">
|
||||||
<PushbulletLogo className="h-4 mr-2" />
|
<PushbulletLogo className="mr-2 h-4" />
|
||||||
Pushbullet
|
Pushbullet
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
@@ -96,7 +96,7 @@ const SettingsNotifications: React.FC = ({ children }) => {
|
|||||||
text: 'Pushover',
|
text: 'Pushover',
|
||||||
content: (
|
content: (
|
||||||
<span className="flex items-center">
|
<span className="flex items-center">
|
||||||
<PushoverLogo className="h-4 mr-2" />
|
<PushoverLogo className="mr-2 h-4" />
|
||||||
Pushover
|
Pushover
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
@@ -107,7 +107,7 @@ const SettingsNotifications: React.FC = ({ children }) => {
|
|||||||
text: 'Slack',
|
text: 'Slack',
|
||||||
content: (
|
content: (
|
||||||
<span className="flex items-center">
|
<span className="flex items-center">
|
||||||
<SlackLogo className="h-4 mr-2" />
|
<SlackLogo className="mr-2 h-4" />
|
||||||
Slack
|
Slack
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
@@ -118,7 +118,7 @@ const SettingsNotifications: React.FC = ({ children }) => {
|
|||||||
text: 'Telegram',
|
text: 'Telegram',
|
||||||
content: (
|
content: (
|
||||||
<span className="flex items-center">
|
<span className="flex items-center">
|
||||||
<TelegramLogo className="h-4 mr-2" />
|
<TelegramLogo className="mr-2 h-4" />
|
||||||
Telegram
|
Telegram
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
@@ -129,7 +129,7 @@ const SettingsNotifications: React.FC = ({ children }) => {
|
|||||||
text: intl.formatMessage(messages.webhook),
|
text: intl.formatMessage(messages.webhook),
|
||||||
content: (
|
content: (
|
||||||
<span className="flex items-center">
|
<span className="flex items-center">
|
||||||
<LightningBoltIcon className="h-4 mr-2" />
|
<LightningBoltIcon className="mr-2 h-4" />
|
||||||
{intl.formatMessage(messages.webhook)}
|
{intl.formatMessage(messages.webhook)}
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -506,7 +506,7 @@ const SettingsPlex: React.FC<SettingsPlexProps> = ({ onComplete }) => {
|
|||||||
</label>
|
</label>
|
||||||
<div className="form-input">
|
<div className="form-input">
|
||||||
<div className="form-input-field">
|
<div className="form-input-field">
|
||||||
<span className="inline-flex items-center px-3 text-gray-100 bg-gray-800 border border-r-0 border-gray-500 cursor-default rounded-l-md sm:text-sm">
|
<span className="inline-flex cursor-default items-center rounded-l-md border border-r-0 border-gray-500 bg-gray-800 px-3 text-gray-100 sm:text-sm">
|
||||||
{values.useSsl ? 'https://' : 'http://'}
|
{values.useSsl ? 'https://' : 'http://'}
|
||||||
</span>
|
</span>
|
||||||
<Field
|
<Field
|
||||||
@@ -594,7 +594,7 @@ const SettingsPlex: React.FC<SettingsPlexProps> = ({ onComplete }) => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
type="submit"
|
type="submit"
|
||||||
@@ -637,7 +637,7 @@ const SettingsPlex: React.FC<SettingsPlexProps> = ({ onComplete }) => {
|
|||||||
: intl.formatMessage(messages.scan)}
|
: intl.formatMessage(messages.scan)}
|
||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
<ul className="grid grid-cols-1 gap-5 mt-6 sm:gap-6 sm:grid-cols-2 lg:grid-cols-4">
|
<ul className="mt-6 grid grid-cols-1 gap-5 sm:grid-cols-2 sm:gap-6 lg:grid-cols-4">
|
||||||
{data?.libraries.map((library) => (
|
{data?.libraries.map((library) => (
|
||||||
<LibraryItem
|
<LibraryItem
|
||||||
name={library.name}
|
name={library.name}
|
||||||
@@ -655,11 +655,11 @@ const SettingsPlex: React.FC<SettingsPlexProps> = ({ onComplete }) => {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="section">
|
<div className="section">
|
||||||
<div className="p-4 bg-gray-800 rounded-md">
|
<div className="rounded-md bg-gray-800 p-4">
|
||||||
<div className="relative w-full h-8 mb-6 overflow-hidden bg-gray-600 rounded-full">
|
<div className="relative mb-6 h-8 w-full overflow-hidden rounded-full bg-gray-600">
|
||||||
{dataSync?.running && (
|
{dataSync?.running && (
|
||||||
<div
|
<div
|
||||||
className="h-8 transition-all duration-200 ease-in-out bg-indigo-600"
|
className="h-8 bg-indigo-600 transition-all duration-200 ease-in-out"
|
||||||
style={{
|
style={{
|
||||||
width: `${Math.round(
|
width: `${Math.round(
|
||||||
(dataSync.progress / dataSync.total) * 100
|
(dataSync.progress / dataSync.total) * 100
|
||||||
@@ -667,7 +667,7 @@ const SettingsPlex: React.FC<SettingsPlexProps> = ({ onComplete }) => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<div className="absolute inset-0 flex items-center justify-center w-full h-8 text-sm">
|
<div className="absolute inset-0 flex h-8 w-full items-center justify-center text-sm">
|
||||||
<span>
|
<span>
|
||||||
{dataSync?.running
|
{dataSync?.running
|
||||||
? `${dataSync.progress} of ${dataSync.total}`
|
? `${dataSync.progress} of ${dataSync.total}`
|
||||||
@@ -675,11 +675,11 @@ const SettingsPlex: React.FC<SettingsPlexProps> = ({ onComplete }) => {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col w-full sm:flex-row">
|
<div className="flex w-full flex-col sm:flex-row">
|
||||||
{dataSync?.running && (
|
{dataSync?.running && (
|
||||||
<>
|
<>
|
||||||
{dataSync.currentLibrary && (
|
{dataSync.currentLibrary && (
|
||||||
<div className="flex items-center mb-2 mr-0 sm:mb-0 sm:mr-2">
|
<div className="mb-2 mr-0 flex items-center sm:mb-0 sm:mr-2">
|
||||||
<Badge>
|
<Badge>
|
||||||
{intl.formatMessage(messages.currentlibrary, {
|
{intl.formatMessage(messages.currentlibrary, {
|
||||||
name: dataSync.currentLibrary.name,
|
name: dataSync.currentLibrary.name,
|
||||||
@@ -792,7 +792,7 @@ const SettingsPlex: React.FC<SettingsPlexProps> = ({ onComplete }) => {
|
|||||||
</label>
|
</label>
|
||||||
<div className="form-input">
|
<div className="form-input">
|
||||||
<div className="form-input-field">
|
<div className="form-input-field">
|
||||||
<span className="inline-flex items-center px-3 text-gray-100 bg-gray-800 border border-r-0 border-gray-500 cursor-default rounded-l-md sm:text-sm">
|
<span className="inline-flex cursor-default items-center rounded-l-md border border-r-0 border-gray-500 bg-gray-800 px-3 text-gray-100 sm:text-sm">
|
||||||
{values.tautulliUseSsl ? 'https://' : 'http://'}
|
{values.tautulliUseSsl ? 'https://' : 'http://'}
|
||||||
</span>
|
</span>
|
||||||
<Field
|
<Field
|
||||||
@@ -904,7 +904,7 @@ const SettingsPlex: React.FC<SettingsPlexProps> = ({ onComplete }) => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
type="submit"
|
type="submit"
|
||||||
|
|||||||
@@ -79,14 +79,14 @@ const ServerInstance: React.FC<ServerInstanceProps> = ({
|
|||||||
const serviceUrl = externalUrl ?? internalUrl;
|
const serviceUrl = externalUrl ?? internalUrl;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li className="col-span-1 bg-gray-800 rounded-lg shadow ring-1 ring-gray-500">
|
<li className="col-span-1 rounded-lg bg-gray-800 shadow ring-1 ring-gray-500">
|
||||||
<div className="flex items-center justify-between w-full p-6 space-x-6">
|
<div className="flex w-full items-center justify-between space-x-6 p-6">
|
||||||
<div className="flex-1 truncate">
|
<div className="flex-1 truncate">
|
||||||
<div className="flex items-center mb-2 space-x-2">
|
<div className="mb-2 flex items-center space-x-2">
|
||||||
<h3 className="font-medium leading-5 text-white truncate">
|
<h3 className="truncate font-medium leading-5 text-white">
|
||||||
<a
|
<a
|
||||||
href={serviceUrl}
|
href={serviceUrl}
|
||||||
className="transition duration-300 hover:underline hover:text-white"
|
className="transition duration-300 hover:text-white hover:underline"
|
||||||
>
|
>
|
||||||
{name}
|
{name}
|
||||||
</a>
|
</a>
|
||||||
@@ -108,18 +108,18 @@ const ServerInstance: React.FC<ServerInstanceProps> = ({
|
|||||||
</Badge>
|
</Badge>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<p className="mt-1 text-sm leading-5 text-gray-300 truncate">
|
<p className="mt-1 truncate text-sm leading-5 text-gray-300">
|
||||||
<span className="mr-2 font-bold">
|
<span className="mr-2 font-bold">
|
||||||
{intl.formatMessage(messages.address)}
|
{intl.formatMessage(messages.address)}
|
||||||
</span>
|
</span>
|
||||||
<a
|
<a
|
||||||
href={internalUrl}
|
href={internalUrl}
|
||||||
className="transition duration-300 hover:underline hover:text-white"
|
className="transition duration-300 hover:text-white hover:underline"
|
||||||
>
|
>
|
||||||
{internalUrl}
|
{internalUrl}
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
<p className="mt-1 text-sm leading-5 text-gray-300 truncate">
|
<p className="mt-1 truncate text-sm leading-5 text-gray-300">
|
||||||
<span className="mr-2 font-bold">
|
<span className="mr-2 font-bold">
|
||||||
{intl.formatMessage(messages.activeProfile)}
|
{intl.formatMessage(messages.activeProfile)}
|
||||||
</span>
|
</span>
|
||||||
@@ -128,29 +128,29 @@ const ServerInstance: React.FC<ServerInstanceProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
<a href={serviceUrl} className="opacity-50 hover:opacity-100">
|
<a href={serviceUrl} className="opacity-50 hover:opacity-100">
|
||||||
{isSonarr ? (
|
{isSonarr ? (
|
||||||
<SonarrLogo className="flex-shrink-0 w-10 h-10" />
|
<SonarrLogo className="h-10 w-10 flex-shrink-0" />
|
||||||
) : (
|
) : (
|
||||||
<RadarrLogo className="flex-shrink-0 w-10 h-10" />
|
<RadarrLogo className="h-10 w-10 flex-shrink-0" />
|
||||||
)}
|
)}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div className="border-t border-gray-500">
|
<div className="border-t border-gray-500">
|
||||||
<div className="flex -mt-px">
|
<div className="-mt-px flex">
|
||||||
<div className="flex flex-1 w-0 border-r border-gray-500">
|
<div className="flex w-0 flex-1 border-r border-gray-500">
|
||||||
<button
|
<button
|
||||||
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="focus:ring-blue relative -mr-px inline-flex w-0 flex-1 items-center justify-center rounded-bl-lg border border-transparent py-4 text-sm font-medium leading-5 text-gray-200 transition duration-150 ease-in-out hover:text-white focus:z-10 focus:border-gray-500 focus:outline-none"
|
||||||
>
|
>
|
||||||
<PencilIcon className="w-5 h-5 mr-2" />
|
<PencilIcon className="mr-2 h-5 w-5" />
|
||||||
<span>{intl.formatMessage(globalMessages.edit)}</span>
|
<span>{intl.formatMessage(globalMessages.edit)}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-1 w-0 -ml-px">
|
<div className="-ml-px flex w-0 flex-1">
|
||||||
<button
|
<button
|
||||||
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="focus:ring-blue relative inline-flex w-0 flex-1 items-center justify-center rounded-br-lg border border-transparent py-4 text-sm font-medium leading-5 text-gray-200 transition duration-150 ease-in-out hover:text-white focus:z-10 focus:border-gray-500 focus:outline-none"
|
||||||
>
|
>
|
||||||
<TrashIcon className="w-5 h-5 mr-2" />
|
<TrashIcon className="mr-2 h-5 w-5" />
|
||||||
<span>{intl.formatMessage(globalMessages.delete)}</span>
|
<span>{intl.formatMessage(globalMessages.delete)}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -334,8 +334,8 @@ const SettingsServices: React.FC = () => {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
<li className="h-32 col-span-1 border-2 border-gray-400 border-dashed rounded-lg shadow sm:h-44">
|
<li className="col-span-1 h-32 rounded-lg border-2 border-dashed border-gray-400 shadow sm:h-44">
|
||||||
<div className="flex items-center justify-center w-full h-full">
|
<div className="flex h-full w-full items-center justify-center">
|
||||||
<Button
|
<Button
|
||||||
buttonType="ghost"
|
buttonType="ghost"
|
||||||
className="mt-3 mb-3"
|
className="mt-3 mb-3"
|
||||||
@@ -425,8 +425,8 @@ const SettingsServices: React.FC = () => {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
<li className="h-32 col-span-1 border-2 border-gray-400 border-dashed rounded-lg shadow sm:h-44">
|
<li className="col-span-1 h-32 rounded-lg border-2 border-dashed border-gray-400 shadow sm:h-44">
|
||||||
<div className="flex items-center justify-center w-full h-full">
|
<div className="flex h-full w-full items-center justify-center">
|
||||||
<Button
|
<Button
|
||||||
buttonType="ghost"
|
buttonType="ghost"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ const SettingsUsers: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
type="submit"
|
type="submit"
|
||||||
|
|||||||
@@ -45,10 +45,10 @@ const LoginWithPlex: React.FC<LoginWithPlexProps> = ({ onComplete }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<form>
|
<form>
|
||||||
<div className="flex justify-center mb-2 text-xl font-bold">
|
<div className="mb-2 flex justify-center text-xl font-bold">
|
||||||
{intl.formatMessage(messages.welcome)}
|
{intl.formatMessage(messages.welcome)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-center pb-6 mb-2 text-sm">
|
<div className="mb-2 flex justify-center pb-6 text-sm">
|
||||||
{intl.formatMessage(messages.signinMessage)}
|
{intl.formatMessage(messages.signinMessage)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-center">
|
<div className="flex items-center justify-center">
|
||||||
|
|||||||
@@ -17,14 +17,14 @@ const SetupSteps: React.FC<CurrentStep> = ({
|
|||||||
isLastStep = false,
|
isLastStep = false,
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<li className="relative md:flex-1 md:flex">
|
<li className="relative md:flex md:flex-1">
|
||||||
<div className="flex items-center px-6 py-4 space-x-4 text-sm font-medium leading-5">
|
<div className="flex items-center space-x-4 px-6 py-4 text-sm font-medium leading-5">
|
||||||
<div
|
<div
|
||||||
className={`flex-shrink-0 w-10 h-10 flex items-center justify-center border-2
|
className={`flex h-10 w-10 flex-shrink-0 items-center justify-center border-2
|
||||||
${active ? 'border-indigo-600 ' : 'border-white '}
|
${active ? 'border-indigo-600 ' : 'border-white '}
|
||||||
${completed ? 'bg-indigo-600 border-indigo-600 ' : ''} rounded-full`}
|
${completed ? 'border-indigo-600 bg-indigo-600 ' : ''} rounded-full`}
|
||||||
>
|
>
|
||||||
{completed && <CheckIcon className="w-6 h-6 text-white" />}
|
{completed && <CheckIcon className="h-6 w-6 text-white" />}
|
||||||
{!completed && (
|
{!completed && (
|
||||||
<p className={active ? 'text-white' : 'text-indigo-200'}>
|
<p className={active ? 'text-white' : 'text-indigo-200'}>
|
||||||
{stepNumber}
|
{stepNumber}
|
||||||
@@ -32,7 +32,7 @@ const SetupSteps: React.FC<CurrentStep> = ({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<p
|
<p
|
||||||
className={`text-sm leading-5 font-medium ${
|
className={`text-sm font-medium leading-5 ${
|
||||||
active ? 'text-white' : 'text-indigo-200'
|
active ? 'text-white' : 'text-indigo-200'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
@@ -41,9 +41,9 @@ const SetupSteps: React.FC<CurrentStep> = ({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{!isLastStep && (
|
{!isLastStep && (
|
||||||
<div className="absolute top-0 right-0 hidden w-5 h-full md:block">
|
<div className="absolute top-0 right-0 hidden h-full w-5 md:block">
|
||||||
<svg
|
<svg
|
||||||
className="w-full h-full text-gray-600"
|
className="h-full w-full text-gray-600"
|
||||||
viewBox="0 0 22 80"
|
viewBox="0 0 22 80"
|
||||||
fill="none"
|
fill="none"
|
||||||
preserveAspectRatio="none"
|
preserveAspectRatio="none"
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ const Setup: React.FC = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative flex flex-col justify-center min-h-screen py-12 bg-gray-900">
|
<div className="relative flex min-h-screen flex-col justify-center bg-gray-900 py-12">
|
||||||
<PageTitle title={intl.formatMessage(messages.setup)} />
|
<PageTitle title={intl.formatMessage(messages.setup)} />
|
||||||
<ImageFader
|
<ImageFader
|
||||||
backgroundImages={
|
backgroundImages={
|
||||||
@@ -67,19 +67,19 @@ const Setup: React.FC = () => {
|
|||||||
) ?? []
|
) ?? []
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<div className="absolute z-50 top-4 right-4">
|
<div className="absolute top-4 right-4 z-50">
|
||||||
<LanguagePicker />
|
<LanguagePicker />
|
||||||
</div>
|
</div>
|
||||||
<div className="relative z-40 px-4 sm:mx-auto sm:w-full sm:max-w-4xl">
|
<div className="relative z-40 px-4 sm:mx-auto sm:w-full sm:max-w-4xl">
|
||||||
<img
|
<img
|
||||||
src="/logo_stacked.svg"
|
src="/logo_stacked.svg"
|
||||||
className="max-w-full mb-10 sm:max-w-md sm:mx-auto"
|
className="mb-10 max-w-full sm:mx-auto sm:max-w-md"
|
||||||
alt="Logo"
|
alt="Logo"
|
||||||
/>
|
/>
|
||||||
<AppDataWarning />
|
<AppDataWarning />
|
||||||
<nav className="relative z-50">
|
<nav className="relative z-50">
|
||||||
<ul
|
<ul
|
||||||
className="bg-gray-800 bg-opacity-50 border border-gray-600 divide-y divide-gray-600 rounded-md md:flex md:divide-y-0"
|
className="divide-y divide-gray-600 rounded-md border border-gray-600 bg-gray-800 bg-opacity-50 md:flex md:divide-y-0"
|
||||||
style={{ backdropFilter: 'blur(5px)' }}
|
style={{ backdropFilter: 'blur(5px)' }}
|
||||||
>
|
>
|
||||||
<SetupSteps
|
<SetupSteps
|
||||||
@@ -102,7 +102,7 @@ const Setup: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
<div className="w-full p-4 mt-10 text-white bg-gray-800 bg-opacity-50 border border-gray-600 rounded-md">
|
<div className="mt-10 w-full rounded-md border border-gray-600 bg-gray-800 bg-opacity-50 p-4 text-white">
|
||||||
{currentStep === 1 && (
|
{currentStep === 1 && (
|
||||||
<LoginWithPlex onComplete={() => setCurrentStep(2)} />
|
<LoginWithPlex onComplete={() => setCurrentStep(2)} />
|
||||||
)}
|
)}
|
||||||
@@ -117,7 +117,7 @@ const Setup: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
disabled={!plexSettingsComplete}
|
disabled={!plexSettingsComplete}
|
||||||
@@ -135,7 +135,7 @@ const Setup: React.FC = () => {
|
|||||||
<SettingsServices />
|
<SettingsServices />
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
onClick={() => finishSetup()}
|
onClick={() => finishSetup()}
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ const Slider: React.FC<SliderProps> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<div className="absolute right-0 flex -mt-10 text-gray-400">
|
<div className="absolute right-0 -mt-10 flex text-gray-400">
|
||||||
<button
|
<button
|
||||||
className={`${
|
className={`${
|
||||||
scrollPos.isStart ? 'text-gray-800' : 'hover:text-white'
|
scrollPos.isStart ? 'text-gray-800' : 'hover:text-white'
|
||||||
@@ -163,7 +163,7 @@ const Slider: React.FC<SliderProps> = ({
|
|||||||
onClick={() => slide(Direction.LEFT)}
|
onClick={() => slide(Direction.LEFT)}
|
||||||
disabled={scrollPos.isStart}
|
disabled={scrollPos.isStart}
|
||||||
>
|
>
|
||||||
<ChevronLeftIcon className="w-6 h-6" />
|
<ChevronLeftIcon className="h-6 w-6" />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className={`${
|
className={`${
|
||||||
@@ -172,11 +172,11 @@ const Slider: React.FC<SliderProps> = ({
|
|||||||
onClick={() => slide(Direction.RIGHT)}
|
onClick={() => slide(Direction.RIGHT)}
|
||||||
disabled={scrollPos.isEnd}
|
disabled={scrollPos.isEnd}
|
||||||
>
|
>
|
||||||
<ChevronRightIcon className="w-6 h-6" />
|
<ChevronRightIcon className="h-6 w-6" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="relative px-2 py-2 -my-2 -ml-4 -mr-4 overflow-x-scroll overflow-y-auto whitespace-nowrap hide-scrollbar overscroll-x-contain"
|
className="hide-scrollbar relative -my-2 -ml-4 -mr-4 overflow-y-auto overflow-x-scroll overscroll-x-contain whitespace-nowrap px-2 py-2"
|
||||||
ref={containerRef}
|
ref={containerRef}
|
||||||
onScroll={onScroll}
|
onScroll={onScroll}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ const StatusBadge: React.FC<StatusBadgeProps> = ({
|
|||||||
status: intl.formatMessage(globalMessages.available),
|
status: intl.formatMessage(globalMessages.available),
|
||||||
})}
|
})}
|
||||||
</span>
|
</span>
|
||||||
{inProgress && <Spinner className="w-3 h-3 ml-1" />}
|
{inProgress && <Spinner className="ml-1 h-3 w-3" />}
|
||||||
</div>
|
</div>
|
||||||
</Badge>
|
</Badge>
|
||||||
);
|
);
|
||||||
@@ -62,7 +62,7 @@ const StatusBadge: React.FC<StatusBadgeProps> = ({
|
|||||||
status: intl.formatMessage(globalMessages.partiallyavailable),
|
status: intl.formatMessage(globalMessages.partiallyavailable),
|
||||||
})}
|
})}
|
||||||
</span>
|
</span>
|
||||||
{inProgress && <Spinner className="w-3 h-3 ml-1" />}
|
{inProgress && <Spinner className="ml-1 h-3 w-3" />}
|
||||||
</div>
|
</div>
|
||||||
</Badge>
|
</Badge>
|
||||||
);
|
);
|
||||||
@@ -78,7 +78,7 @@ const StatusBadge: React.FC<StatusBadgeProps> = ({
|
|||||||
: intl.formatMessage(globalMessages.requested),
|
: intl.formatMessage(globalMessages.requested),
|
||||||
})}
|
})}
|
||||||
</span>
|
</span>
|
||||||
{inProgress && <Spinner className="w-3 h-3 ml-1" />}
|
{inProgress && <Spinner className="ml-1 h-3 w-3" />}
|
||||||
</div>
|
</div>
|
||||||
</Badge>
|
</Badge>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ const TitleCard: React.FC<TitleCardProps> = ({
|
|||||||
onCancel={closeModal}
|
onCancel={closeModal}
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
className={`transition duration-300 transform-gpu outline-none cursor-default relative bg-gray-800 bg-cover rounded-xl ring-1 overflow-hidden ${
|
className={`relative transform-gpu cursor-default overflow-hidden rounded-xl bg-gray-800 bg-cover outline-none ring-1 transition duration-300 ${
|
||||||
showDetail
|
showDetail
|
||||||
? 'scale-105 shadow-lg ring-gray-500'
|
? 'scale-105 shadow-lg ring-gray-500'
|
||||||
: 'scale-100 shadow ring-gray-700'
|
: 'scale-100 shadow ring-gray-700'
|
||||||
@@ -111,9 +111,9 @@ const TitleCard: React.FC<TitleCardProps> = ({
|
|||||||
role="link"
|
role="link"
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
>
|
>
|
||||||
<div className="absolute inset-0 w-full h-full overflow-hidden">
|
<div className="absolute inset-0 h-full w-full overflow-hidden">
|
||||||
<CachedImage
|
<CachedImage
|
||||||
className="absolute inset-0 w-full h-full"
|
className="absolute inset-0 h-full w-full"
|
||||||
alt=""
|
alt=""
|
||||||
src={
|
src={
|
||||||
image
|
image
|
||||||
@@ -125,34 +125,34 @@ const TitleCard: React.FC<TitleCardProps> = ({
|
|||||||
/>
|
/>
|
||||||
<div className="absolute left-0 right-0 flex items-center justify-between p-2">
|
<div className="absolute left-0 right-0 flex items-center justify-between p-2">
|
||||||
<div
|
<div
|
||||||
className={`rounded-full z-40 pointer-events-none shadow ${
|
className={`pointer-events-none z-40 rounded-full shadow ${
|
||||||
mediaType === 'movie' ? 'bg-blue-500' : 'bg-purple-600'
|
mediaType === 'movie' ? 'bg-blue-500' : 'bg-purple-600'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="flex items-center h-4 px-2 py-2 text-xs font-medium tracking-wider text-center text-white uppercase sm:h-5">
|
<div className="flex h-4 items-center px-2 py-2 text-center text-xs font-medium uppercase tracking-wider text-white sm:h-5">
|
||||||
{mediaType === 'movie'
|
{mediaType === 'movie'
|
||||||
? intl.formatMessage(globalMessages.movie)
|
? intl.formatMessage(globalMessages.movie)
|
||||||
: intl.formatMessage(globalMessages.tvshow)}
|
: intl.formatMessage(globalMessages.tvshow)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="z-40 pointer-events-none">
|
<div className="pointer-events-none z-40">
|
||||||
{(currentStatus === MediaStatus.AVAILABLE ||
|
{(currentStatus === MediaStatus.AVAILABLE ||
|
||||||
currentStatus === MediaStatus.PARTIALLY_AVAILABLE) && (
|
currentStatus === MediaStatus.PARTIALLY_AVAILABLE) && (
|
||||||
<div className="flex items-center justify-center w-4 h-4 text-white bg-green-400 rounded-full shadow sm:w-5 sm:h-5">
|
<div className="flex h-4 w-4 items-center justify-center rounded-full bg-green-400 text-white shadow sm:h-5 sm:w-5">
|
||||||
<CheckIcon className="w-3 h-3 sm:w-4 sm:h-4" />
|
<CheckIcon className="h-3 w-3 sm:h-4 sm:w-4" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{currentStatus === MediaStatus.PENDING && (
|
{currentStatus === MediaStatus.PENDING && (
|
||||||
<div className="flex items-center justify-center w-4 h-4 text-white bg-yellow-500 rounded-full shadow sm:w-5 sm:h-5">
|
<div className="flex h-4 w-4 items-center justify-center rounded-full bg-yellow-500 text-white shadow sm:h-5 sm:w-5">
|
||||||
<BellIcon className="w-3 h-3 sm:w-4 sm:h-4" />
|
<BellIcon className="h-3 w-3 sm:h-4 sm:w-4" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{currentStatus === MediaStatus.PROCESSING && (
|
{currentStatus === MediaStatus.PROCESSING && (
|
||||||
<div className="flex items-center justify-center w-4 h-4 text-white bg-indigo-500 rounded-full shadow sm:w-5 sm:h-5">
|
<div className="flex h-4 w-4 items-center justify-center rounded-full bg-indigo-500 text-white shadow sm:h-5 sm:w-5">
|
||||||
{inProgress ? (
|
{inProgress ? (
|
||||||
<Spinner className="w-3 h-3" />
|
<Spinner className="h-3 w-3" />
|
||||||
) : (
|
) : (
|
||||||
<ClockIcon className="w-3 h-3 sm:w-4 sm:h-4" />
|
<ClockIcon className="h-3 w-3 sm:h-4 sm:w-4" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -167,8 +167,8 @@ const TitleCard: React.FC<TitleCardProps> = ({
|
|||||||
leaveFrom="opacity-100"
|
leaveFrom="opacity-100"
|
||||||
leaveTo="opacity-0"
|
leaveTo="opacity-0"
|
||||||
>
|
>
|
||||||
<div className="absolute inset-0 z-40 flex items-center justify-center text-white bg-gray-800 bg-opacity-75 rounded-xl">
|
<div className="absolute inset-0 z-40 flex items-center justify-center rounded-xl bg-gray-800 bg-opacity-75 text-white">
|
||||||
<Spinner className="w-10 h-10" />
|
<Spinner className="h-10 w-10" />
|
||||||
</div>
|
</div>
|
||||||
</Transition>
|
</Transition>
|
||||||
|
|
||||||
@@ -184,13 +184,13 @@ const TitleCard: React.FC<TitleCardProps> = ({
|
|||||||
<div className="absolute inset-0 overflow-hidden rounded-xl">
|
<div className="absolute inset-0 overflow-hidden rounded-xl">
|
||||||
<Link href={mediaType === 'movie' ? `/movie/${id}` : `/tv/${id}`}>
|
<Link href={mediaType === 'movie' ? `/movie/${id}` : `/tv/${id}`}>
|
||||||
<a
|
<a
|
||||||
className="absolute inset-0 w-full h-full overflow-hidden text-left cursor-pointer"
|
className="absolute inset-0 h-full w-full cursor-pointer overflow-hidden text-left"
|
||||||
style={{
|
style={{
|
||||||
background:
|
background:
|
||||||
'linear-gradient(180deg, rgba(45, 55, 72, 0.4) 0%, rgba(45, 55, 72, 0.9) 100%)',
|
'linear-gradient(180deg, rgba(45, 55, 72, 0.4) 0%, rgba(45, 55, 72, 0.9) 100%)',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="flex items-end w-full h-full">
|
<div className="flex h-full w-full items-end">
|
||||||
<div
|
<div
|
||||||
className={`px-2 text-white ${
|
className={`px-2 text-white ${
|
||||||
!showRequestButton ||
|
!showRequestButton ||
|
||||||
@@ -204,7 +204,7 @@ const TitleCard: React.FC<TitleCardProps> = ({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<h1
|
<h1
|
||||||
className="text-xl font-bold leading-tight whitespace-normal"
|
className="whitespace-normal text-xl font-bold leading-tight"
|
||||||
style={{
|
style={{
|
||||||
WebkitLineClamp: 3,
|
WebkitLineClamp: 3,
|
||||||
display: '-webkit-box',
|
display: '-webkit-box',
|
||||||
@@ -216,7 +216,7 @@ const TitleCard: React.FC<TitleCardProps> = ({
|
|||||||
{title}
|
{title}
|
||||||
</h1>
|
</h1>
|
||||||
<div
|
<div
|
||||||
className="text-xs whitespace-normal"
|
className="whitespace-normal text-xs"
|
||||||
style={{
|
style={{
|
||||||
WebkitLineClamp:
|
WebkitLineClamp:
|
||||||
!showRequestButton ||
|
!showRequestButton ||
|
||||||
@@ -247,7 +247,7 @@ const TitleCard: React.FC<TitleCardProps> = ({
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setShowRequestModal(true);
|
setShowRequestModal(true);
|
||||||
}}
|
}}
|
||||||
className="w-full h-7"
|
className="h-7 w-full"
|
||||||
>
|
>
|
||||||
<DownloadIcon />
|
<DownloadIcon />
|
||||||
<span>{intl.formatMessage(globalMessages.request)}</span>
|
<span>{intl.formatMessage(globalMessages.request)}</span>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ const Toast: React.FC<ToastProps> = ({
|
|||||||
transitionState,
|
transitionState,
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div className="flex items-end justify-center max-w-full px-2 py-2 pointer-events-none toast sm:items-start sm:justify-end">
|
<div className="toast pointer-events-none flex max-w-full items-end justify-center px-2 py-2 sm:items-start sm:justify-end">
|
||||||
<Transition
|
<Transition
|
||||||
show={transitionState === 'entered'}
|
show={transitionState === 'entered'}
|
||||||
enter="transition duration-300 transform-gpu"
|
enter="transition duration-300 transform-gpu"
|
||||||
@@ -26,31 +26,31 @@ const Toast: React.FC<ToastProps> = ({
|
|||||||
leaveFrom="opacity-100 scale-100"
|
leaveFrom="opacity-100 scale-100"
|
||||||
leaveTo="opacity-0 scale-90"
|
leaveTo="opacity-0 scale-90"
|
||||||
>
|
>
|
||||||
<div className="w-full max-w-sm bg-gray-800 rounded-lg shadow-lg pointer-events-auto ring-1 ring-gray-500">
|
<div className="pointer-events-auto w-full max-w-sm rounded-lg bg-gray-800 shadow-lg ring-1 ring-gray-500">
|
||||||
<div className="overflow-hidden rounded-lg ring-1 ring-black ring-opacity-5">
|
<div className="overflow-hidden rounded-lg ring-1 ring-black ring-opacity-5">
|
||||||
<div className="p-4">
|
<div className="p-4">
|
||||||
<div className="flex items-start">
|
<div className="flex items-start">
|
||||||
<div className="flex-shrink-0">
|
<div className="flex-shrink-0">
|
||||||
{appearance === 'success' && (
|
{appearance === 'success' && (
|
||||||
<CheckCircleIcon className="w-6 h-6 text-green-400" />
|
<CheckCircleIcon className="h-6 w-6 text-green-400" />
|
||||||
)}
|
)}
|
||||||
{appearance === 'error' && (
|
{appearance === 'error' && (
|
||||||
<ExclamationCircleIcon className="w-6 h-6 text-red-500" />
|
<ExclamationCircleIcon className="h-6 w-6 text-red-500" />
|
||||||
)}
|
)}
|
||||||
{appearance === 'info' && (
|
{appearance === 'info' && (
|
||||||
<InformationCircleIcon className="w-6 h-6 text-indigo-500" />
|
<InformationCircleIcon className="h-6 w-6 text-indigo-500" />
|
||||||
)}
|
)}
|
||||||
{appearance === 'warning' && (
|
{appearance === 'warning' && (
|
||||||
<ExclamationIcon className="w-6 h-6 text-orange-400" />
|
<ExclamationIcon className="h-6 w-6 text-orange-400" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-1 w-0 ml-3 text-white">{children}</div>
|
<div className="ml-3 w-0 flex-1 text-white">{children}</div>
|
||||||
<div className="flex flex-shrink-0 ml-4">
|
<div className="ml-4 flex flex-shrink-0">
|
||||||
<button
|
<button
|
||||||
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:text-gray-500 focus:outline-none"
|
||||||
>
|
>
|
||||||
<XIcon className="w-5 h-5" />
|
<XIcon className="h-5 w-5" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ const ToastContainer: React.FC<ToastContainerProps> = ({
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
id="toast-container"
|
id="toast-container"
|
||||||
className="box-border fixed right-0 max-w-full max-h-full px-4 overflow-hidden top-4"
|
className="fixed right-0 top-4 box-border max-h-full max-w-full overflow-hidden px-4"
|
||||||
style={{
|
style={{
|
||||||
pointerEvents: hasToasts ? 'all' : 'none',
|
pointerEvents: hasToasts ? 'all' : 'none',
|
||||||
zIndex: 10000,
|
zIndex: 10000,
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
|||||||
)?.rating;
|
)?.rating;
|
||||||
if (contentRating) {
|
if (contentRating) {
|
||||||
seriesAttributes.push(
|
seriesAttributes.push(
|
||||||
<span className="p-0.5 py-0 border rounded-md">{contentRating}</span>
|
<span className="rounded-md border p-0.5 py-0">{contentRating}</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -373,8 +373,8 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
|||||||
) ?? []
|
) ?? []
|
||||||
).length > 0 && (
|
).length > 0 && (
|
||||||
<>
|
<>
|
||||||
<div className="absolute w-3 h-3 bg-red-600 rounded-full -right-1 -top-1" />
|
<div className="absolute -right-1 -top-1 h-3 w-3 rounded-full bg-red-600" />
|
||||||
<div className="absolute w-3 h-3 bg-red-600 rounded-full -right-1 -top-1 animate-ping" />
|
<div className="absolute -right-1 -top-1 h-3 w-3 animate-ping rounded-full bg-red-600" />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
@@ -416,11 +416,11 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
|||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
<div className="flex justify-end mt-4">
|
<div className="mt-4 flex justify-end">
|
||||||
<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.5" />
|
<ArrowCircleRightIcon className="ml-1.5 inline-block h-5 w-5" />
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
@@ -436,9 +436,9 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
|||||||
{ratingData?.criticsRating && !!ratingData?.criticsScore && (
|
{ratingData?.criticsRating && !!ratingData?.criticsScore && (
|
||||||
<span className="media-rating">
|
<span className="media-rating">
|
||||||
{ratingData.criticsRating === 'Rotten' ? (
|
{ratingData.criticsRating === 'Rotten' ? (
|
||||||
<RTRotten className="w-6 mr-1" />
|
<RTRotten className="mr-1 w-6" />
|
||||||
) : (
|
) : (
|
||||||
<RTFresh className="w-6 mr-1" />
|
<RTFresh className="mr-1 w-6" />
|
||||||
)}
|
)}
|
||||||
{ratingData.criticsScore}%
|
{ratingData.criticsScore}%
|
||||||
</span>
|
</span>
|
||||||
@@ -446,16 +446,16 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
|||||||
{ratingData?.audienceRating && !!ratingData?.audienceScore && (
|
{ratingData?.audienceRating && !!ratingData?.audienceScore && (
|
||||||
<span className="media-rating">
|
<span className="media-rating">
|
||||||
{ratingData.audienceRating === 'Spilled' ? (
|
{ratingData.audienceRating === 'Spilled' ? (
|
||||||
<RTAudRotten className="w-6 mr-1" />
|
<RTAudRotten className="mr-1 w-6" />
|
||||||
) : (
|
) : (
|
||||||
<RTAudFresh className="w-6 mr-1" />
|
<RTAudFresh className="mr-1 w-6" />
|
||||||
)}
|
)}
|
||||||
{ratingData.audienceScore}%
|
{ratingData.audienceScore}%
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{!!data.voteCount && (
|
{!!data.voteCount && (
|
||||||
<span className="media-rating">
|
<span className="media-rating">
|
||||||
<TmdbLogo className="w-6 mr-2" />
|
<TmdbLogo className="mr-2 w-6" />
|
||||||
{data.voteAverage}/10
|
{data.voteAverage}/10
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ const PlexImportModal: React.FC<PlexImportProps> = ({
|
|||||||
<table className="min-w-full">
|
<table className="min-w-full">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th className="w-16 px-4 py-3 bg-gray-500">
|
<th className="w-16 bg-gray-500 px-4 py-3">
|
||||||
<span
|
<span
|
||||||
role="checkbox"
|
role="checkbox"
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
@@ -152,31 +152,31 @@ const PlexImportModal: React.FC<PlexImportProps> = ({
|
|||||||
toggleAllUsers();
|
toggleAllUsers();
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
className="relative inline-flex items-center justify-center flex-shrink-0 w-10 h-5 pt-2 cursor-pointer focus:outline-none"
|
className="relative inline-flex h-5 w-10 flex-shrink-0 cursor-pointer items-center justify-center pt-2 focus:outline-none"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
className={`${
|
className={`${
|
||||||
isAllUsers() ? 'bg-indigo-500' : 'bg-gray-800'
|
isAllUsers() ? 'bg-indigo-500' : 'bg-gray-800'
|
||||||
} absolute h-4 w-9 mx-auto rounded-full transition-colors ease-in-out duration-200`}
|
} absolute mx-auto h-4 w-9 rounded-full transition-colors duration-200 ease-in-out`}
|
||||||
></span>
|
></span>
|
||||||
<span
|
<span
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
className={`${
|
className={`${
|
||||||
isAllUsers() ? 'translate-x-5' : 'translate-x-0'
|
isAllUsers() ? 'translate-x-5' : 'translate-x-0'
|
||||||
} absolute left-0 inline-block h-5 w-5 border border-gray-200 rounded-full bg-white shadow transform group-focus:ring group-focus:border-blue-300 transition-transform ease-in-out duration-200`}
|
} absolute left-0 inline-block h-5 w-5 transform rounded-full border border-gray-200 bg-white shadow transition-transform duration-200 ease-in-out group-focus:border-blue-300 group-focus:ring`}
|
||||||
></span>
|
></span>
|
||||||
</span>
|
</span>
|
||||||
</th>
|
</th>
|
||||||
<th className="px-1 py-3 text-xs font-medium leading-4 tracking-wider text-left text-gray-200 uppercase bg-gray-500 md:px-6">
|
<th className="bg-gray-500 px-1 py-3 text-left text-xs font-medium uppercase leading-4 tracking-wider text-gray-200 md:px-6">
|
||||||
{intl.formatMessage(messages.user)}
|
{intl.formatMessage(messages.user)}
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody className="bg-gray-600 divide-y divide-gray-700">
|
<tbody className="divide-y divide-gray-700 bg-gray-600">
|
||||||
{data?.map((user) => (
|
{data?.map((user) => (
|
||||||
<tr key={`user-${user.id}`}>
|
<tr key={`user-${user.id}`}>
|
||||||
<td className="px-4 py-4 text-sm font-medium leading-5 text-gray-100 whitespace-nowrap">
|
<td className="whitespace-nowrap px-4 py-4 text-sm font-medium leading-5 text-gray-100">
|
||||||
<span
|
<span
|
||||||
role="checkbox"
|
role="checkbox"
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
@@ -187,7 +187,7 @@ const PlexImportModal: React.FC<PlexImportProps> = ({
|
|||||||
toggleUser(user.id);
|
toggleUser(user.id);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
className="relative inline-flex items-center justify-center flex-shrink-0 w-10 h-5 pt-2 cursor-pointer focus:outline-none"
|
className="relative inline-flex h-5 w-10 flex-shrink-0 cursor-pointer items-center justify-center pt-2 focus:outline-none"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@@ -195,7 +195,7 @@ const PlexImportModal: React.FC<PlexImportProps> = ({
|
|||||||
isSelectedUser(user.id)
|
isSelectedUser(user.id)
|
||||||
? 'bg-indigo-500'
|
? 'bg-indigo-500'
|
||||||
: 'bg-gray-800'
|
: 'bg-gray-800'
|
||||||
} absolute h-4 w-9 mx-auto rounded-full transition-colors ease-in-out duration-200`}
|
} absolute mx-auto h-4 w-9 rounded-full transition-colors duration-200 ease-in-out`}
|
||||||
></span>
|
></span>
|
||||||
<span
|
<span
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@@ -203,14 +203,14 @@ const PlexImportModal: React.FC<PlexImportProps> = ({
|
|||||||
isSelectedUser(user.id)
|
isSelectedUser(user.id)
|
||||||
? 'translate-x-5'
|
? 'translate-x-5'
|
||||||
: 'translate-x-0'
|
: 'translate-x-0'
|
||||||
} absolute left-0 inline-block h-5 w-5 border border-gray-200 rounded-full bg-white shadow transform group-focus:ring group-focus:border-blue-300 transition-transform ease-in-out duration-200`}
|
} absolute left-0 inline-block h-5 w-5 transform rounded-full border border-gray-200 bg-white shadow transition-transform duration-200 ease-in-out group-focus:border-blue-300 group-focus:ring`}
|
||||||
></span>
|
></span>
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td className="px-1 py-4 text-sm font-medium leading-5 text-gray-100 md:px-6 whitespace-nowrap">
|
<td className="whitespace-nowrap px-1 py-4 text-sm font-medium leading-5 text-gray-100 md:px-6">
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<img
|
<img
|
||||||
className="flex-shrink-0 w-10 h-10 rounded-full"
|
className="h-10 w-10 flex-shrink-0 rounded-full"
|
||||||
src={user.thumb}
|
src={user.thumb}
|
||||||
alt=""
|
alt=""
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -471,12 +471,12 @@ const UserList: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
</Transition>
|
</Transition>
|
||||||
|
|
||||||
<div className="flex flex-col justify-between lg:items-end lg:flex-row">
|
<div className="flex flex-col justify-between lg:flex-row lg:items-end">
|
||||||
<Header>{intl.formatMessage(messages.userlist)}</Header>
|
<Header>{intl.formatMessage(messages.userlist)}</Header>
|
||||||
<div className="flex flex-col flex-grow mt-2 lg:flex-row lg:flex-grow-0">
|
<div className="mt-2 flex flex-grow flex-col lg:flex-grow-0 lg:flex-row">
|
||||||
<div className="flex flex-col justify-between flex-grow mb-2 sm:flex-row lg:mb-0 lg:flex-grow-0">
|
<div className="mb-2 flex flex-grow flex-col justify-between sm:flex-row lg:mb-0 lg:flex-grow-0">
|
||||||
<Button
|
<Button
|
||||||
className="flex-grow mb-2 sm:mb-0 sm:mr-2"
|
className="mb-2 flex-grow sm:mb-0 sm:mr-2"
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
onClick={() => setCreateModal({ isOpen: true })}
|
onClick={() => setCreateModal({ isOpen: true })}
|
||||||
>
|
>
|
||||||
@@ -492,9 +492,9 @@ const UserList: React.FC = () => {
|
|||||||
<span>{intl.formatMessage(messages.importfromplex)}</span>
|
<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="mb-2 flex flex-grow lg:mb-0 lg:flex-grow-0">
|
||||||
<span className="inline-flex items-center px-3 text-sm text-gray-100 bg-gray-800 border border-r-0 border-gray-500 cursor-default rounded-l-md">
|
<span className="inline-flex cursor-default items-center rounded-l-md border border-r-0 border-gray-500 bg-gray-800 px-3 text-sm text-gray-100">
|
||||||
<SortDescendingIcon className="w-6 h-6" />
|
<SortDescendingIcon className="h-6 w-6" />
|
||||||
</span>
|
</span>
|
||||||
<select
|
<select
|
||||||
id="sort"
|
id="sort"
|
||||||
@@ -573,9 +573,9 @@ const UserList: React.FC = () => {
|
|||||||
<Table.TD>
|
<Table.TD>
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<Link href={`/users/${user.id}`}>
|
<Link href={`/users/${user.id}`}>
|
||||||
<a className="flex-shrink-0 w-10 h-10">
|
<a className="h-10 w-10 flex-shrink-0">
|
||||||
<img
|
<img
|
||||||
className="w-10 h-10 rounded-full"
|
className="h-10 w-10 rounded-full"
|
||||||
src={user.avatar}
|
src={user.avatar}
|
||||||
alt=""
|
alt=""
|
||||||
/>
|
/>
|
||||||
@@ -666,7 +666,7 @@ const UserList: React.FC = () => {
|
|||||||
<tr className="bg-gray-700">
|
<tr className="bg-gray-700">
|
||||||
<Table.TD colSpan={8} noPadding>
|
<Table.TD colSpan={8} noPadding>
|
||||||
<nav
|
<nav
|
||||||
className="flex flex-col items-center w-screen px-6 py-3 space-x-4 space-y-3 sm:space-y-0 sm:flex-row lg:w-full"
|
className="flex w-screen flex-col items-center space-x-4 space-y-3 px-6 py-3 sm:flex-row sm:space-y-0 lg:w-full"
|
||||||
aria-label="Pagination"
|
aria-label="Pagination"
|
||||||
>
|
>
|
||||||
<div className="hidden lg:flex lg:flex-1">
|
<div className="hidden lg:flex lg:flex-1">
|
||||||
@@ -686,7 +686,7 @@ const UserList: React.FC = () => {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-center sm:flex-1 sm:justify-start lg:justify-center">
|
<div className="flex justify-center sm:flex-1 sm:justify-start lg:justify-center">
|
||||||
<span className="items-center -mt-3 text-sm sm:-ml-4 lg:ml-0 sm:mt-0">
|
<span className="-mt-3 items-center text-sm sm:-ml-4 sm:mt-0 lg:ml-0">
|
||||||
{intl.formatMessage(globalMessages.resultsperpage, {
|
{intl.formatMessage(globalMessages.resultsperpage, {
|
||||||
pageSize: (
|
pageSize: (
|
||||||
<select
|
<select
|
||||||
@@ -699,7 +699,7 @@ const UserList: React.FC = () => {
|
|||||||
.then(() => window.scrollTo(0, 0));
|
.then(() => window.scrollTo(0, 0));
|
||||||
}}
|
}}
|
||||||
value={currentPageSize}
|
value={currentPageSize}
|
||||||
className="inline short"
|
className="short inline"
|
||||||
>
|
>
|
||||||
<option value="5">5</option>
|
<option value="5">5</option>
|
||||||
<option value="10">10</option>
|
<option value="10">10</option>
|
||||||
@@ -711,7 +711,7 @@ const UserList: React.FC = () => {
|
|||||||
})}
|
})}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-center flex-auto space-x-2 sm:justify-end sm:flex-1">
|
<div className="flex flex-auto justify-center space-x-2 sm:flex-1 sm:justify-end">
|
||||||
<Button
|
<Button
|
||||||
disabled={!hasPrevPage}
|
disabled={!hasPrevPage}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
|
|||||||
@@ -40,11 +40,11 @@ const ProfileHeader: React.FC<ProfileHeaderProps> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative z-40 mt-6 mb-12 lg:flex lg:items-end lg:justify-between lg:space-x-5">
|
<div className="relative z-40 mt-6 mb-12 lg:flex lg:items-end lg:justify-between lg:space-x-5">
|
||||||
<div className="flex items-end space-x-5 justify-items-end">
|
<div className="flex items-end justify-items-end space-x-5">
|
||||||
<div className="flex-shrink-0">
|
<div className="flex-shrink-0">
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<img
|
<img
|
||||||
className="w-24 h-24 bg-gray-600 rounded-full ring-1 ring-gray-700"
|
className="h-24 w-24 rounded-full bg-gray-600 ring-1 ring-gray-700"
|
||||||
src={user.avatar}
|
src={user.avatar}
|
||||||
alt=""
|
alt=""
|
||||||
/>
|
/>
|
||||||
@@ -55,18 +55,18 @@ const ProfileHeader: React.FC<ProfileHeaderProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="pt-1.5">
|
<div className="pt-1.5">
|
||||||
<h1 className="flex flex-col mb-1 sm:items-center sm:flex-row">
|
<h1 className="mb-1 flex flex-col sm:flex-row sm:items-center">
|
||||||
<Link
|
<Link
|
||||||
href={
|
href={
|
||||||
user.id === loggedInUser?.id ? '/profile' : `/users/${user.id}`
|
user.id === loggedInUser?.id ? '/profile' : `/users/${user.id}`
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<a className="text-lg font-bold text-transparent sm:text-2xl bg-clip-text bg-gradient-to-br from-indigo-400 to-purple-400 hover:to-purple-200">
|
<a className="bg-gradient-to-br from-indigo-400 to-purple-400 bg-clip-text text-lg font-bold text-transparent hover:to-purple-200 sm:text-2xl">
|
||||||
{user.displayName}
|
{user.displayName}
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
{user.email && user.displayName.toLowerCase() !== user.email && (
|
{user.email && user.displayName.toLowerCase() !== user.email && (
|
||||||
<span className="text-sm text-gray-400 sm:text-lg sm:ml-2">
|
<span className="text-sm text-gray-400 sm:ml-2 sm:text-lg">
|
||||||
({user.email})
|
({user.email})
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
@@ -80,7 +80,7 @@ const ProfileHeader: React.FC<ProfileHeaderProps> = ({
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col-reverse mt-6 space-y-4 space-y-reverse justify-stretch lg:flex-row lg:justify-end lg:space-x-reverse lg:space-y-0 lg:space-x-3">
|
<div className="justify-stretch mt-6 flex flex-col-reverse space-y-4 space-y-reverse lg:flex-row lg:justify-end lg:space-y-0 lg:space-x-3 lg:space-x-reverse">
|
||||||
{(loggedInUser?.id === user.id ||
|
{(loggedInUser?.id === user.id ||
|
||||||
(user.id !== 1 && hasPermission(Permission.MANAGE_USERS))) &&
|
(user.id !== 1 && hasPermission(Permission.MANAGE_USERS))) &&
|
||||||
!isSettingsPage ? (
|
!isSettingsPage ? (
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ const UserGeneralSettings: React.FC = () => {
|
|||||||
{intl.formatMessage(messages.accounttype)}
|
{intl.formatMessage(messages.accounttype)}
|
||||||
</label>
|
</label>
|
||||||
<div className="mb-1 text-sm font-medium leading-5 text-gray-400 sm:mt-2">
|
<div className="mb-1 text-sm font-medium leading-5 text-gray-400 sm:mt-2">
|
||||||
<div className="flex items-center max-w-lg">
|
<div className="flex max-w-lg items-center">
|
||||||
{user?.userType === UserType.PLEX ? (
|
{user?.userType === UserType.PLEX ? (
|
||||||
<Badge badgeType="warning">
|
<Badge badgeType="warning">
|
||||||
{intl.formatMessage(messages.plexuser)}
|
{intl.formatMessage(messages.plexuser)}
|
||||||
@@ -178,7 +178,7 @@ const UserGeneralSettings: React.FC = () => {
|
|||||||
{intl.formatMessage(messages.role)}
|
{intl.formatMessage(messages.role)}
|
||||||
</label>
|
</label>
|
||||||
<div className="mb-1 text-sm font-medium leading-5 text-gray-400 sm:mt-2">
|
<div className="mb-1 text-sm font-medium leading-5 text-gray-400 sm:mt-2">
|
||||||
<div className="flex items-center max-w-lg">
|
<div className="flex max-w-lg items-center">
|
||||||
{user?.id === 1
|
{user?.id === 1
|
||||||
? intl.formatMessage(messages.owner)
|
? intl.formatMessage(messages.owner)
|
||||||
: hasPermission(Permission.ADMIN)
|
: hasPermission(Permission.ADMIN)
|
||||||
@@ -284,7 +284,7 @@ const UserGeneralSettings: React.FC = () => {
|
|||||||
</label>
|
</label>
|
||||||
<div className="form-input">
|
<div className="form-input">
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<div className="flex items-center mb-4">
|
<div className="mb-4 flex items-center">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
checked={movieQuotaEnabled}
|
checked={movieQuotaEnabled}
|
||||||
@@ -324,7 +324,7 @@ const UserGeneralSettings: React.FC = () => {
|
|||||||
</label>
|
</label>
|
||||||
<div className="form-input">
|
<div className="form-input">
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<div className="flex items-center mb-4">
|
<div className="mb-4 flex items-center">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
checked={tvQuotaEnabled}
|
checked={tvQuotaEnabled}
|
||||||
@@ -360,7 +360,7 @@ const UserGeneralSettings: React.FC = () => {
|
|||||||
)}
|
)}
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
type="submit"
|
type="submit"
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ const UserNotificationsDiscord: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
type="submit"
|
type="submit"
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ const UserEmailSettings: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
type="submit"
|
type="submit"
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ const UserPushbulletSettings: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
type="submit"
|
type="submit"
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ const UserPushoverSettings: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
type="submit"
|
type="submit"
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ const UserTelegramSettings: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
type="submit"
|
type="submit"
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ const UserWebPushSettings: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
type="submit"
|
type="submit"
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ const UserNotificationSettings: React.FC = ({ children }) => {
|
|||||||
text: intl.formatMessage(messages.email),
|
text: intl.formatMessage(messages.email),
|
||||||
content: (
|
content: (
|
||||||
<span className="flex items-center">
|
<span className="flex items-center">
|
||||||
<MailIcon className="h-4 mr-2" />
|
<MailIcon className="mr-2 h-4" />
|
||||||
{intl.formatMessage(messages.email)}
|
{intl.formatMessage(messages.email)}
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
@@ -47,7 +47,7 @@ const UserNotificationSettings: React.FC = ({ children }) => {
|
|||||||
text: intl.formatMessage(messages.webpush),
|
text: intl.formatMessage(messages.webpush),
|
||||||
content: (
|
content: (
|
||||||
<span className="flex items-center">
|
<span className="flex items-center">
|
||||||
<CloudIcon className="h-4 mr-2" />
|
<CloudIcon className="mr-2 h-4" />
|
||||||
{intl.formatMessage(messages.webpush)}
|
{intl.formatMessage(messages.webpush)}
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
@@ -59,7 +59,7 @@ const UserNotificationSettings: React.FC = ({ children }) => {
|
|||||||
text: 'Discord',
|
text: 'Discord',
|
||||||
content: (
|
content: (
|
||||||
<span className="flex items-center">
|
<span className="flex items-center">
|
||||||
<DiscordLogo className="h-4 mr-2" />
|
<DiscordLogo className="mr-2 h-4" />
|
||||||
Discord
|
Discord
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
@@ -70,7 +70,7 @@ const UserNotificationSettings: React.FC = ({ children }) => {
|
|||||||
text: 'Pushbullet',
|
text: 'Pushbullet',
|
||||||
content: (
|
content: (
|
||||||
<span className="flex items-center">
|
<span className="flex items-center">
|
||||||
<PushbulletLogo className="h-4 mr-2" />
|
<PushbulletLogo className="mr-2 h-4" />
|
||||||
Pushbullet
|
Pushbullet
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
@@ -81,7 +81,7 @@ const UserNotificationSettings: React.FC = ({ children }) => {
|
|||||||
text: 'Pushover',
|
text: 'Pushover',
|
||||||
content: (
|
content: (
|
||||||
<span className="flex items-center">
|
<span className="flex items-center">
|
||||||
<PushoverLogo className="h-4 mr-2" />
|
<PushoverLogo className="mr-2 h-4" />
|
||||||
Pushover
|
Pushover
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
@@ -92,7 +92,7 @@ const UserNotificationSettings: React.FC = ({ children }) => {
|
|||||||
text: 'Telegram',
|
text: 'Telegram',
|
||||||
content: (
|
content: (
|
||||||
<span className="flex items-center">
|
<span className="flex items-center">
|
||||||
<TelegramLogo className="h-4 mr-2" />
|
<TelegramLogo className="mr-2 h-4" />
|
||||||
Telegram
|
Telegram
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ const UserPasswordChange: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{data.hasPassword && user?.id === currentUser?.id && (
|
{data.hasPassword && user?.id === currentUser?.id && (
|
||||||
<div className="pb-6 form-row">
|
<div className="form-row pb-6">
|
||||||
<label htmlFor="currentPassword" className="text-label">
|
<label htmlFor="currentPassword" className="text-label">
|
||||||
{intl.formatMessage(messages.currentpassword)}
|
{intl.formatMessage(messages.currentpassword)}
|
||||||
</label>
|
</label>
|
||||||
@@ -222,7 +222,7 @@ const UserPasswordChange: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
type="submit"
|
type="submit"
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ const UserPermissions: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<span className="inline-flex ml-3 rounded-md shadow-sm">
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
<Button
|
<Button
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
type="submit"
|
type="submit"
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ const UserProfile: React.FC = () => {
|
|||||||
<>
|
<>
|
||||||
<PageTitle title={user.displayName} />
|
<PageTitle title={user.displayName} />
|
||||||
{Object.keys(availableTitles).length > 0 && (
|
{Object.keys(availableTitles).length > 0 && (
|
||||||
<div className="absolute left-0 right-0 z-0 -top-16 h-96">
|
<div className="absolute left-0 right-0 -top-16 z-0 h-96">
|
||||||
<ImageFader
|
<ImageFader
|
||||||
key={user.id}
|
key={user.id}
|
||||||
isDarker
|
isDarker
|
||||||
@@ -123,9 +123,9 @@ const UserProfile: React.FC = () => {
|
|||||||
{ type: 'and' }
|
{ type: 'and' }
|
||||||
)) && (
|
)) && (
|
||||||
<div className="relative z-40">
|
<div className="relative z-40">
|
||||||
<dl className="grid grid-cols-1 gap-5 mt-5 lg:grid-cols-3">
|
<dl className="mt-5 grid grid-cols-1 gap-5 lg:grid-cols-3">
|
||||||
<div className="px-4 py-5 overflow-hidden bg-gray-800 bg-opacity-50 rounded-lg shadow ring-1 ring-gray-700 sm:p-6">
|
<div className="overflow-hidden rounded-lg bg-gray-800 bg-opacity-50 px-4 py-5 shadow ring-1 ring-gray-700 sm:p-6">
|
||||||
<dt className="text-sm font-bold text-gray-300 truncate">
|
<dt className="truncate text-sm font-bold text-gray-300">
|
||||||
{intl.formatMessage(messages.totalrequests)}
|
{intl.formatMessage(messages.totalrequests)}
|
||||||
</dt>
|
</dt>
|
||||||
<dd className="mt-1 text-3xl font-semibold text-white">
|
<dd className="mt-1 text-3xl font-semibold text-white">
|
||||||
@@ -133,14 +133,14 @@ const UserProfile: React.FC = () => {
|
|||||||
</dd>
|
</dd>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={`px-4 py-5 overflow-hidden bg-gray-800 bg-opacity-50 rounded-lg shadow ring-1 ${
|
className={`overflow-hidden rounded-lg bg-gray-800 bg-opacity-50 px-4 py-5 shadow ring-1 ${
|
||||||
quota.movie.restricted
|
quota.movie.restricted
|
||||||
? 'ring-red-500 from-red-900 to-transparent bg-gradient-to-t'
|
? 'bg-gradient-to-t from-red-900 to-transparent ring-red-500'
|
||||||
: 'ring-gray-700'
|
: 'ring-gray-700'
|
||||||
} sm:p-6`}
|
} sm:p-6`}
|
||||||
>
|
>
|
||||||
<dt
|
<dt
|
||||||
className={`text-sm font-bold truncate ${
|
className={`truncate text-sm font-bold ${
|
||||||
quota.movie.restricted ? 'text-red-500' : 'text-gray-300'
|
quota.movie.restricted ? 'text-red-500' : 'text-gray-300'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
@@ -152,7 +152,7 @@ const UserProfile: React.FC = () => {
|
|||||||
: intl.formatMessage(messages.movierequests)}
|
: intl.formatMessage(messages.movierequests)}
|
||||||
</dt>
|
</dt>
|
||||||
<dd
|
<dd
|
||||||
className={`flex mt-1 text-sm items-center ${
|
className={`mt-1 flex items-center text-sm ${
|
||||||
quota.movie.restricted ? 'text-red-500' : 'text-white'
|
quota.movie.restricted ? 'text-red-500' : 'text-white'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
@@ -165,7 +165,7 @@ const UserProfile: React.FC = () => {
|
|||||||
100
|
100
|
||||||
)}
|
)}
|
||||||
useHeatLevel
|
useHeatLevel
|
||||||
className="w-8 h-8 mr-2"
|
className="mr-2 h-8 w-8"
|
||||||
/>
|
/>
|
||||||
<div>
|
<div>
|
||||||
{intl.formatMessage(messages.requestsperdays, {
|
{intl.formatMessage(messages.requestsperdays, {
|
||||||
@@ -188,14 +188,14 @@ const UserProfile: React.FC = () => {
|
|||||||
</dd>
|
</dd>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={`px-4 py-5 overflow-hidden bg-gray-800 bg-opacity-50 rounded-lg shadow ring-1 ${
|
className={`overflow-hidden rounded-lg bg-gray-800 bg-opacity-50 px-4 py-5 shadow ring-1 ${
|
||||||
quota.tv.restricted
|
quota.tv.restricted
|
||||||
? 'ring-red-500 from-red-900 to-transparent bg-gradient-to-t'
|
? 'bg-gradient-to-t from-red-900 to-transparent ring-red-500'
|
||||||
: 'ring-gray-700'
|
: 'ring-gray-700'
|
||||||
} sm:p-6`}
|
} sm:p-6`}
|
||||||
>
|
>
|
||||||
<dt
|
<dt
|
||||||
className={`text-sm font-bold truncate ${
|
className={`truncate text-sm font-bold ${
|
||||||
quota.tv.restricted ? 'text-red-500' : 'text-gray-300'
|
quota.tv.restricted ? 'text-red-500' : 'text-gray-300'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
@@ -207,7 +207,7 @@ const UserProfile: React.FC = () => {
|
|||||||
: intl.formatMessage(messages.seriesrequest)}
|
: intl.formatMessage(messages.seriesrequest)}
|
||||||
</dt>
|
</dt>
|
||||||
<dd
|
<dd
|
||||||
className={`flex items-center mt-1 text-sm ${
|
className={`mt-1 flex items-center text-sm ${
|
||||||
quota.tv.restricted ? 'text-red-500' : 'text-white'
|
quota.tv.restricted ? 'text-red-500' : 'text-white'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
@@ -220,7 +220,7 @@ const UserProfile: React.FC = () => {
|
|||||||
100
|
100
|
||||||
)}
|
)}
|
||||||
useHeatLevel
|
useHeatLevel
|
||||||
className="w-8 h-8 mr-2"
|
className="mr-2 h-8 w-8"
|
||||||
/>
|
/>
|
||||||
<div>
|
<div>
|
||||||
{intl.formatMessage(messages.requestsperdays, {
|
{intl.formatMessage(messages.requestsperdays, {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user