Files
channels-seerr/src/components/Setup/SetupLogin.tsx
Michael Thomas 73d8efaa54 feat: revamp login page and support disabling media server login (#1286)
* feat: support disabling jellyfin login

* feat: revamp login screen

Update the login screen for better usability, especially with OpenID
Connect and Plex login, allowing one-click login and removing the
accordion layout. Additionally, ensures that media server login is
hidden when disabled in the settings.

* test: update cypress login command
2025-02-23 00:40:38 +08:00

121 lines
3.6 KiB
TypeScript

import Button from '@app/components/Common/Button';
import PlexLoginButton from '@app/components/Login/PlexLoginButton';
import JellyfinSetup from '@app/components/Setup/JellyfinSetup';
import { useUser } from '@app/hooks/useUser';
import defineMessages from '@app/utils/defineMessages';
import { MediaServerType } from '@server/constants/server';
import { useEffect, useState } from 'react';
import { FormattedMessage } from 'react-intl';
const messages = defineMessages('components.Setup', {
welcome: 'Welcome to Jellyseerr',
signinMessage: 'Get started by signing in',
signin: 'Sign in to your account',
signinWithJellyfin: 'Enter your Jellyfin details',
signinWithEmby: 'Enter your Emby details',
signinWithPlex: 'Enter your Plex details',
back: 'Go back',
});
interface LoginWithMediaServerProps {
serverType: MediaServerType;
onCancel: () => void;
onComplete: () => void;
}
const SetupLogin: React.FC<LoginWithMediaServerProps> = ({
serverType,
onCancel,
onComplete,
}) => {
const [authToken, setAuthToken] = useState<string | undefined>(undefined);
const [mediaServerType, setMediaServerType] = useState<MediaServerType>(
MediaServerType.NOT_CONFIGURED
);
const { user, revalidate } = useUser();
// Effect that is triggered when the `authToken` comes back from the Plex OAuth
// We take the token and attempt to login. If we get a success message, we will
// ask swr to revalidate the user which _shouid_ come back with a valid user.
useEffect(() => {
const login = async () => {
const res = await fetch('/api/v1/auth/plex', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
authToken: authToken,
}),
});
if (!res.ok) throw new Error();
const data = await res.json();
if (data?.email) {
revalidate();
}
};
if (authToken && mediaServerType == MediaServerType.PLEX) {
login();
}
}, [authToken, mediaServerType, revalidate]);
useEffect(() => {
if (user) {
onComplete();
}
}, [user, mediaServerType, onComplete]);
return (
<div className="p-4">
<div className="mb-2 flex justify-center text-xl font-bold">
<FormattedMessage {...messages.signin} />
</div>
<div className="mb-2 flex justify-center pb-6 text-sm">
{serverType === MediaServerType.JELLYFIN ? (
<FormattedMessage {...messages.signinWithJellyfin} />
) : serverType === MediaServerType.EMBY ? (
<FormattedMessage {...messages.signinWithEmby} />
) : (
<FormattedMessage {...messages.signinWithPlex} />
)}
</div>
{serverType === MediaServerType.PLEX && (
<>
<div className="flex justify-center bg-black/30 px-10 py-8">
<PlexLoginButton
large
onAuthToken={(authToken) => {
setMediaServerType(MediaServerType.PLEX);
setAuthToken(authToken);
}}
/>
</div>
<div className="mt-4">
<Button buttonType="default" onClick={() => onCancel()}>
<FormattedMessage {...messages.back} />
</Button>
</div>
</>
)}
{serverType === MediaServerType.JELLYFIN && (
<JellyfinSetup
revalidate={revalidate}
serverType={serverType}
onCancel={onCancel}
/>
)}
{serverType === MediaServerType.EMBY && (
<JellyfinSetup
revalidate={revalidate}
serverType={serverType}
onCancel={onCancel}
/>
)}
</div>
);
};
export default SetupLogin;