import React, { useState } from "react"; import { motion } from "framer-motion"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Separator } from "@/components/ui/separator"; import { Zap, Target, Upload, CheckCircle2, ArrowRight, Mail, Sparkles, Shield, Globe, AlertCircle, Loader2, } from "lucide-react"; import { useAuth } from "@/contexts/AuthContext"; export default function LoginForm() { const { firebaseLogin, requestOTP, verifyOTP } = useAuth(); const [email, setEmail] = useState(""); const [showOtp, setShowOtp] = useState(false); const [otp, setOtp] = useState(["", "", "", "", "", ""]); const [loading, setLoading] = useState(false); const [error, setError] = useState(""); // Business email validation const PERSONAL_EMAIL_DOMAINS = [ "gmail.com", "yahoo.com", "hotmail.com", "outlook.com", "aol.com", "icloud.com", "mail.com", "protonmail.com", "yandex.com", "zoho.com", "gmx.com", "live.com", "msn.com", ]; const isBusinessEmail = (email) => { if (!email || !email.includes("@")) return false; const domain = email.split("@")[1].toLowerCase(); return !PERSONAL_EMAIL_DOMAINS.includes(domain); }; const handleGoogleLogin = async () => { setLoading(true); setError(""); try { await firebaseLogin(); } catch (err) { setError(err.message || "Failed to sign in with Google"); } finally { setLoading(false); } }; const handleEmailSubmit = async (e) => { e.preventDefault(); setLoading(true); setError(""); if (!email) { setError("Please enter your email address"); setLoading(false); return; } if (!isBusinessEmail(email)) { setError("Only business email addresses are allowed. Personal email accounts (Gmail, Yahoo, etc.) are not permitted."); setLoading(false); return; } try { await requestOTP(email); setShowOtp(true); } catch (err) { setError(err.message || "Failed to send OTP"); } finally { setLoading(false); } }; const handleOtpChange = (index, value) => { if (value.length <= 1 && /^\d*$/.test(value)) { const newOtp = [...otp]; newOtp[index] = value; setOtp(newOtp); setError(""); // Auto-focus next input if (value && index < 5) { const nextInput = document.getElementById(`otp-${index + 1}`); nextInput?.focus(); } } }; const handleOtpPaste = (e, startIndex = 0) => { e.preventDefault(); const pastedData = e.clipboardData.getData("text"); // Extract only digits from pasted content const digits = pastedData.replace(/\D/g, "").slice(0, 6); if (digits.length > 0) { const newOtp = [...otp]; // Fill the OTP array with pasted digits starting from the current field for (let i = 0; i < digits.length && (startIndex + i) < 6; i++) { newOtp[startIndex + i] = digits[i]; } setOtp(newOtp); setError(""); // Focus on the next empty input or the last input if all are filled const nextEmptyIndex = Math.min(startIndex + digits.length, 5); const nextInput = document.getElementById(`otp-${nextEmptyIndex}`); nextInput?.focus(); } }; const handleOtpKeyDown = (index, e) => { if (e.key === "Backspace" && !otp[index] && index > 0) { const prevInput = document.getElementById(`otp-${index - 1}`); prevInput?.focus(); } }; const handleOtpVerify = async (e) => { e.preventDefault(); setLoading(true); setError(""); const otpString = otp.join(""); if (otpString.length !== 6) { setError("Please enter a valid 6-digit OTP"); setLoading(false); return; } try { await verifyOTP(email, otpString); // Success - user will be redirected by AuthContext } catch (err) { setError(err.message || "Invalid OTP. Please try again."); setOtp(["", "", "", "", "", ""]); } finally { setLoading(false); } }; const features = [ { icon: Zap, title: "Lightning Fast", description: "Process documents in seconds and get outputs for ERP ingestion", color: "text-amber-500", bg: "bg-amber-50", }, { icon: Target, title: "100% Accuracy", description: "Industry-leading extraction with Visual Reasoning Processor", color: "text-emerald-500", bg: "bg-emerald-50", }, { icon: Globe, title: "Any Format, Any Language", description: "PDF, images, scanned docs — multi-lingual support included", color: "text-blue-500", bg: "bg-blue-50", }, ]; const supportedFormats = [ { ext: "PDF", color: "bg-red-500" }, { ext: "PNG", color: "bg-blue-500" }, { ext: "JPG", color: "bg-green-500" }, { ext: "TIFF", color: "bg-purple-500" }, ]; return (
{
// Fallback: hide image if logo not found
e.target.style.display = 'none';
}}
/>
VRP Intelligence
Deterministic, layout-aware extraction (without LLM) using our proprietary{" "} Visual Reasoning Processor (VRP)
Drop a document to extract data
Invoices, purchase orders, delivery notes, receipts, and operational documents
{feature.description}
{
// Fallback: hide image if logo not found
e.target.style.display = 'none';
}}
/>
VRP Intelligence
{showOtp ? `We sent a code to ${email}` : "Access your document intelligence workspace"}
{error}
By signing in, you agree to our{" "} Terms of Service {" "} and{" "} Privacy Policy