mirror of
https://github.com/Mintplex-Labs/anything-llm.git
synced 2024-11-19 04:30:10 +01:00
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:
parent
79898610cc
commit
66a81c21b7
@ -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>
|
||||
);
|
||||
}
|
||||
|
@ -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"
|
||||
/>
|
||||
|
@ -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}
|
||||
|
@ -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 |
Loading…
Reference in New Issue
Block a user