feat: add divider between buttons and form on login page

pull/3015/head
sct 2 years ago
parent 2ca573d73e
commit 7f3dbd4e84
No known key found for this signature in database

@ -1,72 +0,0 @@
import type * as React from 'react';
import { useState } from 'react';
import AnimateHeight from 'react-animate-height';
export interface AccordionProps {
children: (args: AccordionChildProps) => JSX.Element;
/** If true, only one accordion item can be open at any time */
single?: boolean;
/** If true, at least one accordion item will always be open */
atLeastOne?: boolean;
initialOpenIndexes?: number[];
}
export interface AccordionChildProps {
openIndexes: number[];
handleClick(index: number): void;
AccordionContent: typeof AccordionContent;
}
type AccordionContentProps = {
isOpen: boolean;
children: React.ReactNode;
};
export const AccordionContent = ({
isOpen,
children,
}: AccordionContentProps) => {
return <AnimateHeight height={isOpen ? 'auto' : 0}>{children}</AnimateHeight>;
};
const Accordion = ({
single,
atLeastOne,
initialOpenIndexes,
children,
}: AccordionProps) => {
const initialState = initialOpenIndexes || (atLeastOne && [0]) || [];
const [openIndexes, setOpenIndexes] = useState<number[]>(initialState);
const close = (index: number) => {
const openCount = openIndexes.length;
const newListOfIndexes =
atLeastOne && openCount === 1 && openIndexes.includes(index)
? openIndexes
: openIndexes.filter((i) => i !== index);
setOpenIndexes(newListOfIndexes);
};
const open = (index: number) => {
const newListOfIndexes = single ? [index] : [...openIndexes, index];
setOpenIndexes(newListOfIndexes);
};
const handleItemClick = (index: number) => {
const action = openIndexes.includes(index) ? 'closing' : 'opening';
if (action === 'closing') {
close(index);
} else {
open(index);
}
};
return children({
openIndexes: openIndexes,
handleClick: handleItemClick,
AccordionContent,
});
};
export default Accordion;

