login

 import React, { useState } from 'react';

import { authService } from '../Services/authService';
import { Button } from '../Shared/Components/Button/Button';
import { Input } from '../Shared/Components/Input/Input';
import { ForgotPasswordModal } from './ForgotPassword/ForgotPassword';
import { toast } from 'sonner';
import { apiService } from '../Services/apiService';
import { JWT_DECODE } from '../Services/jwtUtils'
import { EyeOff, Eye } from 'lucide-react';
import { AESCipher } from '../Services/cryptoUtil';
import { ENVIRONMENT_CONFIG } from '../Config/apiConfig';
import fordLogo from '../../src/Assets/images/ford-logo.png';
import blueSwirlA from '../../src/Assets/images/BlueSwirl1.png';
import blueSwirlB from '../../src/Assets/images/BlueSwirl2.png';
interface LoginProps {
  onLogin: (user: any) => void;
}

export default function UserLogin({ onLogin }: LoginProps) {
  const [email, setUsername] = useState('');
  const [password, setPassword] = useState('');
  const [confirmPassword, setConfirmPassword] = useState('');
  const [rememberMe] = useState(false);
  const [isLoading, setIsLoading] = useState(false);
  const [isChecked, setIsChecked] = useState(false);
  const [, setError] = useState('');
  const [showForgotPasswordModal, setShowForgotPasswordModal] = useState(false);
  const [emailError, setEmailError] = useState("");
  const [showPassword, setShowPassword] = useState(false);
  const [showNewPassword, setShowNewPassword] = useState(false);
  const [showConfirmPassword, setShowConfirmPassword] = useState(false);
  const [newUser, setNewUser] = useState(false);

  const validateEmail = (value: string) => {
    if (!value.includes("@") || !value.includes(".com")) {
      setEmailError("Please enter a valid email (must contain @ and .com)");
    } else {
      setEmailError("");
    }
  };


  const handleLogin = async (e: React.FormEvent) => {
    e.preventDefault();
    setIsLoading(true);
    setError('');
    try {
      const tokenResult = await apiService.getToken();
      let jwtTokenDecode = null;
      if (ENVIRONMENT_CONFIG.dataFormat !== 'application/json') {
        jwtTokenDecode = JWT_DECODE(tokenResult.data);
      } else {
        jwtTokenDecode = typeof(tokenResult.data) === 'string' ? JSON.parse(tokenResult.data) : tokenResult.data;
      }
      if (tokenResult.status !== "success" || !tokenResult.data) {
        toast.error("An unexpected error occurred");
        setError(tokenResult.message || "Failed to get token");
        return;
      }
      const uniqueKey = jwtTokenDecode['unique_key'];
      const secret_key = email.substring(0, 3);
      const cipher = new AESCipher(uniqueKey + secret_key);
      const hashedPassword = cipher.encrypt(password);

      if (!hashedPassword) {
        setError("Failed to encrypt password");
        return;
      }

      const result = await authService.login({
        email,
        hashedPassword,
        rememberMe
      });

      if (result.status === "success") {
        if((localStorage.getItem('new_user') === 'false') || localStorage.getItem('new_user') === undefined){
          onLogin(result.user);
          toast.success(result.message || "Logged in successfully");
          setNewUser(false)
          console.log("Login successful:", result.user);
        }
        else{
          setNewUser(true);
          setPassword('');
        }
      } else {
        toast.error(result.message || "Login failed");
        setError(result.message || "Login failed");
      }
    } catch (error) {
      console.error("Login error:", error);
      toast.error("An unexpected error occurred");
      setError("An unexpected error occurred");
    } finally {
      setIsLoading(false);
    }
  };

  const handleCreatePassword = async (e: React.FormEvent) => {
    e.preventDefault();
    setIsLoading(true);
    setError('');

    if (password !== confirmPassword) {
      toast.error("Password does not match!");
      setIsLoading(false);
      return;
    }

    try {
      const tokenResult = await apiService.getToken();
      let jwtTokenDecode = null;
      if (ENVIRONMENT_CONFIG.dataFormat !== 'application/json') {
        jwtTokenDecode = JWT_DECODE(tokenResult.data);
      } else {
        jwtTokenDecode = typeof(tokenResult.data) === 'string' ? JSON.parse(tokenResult.data) : tokenResult.data;
      }
      if (tokenResult.status !== "success" || !tokenResult.data) {
        setError(tokenResult.message || "Failed to get token");
        setIsLoading(false);
        return;
      }
      const uniqueKey = jwtTokenDecode['unique_key'];
      const secret_key = email.substring(0, 3);
      const cipher = new AESCipher(uniqueKey + secret_key);
      const hashedPassword = cipher.encrypt(password);
     
      const payload = {
        email: email,
        password: hashedPassword,
        reset: false
      };
      const result = await apiService.create_password(payload);
      if (result.status === "success") {
        toast.success(result.message);
        setPassword('');
        setConfirmPassword('');
        setShowNewPassword(false);
        setShowConfirmPassword(false);
        setIsChecked(true);
        localStorage.removeItem('new_user');
        setNewUser(false);
      } else {
        setError(result.message || 'Password creation failed!');
        toast.error(result.message || 'Password creation failed!');
      }
    } catch (error) {
      console.error("Create password error:", error);
      toast.error("An unexpected error occurred");
      setError("An unexpected error occurred");
    } finally {
      setIsLoading(false);
    }
  };
 
  const handleSSO = async () => {
    setIsLoading(true);
    setError('');

    try {
      const result = await authService.loginWithSSO();
      if (!result.status) {
        setError(result.message || 'SSO login failed');
      }
    } catch (error) {
      console.error('SSO error:', error);
      setError('SSO service unavailable');
    } finally {
      setIsLoading(false);
    }
  };

  const handleForgotPassword = () => {
    setShowForgotPasswordModal(true);
  };

 
  return (
    <div className="bg-[#00052e] min-h-screen relative flex flex-col items-center justify-center">
      {/* Background Pattern */}
      <div className="flex justify-around absolute inset-0 opacity-100">
       <img src={blueSwirlA} className="w-170 h-120 pl-15"/>
       <img src={blueSwirlB} className="w-150 h-70 mt-100"/>
      </div>
      {/* Main Content */}
      <div className="relative flex flex-col items-center justify-center flex-1 w-full px-m">
        {/* Login Form Container */}
        <div className="mb-2xl">
          <div
            className="bg-[#00052e] rounded-br-[16px] rounded-tl-[16px] p-5 w-full max-w-md shadow-2xl min-w-[30vw]"
            style={{ minHeight: '420px' }}
          >
            {/* Ford Logo */}
            <div className="text-center mb-6">
              <div className="flex justify-around text-white text-5xl font-bold mb-3 tracking-wide" style={{ fontFamily: 'serif' }}>
                <img
                  src={fordLogo}
                  alt="Ford"
                  className="w-45 h-20"/>
              </div>
             
              {/* Dimensional Intelligence */}
              <h1 className="text-[#ffffff] text-[30px] font-['Roboto:Medium',_sans-serif] tracking-[0.1px] leading-[20px] mb-2">
                Dimensional Intelligence
              </h1>
              <p className="text-[#ffffff] opacity-70 text-[18px] font-['Roboto:Regular',_sans-serif]">
                Ford Motor Company
              </p>
            </div>
          {!newUser? (
            <>
            {/* Login Tab */}
            <div className="text-center mb-xl">
              <h2 className="text-[#ffffff] text-[25px] font-['Noto_Sans_Display:Medium',_sans-serif] leading-[30px]">
                User Login
              </h2>
            </div>
              {/* Login Form */}
              <form
                onSubmit={handleLogin}
                className="space-y-2 mt-2"
              >
                {/* Username Field */}
                <div>
                  <label className="block text-left text-[#f7fefe] text-[14px] mb-1">
                    Email
                  </label>
                  <Input
                    type="text"
                    value={email}
                    placeholder="Enter your email address"
                    onChange={(e) => {
                      setUsername(e.target.value);
                      validateEmail(e.target.value);
                    }}
                    onBlur={(e) => validateEmail(e.target.value)}
                    className={`w-full bg-transparent text-white border-b ${
                      emailError ? "border-red-500" : "border-white"
                    }`}
                    disabled={isLoading || isChecked}
                  />
                  {emailError && (
                    <p className="text-red-400 text-[10px] mt-1">{emailError}</p>
                  )}
                </div>
                {/* Password Field */}
                <div className="relative w-full">
                  <label className="block text-left text-[#f7fefe] text-[14px] mb-1">
                    Password
                  </label>
                  <Input
                    type={showPassword ? 'text' : 'password'}
                    value={password}
                    required
                    onChange={(e) => setPassword(e.target.value)}
                    className="w-full bg-transparent text-white border-b border-white pr-10 py-2"
                    disabled={isLoading}
                  />
                  <button
                    type="button"
                    onClick={() => setShowPassword(!showPassword)}
                    className="absolute top-[35px] right-2 transform -translate-y-1/2 text-white p-2 mt-1.5"
                    tabIndex={-1}
                    aria-label={showPassword ? "Hide password" : "Show password"}
                  >
                    {showPassword ? <EyeOff size={14} /> : <Eye size={14} />}
                  </button>
                </div>
                {/* Buttons */}
                <div className="flex justify-between mt-6">
                  <button
                        type="button"
                        onClick={handleForgotPassword}
                        className="text-sm text-[#f7fefe] underline hover:text-gray-300"
                      >
                        Forgot Password?
                      </button>
                    <Button
                      type="submit"
                      className="bg-[#ffffff] float-right text-[#000000] text-[14px] font-['Noto_Sans_Display:Regular',_sans-serif] tracking-[0.4px] leading-[22px] px-5 py-0 rounded-br-[4px] rounded-tl-[4px] cursor-pointer hover:bg-gray-100 transition-all duration-200 transform hover:scale-105"
                      disabled={isLoading}
                    >
                      Login
                    </Button>
                </div>
                <div className="flex justify-end mt-6">
                  <button
                  onClick={handleSSO}
                  disabled={isLoading}
                  className="w-full bg-[#0078d4] hover:bg-[#106ebe] text-[#ffffff] text-[14px] font-['Noto_Sans_Display:Medium',_sans-serif] tracking-[0.25px] leading-[20px] py-2 px-4 rounded-br-[4px] rounded-tl-[4px] cursor-pointer transition-all duration-200 transform hover:scale-105 flex items-center justify-center space-s"
                >
                  <span>{isLoading ? 'Redirecting...' : 'Sign In with SSO'}</span>
                </button>
                </div>
              </form>
            </>
            ) : (
            <>
              <div className="text-center mb-xl">
                <h2 className="text-[#ffffff] text-[25px] font-['Noto_Sans_Display:Medium',_sans-serif] leading-[30px]">
                  Reset Password
                </h2>
              </div>
              {/* Reser Password Form */}
              <form
                onSubmit={handleCreatePassword}
                className="space-y-2 mt-2"
              >
                {/* New Password */}
                <div className="relative w-full mb-4">
                  <label className="block text-left text-[#f7fefe] text-[14px] mb-1">
                    New Password
                  </label>
                  <Input
                    type={showNewPassword ? 'text' : 'password'}
                    value={password}
                    onChange={(e) => setPassword(e.target.value)}
                    className="w-full bg-transparent text-white border-b border-white pr-10 py-2"
                    disabled={isLoading}
                  />
                  <button
                    type="button"
                    onClick={() => setShowNewPassword(!showNewPassword)}
                    className="absolute top-[35px] right-2 transform -translate-y-1/2 text-white p-2 mt-1.5"
                    tabIndex={-1}
                    aria-label={showNewPassword ? "Hide new password" : "Show new password"}
                  >
                    {showNewPassword ? <EyeOff size={14} /> : <Eye size={14} />}
                  </button>
                </div>

                {/* Confirm New Password */}
                <div className="relative w-full">
                  <label className="block text-left text-[#f7fefe] text-[14px] mb-1">
                    Confirm New Password
                  </label>
                  <Input
                    type={showConfirmPassword ? 'text' : 'password'}
                    value={confirmPassword}
                    onChange={(e) => setConfirmPassword(e.target.value)}
                    className="w-full bg-transparent text-white border-b border-white pr-10 py-2"
                    disabled={isLoading}
                  />
                  <button
                    type="button"
                    onClick={() => setShowConfirmPassword(!showConfirmPassword)}
                    className="absolute top-[35px] right-2 transform -translate-y-1/2 text-white p-2 mt-1.5"
                    tabIndex={-1}
                    aria-label={showConfirmPassword ? "Hide confirm password" : "Show confirm password"}
                  >
                    {showConfirmPassword ? <EyeOff size={14} /> : <Eye size={14} />}
                  </button>
                </div>

                <div className="flex justify-end mt-6">
                  <Button
                    type="submit"
                    className="bg-[#ffffff] float-right text-[#000000] text-[14px] font-['Noto_Sans_Display:Regular',_sans-serif] tracking-[0.4px] leading-[22px] px-5 py-0 rounded-br-[4px] rounded-tl-[4px] cursor-pointer hover:bg-gray-100 transition-all duration-200 transform hover:scale-105"
                    disabled={isLoading}
                  >
                    Create Password
                  </Button>
                </div>
                </form>
            </>
          )}
          </div>
        </div>
      </div>
      <ForgotPasswordModal
        isOpen={showForgotPasswordModal}
        onClose={() => setShowForgotPasswordModal(false)}
      />
      {/* Footer */}
      <div className="absolute bottom-0 left-0 right-0 bg-[#f1f4f6] flex items-center justify-between px-m py-s text-[12px] font-['Noto_Sans_Display:Regular',_sans-serif] tracking-[0.4px] leading-[22px] border-t border-gray-200">
        <div className="text-[#000000]">
          Copyright ©2025 Ford Motor Company
        </div>
        <div className="text-[#235d9f] cursor-pointer hover:underline transition-all">
          View Terms & Conditions
        </div>
      </div>
    </div>
  );
}

Comments

Popular posts from this blog

Homesit

Login.js