프론트엔드 부분은 백엔드 부분에 비해 매우 쉽습니다. 내가 해야 할 일은 모달을 만들고 이를 사용하여 데이터를 두 번 보내는 것뿐입니다.
모달을 생성하기 위해 이전 프로젝트 Chat-Nat의 MessageModal 구성 요소에서 모달 캡슐화를 위한 일부 코드인 classNames를 복사했습니다.
'비밀번호를 잊으셨나요?'를 추가하겠습니다. 로그인 페이지의 버튼을 클릭하고 모달을 열도록 onClick 핸들러를 설정합니다
OTP를 요청하기 전에 사용자의 이메일로 OTP가 전송되었는지 여부를 표시하기 위해 부울 상태를 사용해야 합니다. 나는 상태 이름을 isOTPSent
로 지정합니다.다음은 이 프로젝트의 기존 프런트엔드에서 재사용하고 있는 몇 가지 구성 요소와 후크입니다.
모달의 전체 코드는 다음과 같습니다.
// 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
로그인 양식에서 모달의 조건부 렌더링을 처리하는 방법은 다음과 같습니다
// 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> )
끝났습니다! 아니면 그렇다고 생각했어요.
개발 환경에서 앱을 실행하던 중 백엔드를 오랫동안 실행한 경우 이메일이 전달되지 않는 버그를 발견했습니다.
다음 게시물에서 이 버그를 수정하겠습니다
위 내용은 비밀번호 재설정 기능: 프런트엔드의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!