@ -76,85 +76,84 @@ const LocalLogin = ({ onError }: LocalLoginProps) => {
>
{({ errors, touched, isSubmitting, isValid }) => {
return (
<>
<Form>
<div>
<label htmlFor="email" className="text-label">
{intl.formatMessage(messages.email)}
</label>
<div className="mt-1 mb-2 sm:col-span-2 sm:mt-0">
<div className="form-input-field">
<Field
id="email"
name="email"
type="text"
inputMode="email"
data-testid="email"
/>
</div>
{errors.email &&
touched.email &&
typeof errors.email === 'string' && (
<div className="error">{errors.email}</div>
)}
<Form>
<div>
<label htmlFor="email" className="text-label">
{intl.formatMessage(messages.email)}
</label>
<div className="mt-1 mb-2 sm:col-span-2 sm:mt-0">
<div className="form-input-field">
<Field
id="email"
name="email"
type="text"
inputMode="email"
data-testid="email"
/>
</div>
<label htmlFor="password" className="text-label">
{intl.formatMessage(messages.password)}
</label>
<div className="mt-1 mb-2 sm:col-span-2 sm:mt-0">
<div className="form-input-field">
<SensitiveInput
as="field"
id="password"
name="password"
type="password"
autoComplete="current-password"
data-testid="password"
data-1pignore="false"
data-lpignore="false"
data-bwignore="false"
/>
</div>
{errors.password &&
touched.password &&
typeof errors.password === 'string' && (
<div className="error">{errors.password}</div>
)}
{errors.email &&
touched.email &&
typeof errors.email === 'string' && (
<div className="error">{errors.email}</div>
)}
</div>
<label htmlFor="password" className="text-label">
{intl.formatMessage(messages.password)}
</label>
<div className="mt-1 mb-2 sm:col-span-2 sm:mt-0">
<div className="form-input-field">
<SensitiveInput
as="field"
id="password"
name="password"
type="password"
autoComplete="current-password"
data-testid="password"
data-1pignore="false"
data-lpignore="false"
data-bwignore="false"
/>
</div>
{errors.password &&
touched.password &&
typeof errors.password === 'string' && (
<div className="error">{errors.password}</div>
)}
</div>
<div className="mt-8 border-t border-gray-700 pt-5">
<div className="flex flex-row-reverse justify-between">
</div>
<div className="mt-8 border-t border-gray-700 pt-5">
<div className="flex flex-row-reverse justify-between">
<span className="inline-flex rounded-md shadow-sm">
<Button
buttonType="primary"
type="submit"
disabled={isSubmitting || !isValid}
data-testid="local-signin-button"
>
<LoginIcon />
<span>
{isSubmitting
? intl.formatMessage(messages.signingin)
: intl.formatMessage(messages.signin)}
</span>
</Button>
</span>
{passwordResetEnabled && (
<span className="inline-flex rounded-md shadow-sm">
<Button
buttonType="primary"
type="submit"
disabled={isSubmitting || !isValid}
data-testid="local-signin-button"
>
<ArrowLeftOnRectangleIcon />
<span>
{isSubmitting
? intl.formatMessage(messages.signingin)
: intl.formatMessage(messages.signin)}
</span>
</Button>
<Link href="/resetpassword" passHref>
<Button as="a" buttonType="ghost">
<SupportIcon />
<span>
{intl.formatMessage(messages.forgotpassword)}
</span>
</Button>
</Link>
</span>
{passwordResetEnabled && (
<span className="inline-flex rounded-md shadow-sm">
<Link href="/resetpassword" passHref>
<Button as="a" buttonType="ghost">
<LifebuoyIcon />
<span>
{intl.formatMessage(messages.forgotpassword)}
</span>
</Button>
</Link>
</span>
)}
</div>
)}
</div>
</Form>
</>
</div>
</Form>
);
}}
</Formik>

@ -49,7 +49,7 @@ const Login = () => {
</div>
<div className="relative z-50 mt-8 sm:mx-auto sm:w-full sm:max-w-md">
<div
className="flex flex-col space-y-4 bg-gray-800 bg-opacity-50 p-4 shadow sm:rounded-lg "
className="flex flex-col bg-gray-800 bg-opacity-50 p-4 shadow sm:rounded-lg "
style={{ backdropFilter: 'blur(5px)' }}
>
<>
@ -79,61 +79,17 @@ const Login = () => {
{settings.currentSettings.plexLoginEnabled && (
<PlexLogin onError={(msg) => setError(msg)} />
)}
{settings.currentSettings.plexLoginEnabled &&
settings.currentSettings.localLogin && (
<div className="relative flex items-center py-4">
<div className="flex-grow border-t border-gray-500"></div>
<span className="mx-4 flex-shrink text-gray-400">or</span>
<div className="flex-grow border-t border-gray-500"></div>
</div>
)}
{settings.currentSettings.localLogin && (
<LocalLogin onError={(msg) => setError(msg)} />
)}
{/* <Accordion single atLeastOne>
{({ openIndexes, handleClick, AccordionContent }) => (
<>
{settings.currentSettings.plexLoginEnabled && (
<>
<button
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'
} ${
settings.currentSettings.localLogin &&
'hover:cursor-pointer hover:bg-gray-700'
}`}
onClick={() => handleClick(0)}
disabled={!settings.currentSettings.localLogin}
>
{intl.formatMessage(messages.signinwithplex)}
</button>
<AccordionContent isOpen={openIndexes.includes(0)}>
<div className="px-10 py-8">
<PlexLoginButton
isProcessing={isProcessing}
onAuthToken={(authToken) => setAuthToken(authToken)}
/>
</div>
</AccordionContent>
</>
)}
{settings.currentSettings.localLogin && (
<div>
<button
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)
? 'text-indigo-500'
: 'sm:rounded-b-lg'
}`}
onClick={() => handleClick(1)}
>
{intl.formatMessage(messages.signinwithoverseerr, {
applicationTitle:
settings.currentSettings.applicationTitle,
})}
</button>
<AccordionContent isOpen={openIndexes.includes(1)}>
<div className="px-10 py-8">
<LocalLogin revalidate={revalidate} />
</div>
</AccordionContent>
</div>
)}
</>
)}
</Accordion> */}
</>
</div>
</div>

@ -5254,11 +5254,6 @@ cidr-regex@^3.1.1:
dependencies:
ip-regex "^4.1.0"
classnames@^2.2.5:
version "2.3.2"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924"
integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==
clean-stack@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b"
@ -11284,7 +11279,7 @@ promzard@^0.3.0:
dependencies:
read "1"
prop-types@^15.0.0, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
prop-types@^15.0.0, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@ -11543,54 +11538,6 @@ react-ace@10.1.0:
lodash.isequal "^4.5.0"
prop-types "^15.7.2"
react-animate-height@2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/react-animate-height/-/react-animate-height-2.1.2.tgz#9b450fc64d46f10f5e07da8d0d5e2c47b9f15030"
integrity sha512-A9jfz/4CTdsIsE7WCQtO9UkOpMBcBRh8LxyHl2eoZz1ki02jpyUL5xt58gabd0CyeLQ8fRyQ+s2lyV2Ufu8Owg==
dependencies:
classnames "^2.2.5"
prop-types "^15.6.1"
react-aria@3.23.0:
version "3.23.0"
resolved "https://registry.yarnpkg.com/react-aria/-/react-aria-3.23.0.tgz#8829ae47373793a7b48e19aa8af1b581021b2a9a"
integrity sha512-CMem/+XnL3yuNHU94usRHS2+rdKLuyUzxRmQ/ndVXresflzKdaLYCH7Dtb2Um4rUEjD0BCz33hiNZPsJ7jBVQQ==
dependencies:
"@react-aria/breadcrumbs" "^3.5.0"
"@react-aria/button" "^3.7.0"
"@react-aria/calendar" "^3.1.0"
"@react-aria/checkbox" "^3.8.0"
"@react-aria/combobox" "^3.5.0"
"@react-aria/datepicker" "^3.3.0"
"@react-aria/dialog" "^3.5.0"
"@react-aria/dnd" "^3.1.0"
"@react-aria/focus" "^3.11.0"
"@react-aria/gridlist" "^3.2.0"
"@react-aria/i18n" "^3.7.0"
"@react-aria/interactions" "^3.14.0"
"@react-aria/label" "^3.5.0"
"@react-aria/link" "^3.4.0"
"@react-aria/listbox" "^3.8.0"
"@react-aria/menu" "^3.8.0"
"@react-aria/meter" "^3.4.0"
"@react-aria/numberfield" "^3.4.0"
"@react-aria/overlays" "^3.13.0"
"@react-aria/progress" "^3.4.0"
"@react-aria/radio" "^3.5.0"
"@react-aria/searchfield" "^3.5.0"
"@react-aria/select" "^3.9.0"
"@react-aria/selection" "^3.13.0"
"@react-aria/separator" "^3.3.0"
"@react-aria/slider" "^3.3.0"
"@react-aria/ssr" "^3.5.0"
"@react-aria/switch" "^3.4.0"
"@react-aria/table" "^3.8.0"
"@react-aria/tabs" "^3.4.0"
"@react-aria/textfield" "^3.9.0"
"@react-aria/tooltip" "^3.4.0"
"@react-aria/utils" "^3.15.0"
"@react-aria/visually-hidden" "^3.7.0"
react-dom@18.2.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"

Loading…
Cancel
Save