Implement password reset process

This commit is contained in:
grimsi
2024-09-22 11:34:22 +02:00
parent a993b8a488
commit ae56793e6e
17 changed files with 340 additions and 52 deletions
@@ -58,23 +58,22 @@ function NotificationManagementLayout({getConfig, getConfigs, formik}: any) {
<div className="flex flex-col">
<div className="flex flex-row">
<div className="flex flex-col flex-1">
<ConfigFormField configElement={getConfig("notifications.enabled")}/>
<div className="flex flex-row gap-8">
<div className="flex flex-col flex-1">
<Section title="E-Mail"/>
<ConfigFormField configElement={getConfig("notifications.providers.email.enabled")}/>
<ConfigFormField configElement={getConfig("notifications.providers.email.host")}
isDisabled={!formik.values.notifications.enabled}/>
isDisabled={!formik.values.notifications.providers.email.enabled}/>
<ConfigFormField configElement={getConfig("notifications.providers.email.port")}
isDisabled={!formik.values.notifications.enabled}/>
isDisabled={!formik.values.notifications.providers.email.enabled}/>
<ConfigFormField configElement={getConfig("notifications.providers.email.username")}
isDisabled={!formik.values.notifications.enabled}/>
isDisabled={!formik.values.notifications.providers.email.enabled}/>
<ConfigFormField configElement={getConfig("notifications.providers.email.password")}
type="password"
isDisabled={!formik.values.notifications.enabled}/>
isDisabled={!formik.values.notifications.providers.email.enabled}/>
<Button onPress={() => verifyCredentials("email")}
isDisabled={!(
formik.values.notifications.enabled &&
formik.values.notifications.providers.email.enabled &&
formik.values.notifications.providers.email.host &&
formik.values.notifications.providers.email.port &&
formik.values.notifications.providers.email.username)}>Test</Button>
@@ -83,7 +82,7 @@ function NotificationManagementLayout({getConfig, getConfigs, formik}: any) {
<Section title="Message Templates"/>
<div className="flex flex-col gap-4">
{getConfigs("notifications.templates").map((template: ConfigEntryDto) =>
<Card className="flex flex-row items-center gap-2 p-4">
<Card className="flex flex-row items-center gap-2 p-4" key={template.key}>
<Button isIconOnly
size="sm"
onPress={() => openModal(template)}
@@ -7,7 +7,7 @@ const CheckboxInput = ({label, ...props}) => {
const [field] = useField(props);
return (
<div className="flex flex-row flex-1 items-center gap-2">
<div className="flex flex-row flex-1 items-center gap-2 mb-2">
<Checkbox
{...field}
{...props}
+58 -2
View File
@@ -1,17 +1,36 @@
import {useAuth} from "Frontend/util/auth";
import {useLayoutEffect, useState} from "react";
import {XCircle} from "@phosphor-icons/react";
import {Button, Card, CardBody, CardHeader, Input, Link} from "@nextui-org/react";
import {
Button,
Card,
CardBody,
CardHeader,
Input,
Link,
Modal,
ModalBody,
ModalContent,
ModalFooter,
ModalHeader,
useDisclosure
} from "@nextui-org/react";
import {Alert, AlertDescription, AlertTitle} from "Frontend/@/components/ui/alert";
import {useNavigate} from "react-router-dom";
import {PasswordResetEndpoint} from "Frontend/generated/endpoints";
import {toast} from "sonner";
export default function LoginView() {
const {state, login} = useAuth();
const {isOpen, onOpen, onOpenChange} = useDisclosure();
const [hasError, setError] = useState(false);
const [loading, setLoading] = useState(false);
const [username, setUsername] = useState<string>();
const [password, setPassword] = useState<string>();
const [url, setUrl] = useState<string>();
const [resetEmail, setResetEmail] = useState<string>();
const navigate = useNavigate();
useLayoutEffect(() => {
@@ -21,6 +40,11 @@ export default function LoginView() {
}
}, [state.user]);
async function resetPassword() {
await PasswordResetEndpoint.requestPasswordReset(resetEmail);
toast.success("If the email address is registered, you will receive a message with further instructions.");
}
return (
<div className="flex size-full gradient-primary">
<Card className="m-auto p-12">
@@ -84,7 +108,9 @@ export default function LoginView() {
placeholder=""
/>
<div className="flex justify-between items-center">
<Link color="foreground" underline="always">Forgot password?</Link>
<Link color="foreground" underline="always" onPress={onOpen}>
Forgot password?
</Link>
<Button color="primary" type="submit" isLoading={loading}>
{loading ? "" : "Log in"}
</Button>
@@ -92,6 +118,36 @@ export default function LoginView() {
</form>
</CardBody>
</Card>
<Modal isOpen={isOpen} onOpenChange={onOpenChange}>
<ModalContent>
{(onClose) => (
<>
<ModalHeader className="flex flex-col gap-1">Request a password reset</ModalHeader>
<ModalBody>
<Input
onChange={(event: any) => {
setResetEmail(event.target.value);
}}
type="email"
placeholder="Email"
/>
</ModalBody>
<ModalFooter>
<Button color="danger" variant="light" onPress={onClose}>
Cancel
</Button>
<Button color="primary" onPress={async () => {
await resetPassword();
onClose();
}}>
Send request
</Button>
</ModalFooter>
</>
)}
</ModalContent>
</Modal>
</div>
);
}