Dark mode login screens (#2483)

* multi-user auth screen ui update

* dark mode login screen + recovery key modals

* remove unneeded import
This commit is contained in:
Sean Hatfield 2024-10-15 14:41:23 -07:00 committed by GitHub
parent 79898610cc
commit 66a81c21b7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 93 additions and 81 deletions

View File

@ -2,6 +2,7 @@ import showToast from "@/utils/toast";
import { DownloadSimple, Key } from "@phosphor-icons/react";
import { saveAs } from "file-saver";
import { useState } from "react";
import ModalWrapper from "@/components/ModalWrapper";
export default function RecoveryCodeModal({
recoveryCodes,
@ -32,55 +33,59 @@ export default function RecoveryCodeModal({
};
return (
<div className="inline-block bg-secondary rounded-lg text-left overflow-hidden shadow-xl transform transition-all border-2 border-[#BCC9DB]/10 w-[600px] mx-4">
<div className="md:py-[35px] md:px-[50px] py-[28px] px-[20px]">
<div className="flex gap-x-2">
<Key size={24} className="text-white" weight="bold" />
<h3
className="text-lg leading-6 font-medium text-white"
id="modal-headline"
>
Recovery Codes
</h3>
<ModalWrapper isOpen={true}>
<div className="w-full max-w-2xl bg-theme-bg-secondary rounded-lg shadow border-2 border-theme-modal-border overflow-hidden">
<div className="relative p-6 border-b rounded-t border-theme-modal-border">
<div className="w-full flex gap-x-2 items-center">
<Key size={24} className="text-white" weight="bold" />
<h3 className="text-xl font-semibold text-white overflow-hidden overflow-ellipsis whitespace-nowrap">
Recovery Codes
</h3>
</div>
</div>
<div className="mt-4">
<p className="text-sm text-white flex flex-col">
In order to reset your password in the future, you will need these
recovery codes. Download or copy your recovery codes to save them.{" "}
<br />
<b className="mt-4">These recovery codes are only shown once!</b>
</p>
<div
className="bg-dark-highlight text-white hover:text-primary-button
flex items-center justify-center rounded-md mt-6 cursor-pointer"
onClick={handleCopyToClipboard}
>
<ul className="space-y-2 md:p-6 p-4">
{recoveryCodes.map((code, index) => (
<li key={index} className="md:text-sm text-xs">
{code}
</li>
))}
</ul>
<div
className="h-full w-full overflow-y-auto"
style={{ maxHeight: "calc(100vh - 200px)" }}
>
<div className="py-7 px-9 space-y-2 flex-col">
<p className="text-sm text-white flex flex-col">
In order to reset your password in the future, you will need these
recovery codes. Download or copy your recovery codes to save them.{" "}
<br />
<b className="mt-4">These recovery codes are only shown once!</b>
</p>
<div
className="bg-theme-settings-input-bg text-white hover:text-primary-button
flex items-center justify-center rounded-md mt-6 cursor-pointer"
onClick={handleCopyToClipboard}
>
<ul className="space-y-2 md:p-6 p-4">
{recoveryCodes.map((code, index) => (
<li key={index} className="md:text-sm text-xs">
{code}
</li>
))}
</ul>
</div>
</div>
<div className="flex w-full justify-end items-center p-6 space-x-2 border-t border-theme-modal-border rounded-b">
<button
type="button"
className="transition-all duration-300 bg-white text-black hover:opacity-60 px-4 py-2 rounded-lg text-sm flex items-center gap-x-2"
onClick={downloadClicked ? handleClose : downloadRecoveryCodes}
>
{downloadClicked ? (
"Close"
) : (
<>
<DownloadSimple weight="bold" size={18} />
<p>Download</p>
</>
)}
</button>
</div>
</div>
</div>
<div className="flex w-full justify-center items-center p-3 space-x-2 rounded-b border-gray-500/50 -mt-4 mb-4">
<button
type="button"
className="transition-all duration-300 text-xs md:w-[500px] md:h-[34px] h-[48px] w-full m-2 font-semibold rounded-lg bg-primary-button hover:bg-secondary border-2 border-transparent hover:border-primary-button hover:text-white whitespace-nowrap shadow-[0_4px_14px_rgba(0,0,0,0.25)] flex justify-center items-center gap-x-2"
onClick={downloadClicked ? handleClose : downloadRecoveryCodes}
>
{downloadClicked ? (
"Close"
) : (
<>
<DownloadSimple weight="bold" size={18} />
<p>Download</p>
</>
)}
</button>
</div>
</div>
</ModalWrapper>
);
}

View File

@ -32,7 +32,7 @@ const RecoveryForm = ({ onSubmit, setShowRecoveryForm }) => {
return (
<form
onSubmit={handleSubmit}
className="flex flex-col justify-center items-center relative rounded-2xl md:bg-login-gradient md:shadow-[0_4px_14px_rgba(0,0,0,0.25)] md:px-8 px-0 py-4 w-full md:w-fit mt-10 md:mt-0"
className="flex flex-col justify-center items-center relative rounded-2xl bg-theme-bg-secondary md:shadow-[0_4px_14px_rgba(0,0,0,0.25)] md:px-8 px-0 py-4 w-full md:w-fit mt-10 md:mt-0"
>
<div className="flex items-start justify-between pt-11 pb-9 w-screen md:w-full md:px-12 px-6 ">
<div className="flex flex-col gap-y-4 w-full">
@ -56,7 +56,7 @@ const RecoveryForm = ({ onSubmit, setShowRecoveryForm }) => {
placeholder={t("login.multi-user.placeholder-username")}
value={username}
onChange={(e) => setUsername(e.target.value)}
className="bg-zinc-900 text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-md p-2.5 w-full h-[48px] md:w-[300px] md:h-[34px]"
className="bg-theme-settings-input-bg text-theme-text-primary placeholder:text-theme-settings-input-placeholder focus:outline-primary-button active:outline-primary-button outline-none text-sm rounded-md p-2.5 w-full h-[48px] md:w-[300px] md:h-[34px]"
required
/>
</div>
@ -76,7 +76,7 @@ const RecoveryForm = ({ onSubmit, setShowRecoveryForm }) => {
onChange={(e) =>
handleRecoveryCodeChange(index, e.target.value)
}
className="bg-zinc-900 text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-md p-2.5 w-full h-[48px] md:w-[300px] md:h-[34px]"
className="bg-theme-settings-input-bg text-theme-text-primary placeholder:text-theme-settings-input-placeholder focus:outline-primary-button active:outline-primary-button outline-none text-sm rounded-md p-2.5 w-full h-[48px] md:w-[300px] md:h-[34px]"
required
/>
</div>
@ -115,7 +115,7 @@ const ResetPasswordForm = ({ onSubmit }) => {
return (
<form
onSubmit={handleSubmit}
className="flex flex-col justify-center items-center relative rounded-2xl md:bg-login-gradient md:shadow-[0_4px_14px_rgba(0,0,0,0.25)] md:px-12 px-0 py-4 w-full md:w-fit -mt-24 md:-mt-28"
className="flex flex-col justify-center items-center relative rounded-2xl bg-theme-bg-secondary md:shadow-[0_4px_14px_rgba(0,0,0,0.25)] md:px-12 px-0 py-4 w-full md:w-fit -mt-24 md:-mt-28"
>
<div className="flex items-start justify-between pt-11 pb-9 w-screen md:w-full md:px-12 px-6">
<div className="flex flex-col gap-y-4 w-full">
@ -281,7 +281,7 @@ export default function MultiUserAuth() {
return (
<>
<form onSubmit={handleLogin}>
<div className="flex flex-col justify-center items-center relative rounded-2xl md:bg-login-gradient md:shadow-[0_4px_14px_rgba(0,0,0,0.25)] md:px-12 py-12 -mt-4 md:mt-0">
<div className="flex flex-col justify-center items-center relative rounded-2xl bg-theme-bg-secondary md:shadow-[0_4px_14px_rgba(0,0,0,0.25)] md:px-12 py-12 -mt-4 md:mt-0">
<div className="flex items-start justify-between pt-11 pb-9 rounded-t">
<div className="flex items-center flex-col gap-y-4">
<div className="flex gap-x-1">
@ -292,7 +292,7 @@ export default function MultiUserAuth() {
{customAppName || "AnythingLLM"}
</p>
</div>
<p className="text-sm text-white/90 text-center">
<p className="text-sm text-theme-text-secondary text-center">
{t("login.sign-in.start")} {customAppName || "AnythingLLM"}{" "}
{t("login.sign-in.end")}
</p>
@ -305,7 +305,7 @@ export default function MultiUserAuth() {
name="username"
type="text"
placeholder={t("login.multi-user.placeholder-username")}
className="bg-zinc-900 text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-md p-2.5 w-full h-[48px] md:w-[300px] md:h-[34px]"
className="bg-theme-settings-input-bg text-theme-text-primary placeholder:text-theme-settings-input-placeholder focus:outline-primary-button active:outline-primary-button outline-none text-sm rounded-md p-2.5 w-full h-[48px] md:w-[300px] md:h-[34px]"
required={true}
autoComplete="off"
/>
@ -315,7 +315,7 @@ export default function MultiUserAuth() {
name="password"
type="password"
placeholder={t("login.multi-user.placeholder-password")}
className="bg-zinc-900 text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-md p-2.5 w-full h-[48px] md:w-[300px] md:h-[34px]"
className="bg-theme-settings-input-bg text-theme-text-primary placeholder:text-theme-settings-input-placeholder focus:outline-primary-button active:outline-primary-button outline-none text-sm rounded-md p-2.5 w-full h-[48px] md:w-[300px] md:h-[34px]"
required={true}
autoComplete="off"
/>

View File

@ -70,7 +70,7 @@ export default function SingleUserAuth() {
return (
<>
<form onSubmit={handleLogin}>
<div className="flex flex-col justify-center items-center relative rounded-2xl md:bg-login-gradient md:shadow-[0_4px_14px_rgba(0,0,0,0.25)] md:px-12 py-12 -mt-36 md:-mt-10">
<div className="flex flex-col justify-center items-center relative rounded-2xl bg-theme-bg-secondary md:shadow-[0_4px_14px_rgba(0,0,0,0.25)] md:px-12 py-12 -mt-36 md:-mt-10">
<div className="flex items-start justify-between pt-11 pb-9 rounded-t">
<div className="flex items-center flex-col gap-y-4">
<div className="flex gap-x-1">
@ -81,7 +81,7 @@ export default function SingleUserAuth() {
{customAppName || "AnythingLLM"}
</p>
</div>
<p className="text-sm text-white/90 text-center">
<p className="text-sm text-theme-text-secondary text-center">
{t("login.sign-in.start")} {customAppName || "AnythingLLM"}{" "}
{t("login.sign-in.end")}
</p>
@ -94,12 +94,11 @@ export default function SingleUserAuth() {
name="password"
type="password"
placeholder="Password"
className="bg-zinc-900 text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-md p-2.5 w-full h-[48px] md:w-[300px] md:h-[34px]"
className="bg-theme-settings-input-bg text-theme-text-primary placeholder:text-theme-settings-input-placeholder focus:outline-primary-button active:outline-primary-button outline-none text-sm rounded-md p-2.5 w-full h-[48px] md:w-[300px] md:h-[34px]"
required={true}
autoComplete="off"
/>
</div>
{error && <p className="text-red-400 text-sm">Error: {error}</p>}
</div>
</div>
@ -109,13 +108,13 @@ export default function SingleUserAuth() {
type="submit"
className="md:text-primary-button md:bg-transparent text-dark-text text-sm font-bold focus:ring-4 focus:outline-none rounded-md border-[1.5px] border-primary-button md:h-[34px] h-[48px] md:hover:text-white md:hover:bg-primary-button bg-primary-button focus:z-10 w-full"
>
{loading ? "Validating..." : "Login"}
{loading ? t("login.multi-user.validating") : t("login.multi-user.login")}
</button>
</div>
</div>
</form>
<ModalWrapper isOpen={isRecoveryCodeModalOpen}>
<ModalWrapper isOpen={isRecoveryCodeModalOpen} noPortal={true}>
<RecoveryCodeModal
recoveryCodes={recoveryCodes}
onDownloadComplete={handleDownloadComplete}

View File

@ -13,7 +13,7 @@ import illustration from "@/media/illustrations/login-illustration.svg";
export default function PasswordModal({ mode = "single" }) {
const { loginLogo } = useLogo();
return (
<div className="fixed top-0 left-0 right-0 z-50 w-full overflow-x-hidden overflow-y-auto md:inset-0 h-[calc(100%-1rem)] h-full bg-[#25272C] flex flex-col md:flex-row items-center justify-center">
<div className="fixed top-0 left-0 right-0 z-50 w-full overflow-x-hidden overflow-y-auto md:inset-0 h-[calc(100%-1rem)] h-full bg-theme-bg-primary flex flex-col md:flex-row items-center justify-center">
<div
style={{
background: `
@ -33,13 +33,13 @@ export default function PasswordModal({ mode = "single" }) {
alt="login illustration"
/>
</div>
<div className="flex flex-col items-center justify-center h-full w-full md:w-1/2 z-50 relative -mt-20">
<div className="flex flex-col items-center justify-center h-full w-full md:w-1/2 z-50 relative md:-mt-20 mt-0 bg-theme-bg-secondary md:bg-transparent">
<img
src={loginLogo}
alt="Logo"
className={`hidden relative md:flex rounded-2xl w-fit m-4 z-30 ${
mode === "single" ? "md:top-2" : "md:top-12"
} absolute max-h-[65px] md:bg-login-gradient md:shadow-[0_4px_14px_rgba(0,0,0,0.25)]`}
} absolute max-h-[65px]`}
style={{ objectFit: "contain" }}
/>
{mode === "single" ? <SingleUserAuth /> : <MultiUserAuth />}

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 10 KiB