Untitled

 avatar
unknown
plain_text
a month ago
6.6 kB
3
Indexable
import React, { useState, useEffect } from 'react';
import { Helmet } from 'react-helmet-async';
import PageHeader from '../components/PageHeader';
import useAuth from '../hooks/useAuth';
import { getAuth, fetchSignInMethodsForEmail, updatePassword, updateEmail } from 'firebase/auth';

const PasswordForm = ({ hasPassword, onPasswordUpdate }) => {
  const auth = getAuth();
  const [currentPassword, setCurrentPassword] = useState('');
  const [newPassword, setNewPassword] = useState('');
  const [confirmPassword, setConfirmPassword] = useState('');
  const [message, setMessage] = useState('');

  const handlePasswordChange = async (e) => {
    e.preventDefault();

    if (!newPassword || !confirmPassword) {
      setMessage('Error: All fields are required.');
      return;
    }

    if (newPassword.length < 8) {
      setMessage('Error: Password must be at least 8 characters long.');
      return;
    }

    if (newPassword !== confirmPassword) {
      setMessage('Error: New passwords do not match.');
      return;
    }

    try {
      await updatePassword(auth.currentUser, newPassword);
      setMessage('Success: Your password has been updated.');
      onPasswordUpdate(); // Callback to inform parent component that password is set
    } catch (error) {
      setMessage(`Error: ${error.message}`);
    }
  };

  return (
    <div className="p-6 border border-gray-300 rounded-lg shadow bg-white w-full">
      <h2 className="text-xl font-semibold mb-4">{hasPassword ? 'Change Password' : 'Set Password'}</h2>
      <form onSubmit={handlePasswordChange} className="space-y-4">
        {hasPassword && (
          <>
            <label htmlFor="currentPassword" className="block text-sm font-medium">Current Password</label>
            <input 
              id="currentPassword" 
              type="password" 
              value={currentPassword} 
              onChange={(e) => setCurrentPassword(e.target.value)} 
              className="border p-2 w-full rounded-md"
            />
          </>
        )}

        <label htmlFor="newPassword" className="block text-sm font-medium">New Password</label>
        <input 
          id="newPassword" 
          type="password" 
          value={newPassword} 
          onChange={(e) => setNewPassword(e.target.value)} 
          required 
          className="border p-2 w-full rounded-md"
        />

        <label htmlFor="confirmPassword" className="block text-sm font-medium">Confirm New Password</label>
        <input 
          id="confirmPassword" 
          type="password" 
          value={confirmPassword} 
          onChange={(e) => setConfirmPassword(e.target.value)} 
          required 
          className="border p-2 w-full rounded-md"
        />

        <button 
          type="submit" 
          disabled={!newPassword || !confirmPassword}
          className={`p-2 w-full rounded-md text-white ${!newPassword || !confirmPassword ? 'bg-gray-300 cursor-not-allowed' : 'bg-gray-800 hover:bg-gray-900'}`}
        >
          {hasPassword ? 'Update Password' : 'Set Password'}
        </button>

        {message && <p className={`text-sm ${message.includes('Error') ? 'text-red-500' : 'text-green-500'}`}>{message}</p>}
      </form>
    </div>
  );
};

const EmailForm = () => {
  const auth = getAuth();
  const [newEmail, setNewEmail] = useState('');
  const [confirmEmail, setConfirmEmail] = useState('');
  const [message, setMessage] = useState('');

  const handleEmailChange = async (e) => {
    e.preventDefault();

    if (newEmail !== confirmEmail) {
      setMessage('Error: Emails do not match.');
      return;
    }

    try {
      await updateEmail(auth.currentUser, newEmail);
      setMessage('Success: Your email has been updated.');
    } catch (error) {
      setMessage(`Error: ${error.message}`);
    }
  };

  return (
    <div className="p-6 border border-gray-300 rounded-lg shadow bg-white w-full">
      <h2 className="text-xl font-semibold mb-4">Change Email</h2>
      <form onSubmit={handleEmailChange} className="space-y-4">
        <label htmlFor="newEmail" className="block text-sm font-medium">New Email</label>
        <input 
          id="newEmail" 
          type="email" 
          value={newEmail} 
          onChange={(e) => setNewEmail(e.target.value)} 
          required 
          className="border p-2 w-full rounded-md"
        />

        <label htmlFor="confirmEmail" className="block text-sm font-medium">Confirm New Email</label>
        <input 
          id="confirmEmail" 
          type="email" 
          value={confirmEmail} 
          onChange={(e) => setConfirmEmail(e.target.value)} 
          required 
          className="border p-2 w-full rounded-md"
        />

        <button 
          type="submit" 
          disabled={!newEmail || !confirmEmail}
          className={`p-2 w-full rounded-md text-white ${!newEmail || !confirmEmail ? 'bg-gray-300 cursor-not-allowed' : 'bg-gray-800 hover:bg-gray-900'}`}
        >
          Update Email
        </button>

        {message && <p className={`text-sm ${message.includes('Error') ? 'text-red-500' : 'text-green-500'}`}>{message}</p>}
      </form>
    </div>
  );
};

const ManageAccountPage = () => {
  const { user } = useAuth();
  const [hasPassword, setHasPassword] = useState(false);

  useEffect(() => {
    if (user && user.email) {
      fetchSignInMethodsForEmail(getAuth(), user.email).then((methods) => {
        setHasPassword(methods.includes('password'));
      });
    }
  }, [user]);

  const handlePasswordUpdate = () => {
    setHasPassword(true); // Update the state to reflect that the password is set
  };

  return (
    <>
      <Helmet>
        <title>Manage my Account | AUT Events Induction Portal</title>
      </Helmet>
      <PageHeader 
        title="Manage Account" 
        subtext="Manage your AUT Events Induction Portal account" 
      />
      <div className="p-6 flex flex-col items-center">
        <div className="w-full max-w-8xl grid grid-cols-1 md:grid-cols-2 gap-6">
          {/* Show only the Set Password form if user doesn't have a password */}
          {!hasPassword && <PasswordForm hasPassword={false} onPasswordUpdate={handlePasswordUpdate} />}
          {/* Show Change Password and Email forms if user has a password */}
          {hasPassword && (
            <>
              <PasswordForm hasPassword={true} onPasswordUpdate={handlePasswordUpdate} />
              <EmailForm />
            </>
          )}
        </div>
      </div>
    </>
  );
};

export default ManageAccountPage;

Editor is loading...
Leave a Comment