Heim  >  Artikel  >  Backend-Entwicklung  >  Funktion zum Zurücksetzen des Passworts: Frontend

Funktion zum Zurücksetzen des Passworts: Frontend

DDD
DDDOriginal
2024-10-02 12:07:01870Durchsuche

Password Reset Feature: Frontend

Frontend

Der Frontend-Teil ist im Vergleich zum Backend-Teil sehr einfach. Ich muss lediglich ein Modal erstellen und es verwenden, um Daten zweimal zu senden.

  • Senden Sie zunächst eine E-Mail, an die das OTP gesendet werden soll
  • Senden Sie dann das OTP und das neue Passwort, um es zu ändern

Um das Modal zu erstellen, habe ich etwas Code, die Klassennamen für die Kapselung eines Modals, aus der MessageModal-Komponente in meinem früheren Projekt Chat-Nat kopiert.

Planung

Ich füge ein „Passwort vergessen?“ hinzu. Klicken Sie auf der Anmeldeseite auf die Schaltfläche und legen Sie den onClick-Handler fest, um das modale

zu öffnen

Ich muss einen booleschen Zustand verwenden, um anzugeben, ob das OTP an die E-Mail-Adresse des Benutzers gesendet wurde, bevor ich danach frage. Ich nenne den Staat isOTPSent

  • Wenn !isOTPSent -> Fragen Sie einfach nach der E-Mail-Adresse, senden Sie die API-Anforderung und setzen Sie bei Erfolg setOTPSent(true).
  • Wenn isOTPSent -> Fragen Sie nun auch nach dem OTP und dem neuen Passwort und schließen Sie bei Erfolg das Modal

Hier sind ein paar Komponenten und Hooks, die ich aus dem bestehenden Frontend dieses Projekts wiederverwende:

  • Box -> Es hat meine Anmelde- und Registrierungsseiten ordentlich in einer Karte zusammengefasst, die auf der Seite zentriert ist und hier mit dem Titel „Passwort zurücksetzen“ wiederverwendet wird.
  • AuthForm -> Nur ein Formular, aber ich habe es so codiert, dass die Schaltfläche „Senden“ deaktiviert und der Schaltflächentext auf „Laden …“ eingestellt ist, wenn wir auf eine Antwort vom Server warten
  • FormInput -> Eingabefeld mit eigenem Label, mit Value-Setter und onChange-Handler, optional mit einem isRequired-Booleschen Wert
  • useAxios -> Benutzerdefinierter Hook zur Verarbeitung der Antworten vom Server, der eine Token-Aktualisierung benötigt. apiReq-Funktion für das normale Senden von Anforderungen, einige benutzerdefinierte Fehlerbehandlungen zum Anzeigen einer Warnung () und eines Aktualisierungstokens sowie die Funktion „refreshReq“ zum Aktualisieren des Authentifizierungstokens und zum erneuten Versuch der ursprünglichen Anforderung.

Hier ist der gesamte Code für das Modal:

// src/components/PasswordResetModal.tsx
import React, { useState } from "react"
import AuthForm from "./AuthForm";
import FormInput from "./FormInput";
import Box from "./Box";
import { useAxios } from "../hooks/useAxios";

interface FormData {
    email: string,
    new_password: string,
    otp: string,
}

interface Props {
    isVisible: boolean,
    onClose: () => void,
}

const PasswordResetModal: React.FC<Props> = ({ isVisible, onClose }) => {
    const [formData, setFormData] = useState<FormData>({
        email: "",
        new_password: "",
        otp: ""
    });
    const [isLoading, setLoading] = useState<boolean>(false);
    const [isOTPSent, setOTPSent] = useState<boolean>(false);
    const { apiReq } = useAxios();

    const handleClose = (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
        if ((e.target as HTMLElement).id === "wrapper") {
            onClose();

            // could have setOTPSent(false), but avoiding it in case user misclicks outside
        }
    };

    const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        const { name, value } = e.target;
        setFormData({
            ...formData,
            [name]: value,
        });
    };

    const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
        e.preventDefault();
        setLoading(true);

        if (!isOTPSent) { // first request for sending otp,
            const response = await apiReq<unknown, FormData>("post", "/api/reset-password", formData)

            if (response) {
                alert("OTP has been sent to your email");
                setOTPSent(true);
            }
        } else { // then using otp to change password
            const response = await apiReq<unknown, FormData>("put", "/api/reset-password", formData)

            if (response) {
                alert("Password has been successfully reset\nPlease log in again");

                // clear the form
                setFormData({
                    email: "",
                    otp: "",
                    new_password: "",
                })

                // close modal
                onClose();
            }
        }

        setLoading(false);
    };

    if (!isVisible) return null;

    return (
        <div
            id="wrapper"
            className="fixed inset-0 bg-black bg-opacity-25 backdrop-blur-sm flex justify-center items-center"
            onClick={handleClose}>
            <Box title="Password Reset">
                <AuthForm
                    submitHandler={handleSubmit}
                    isLoading={isLoading}
                    buttonText={isOTPSent ? "Change Password" : "Send OTP"}>
                    <FormInput
                        id="email"
                        label="Your email"
                        type="email"
                        value={formData.email}
                        changeHandler={handleChange}
                        isRequired />

                    {isOTPSent && (<>
                        <FormInput
                            id="otp"
                            label="OTP"
                            type="text"
                            value={formData.otp}
                            changeHandler={handleChange}
                            isRequired />
                        <FormInput
                            id="new_password"
                            label="New Password"
                            type="password"
                            value={formData.new_password}
                            changeHandler={handleChange}
                            isRequired />
                    </>)}
                </AuthForm>
            </Box>
        </div>
    )
}

export default PasswordResetModal

Und so wird die bedingte Darstellung des Modals im Anmeldeformular gehandhabt

// src/pages/auth/Login.tsx
import PasswordResetModal from "../../components/PasswordResetModal";

const Login: React.FC = () => {
    const [showModal, setShowModal] = useState<boolean>(false);

    return (
        <Section>
            <Box title="Login">
                <div className="grid grid-flow-col">
                    {/* link to the register page here */}
                    <button 
                    type="button"
                    onClick={() => setShowModal(true)}
                    className="text-blue-700 hover:text-white border border-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-3 py-2 text-center me-2 mb-2 dark:border-blue-500 dark:text-blue-500 dark:hover:text-white dark:hover:bg-blue-500 dark:focus:ring-blue-800">
                        Forgot Password?
                    </button>

                    <PasswordResetModal isVisible={showModal} onClose={() => setShowModal(false)} />
                </div>
            </Box>
        </Section>
    )

Wir sind fertig! Zumindest dachte ich das.

Beim Ausführen der App in meiner Entwicklungsumgebung habe ich einen Fehler entdeckt, der dazu führte, dass die E-Mails nicht weitergeleitet wurden, wenn das Backend schon längere Zeit ausgeführt wurde.

Wir werden diesen Fehler im nächsten Beitrag beheben

Das obige ist der detaillierte Inhalt vonFunktion zum Zurücksetzen des Passworts: Frontend. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn