You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

101 lines
4.2 KiB

import React, { useEffect, useState, useRef } from 'react';
import { GoogleGenAI } from "@google/genai";
import { FormData } from '../types';
interface AIAdvisorProps {
formData: FormData;
}
const AIAdvisor: React.FC<AIAdvisorProps> = ({ formData }) => {
// New pitchable initial line
const [advice, setAdvice] = useState<string>("Smart recommendations tailored to your vehicle's profile.");
const [isLoading, setIsLoading] = useState(false);
const abortControllerRef = useRef<AbortController | null>(null);
const getExpertAdvice = async (data: FormData) => {
if (!data.registrationNumber && data.ncb === 0 && data.claimStatus === 'no') return;
setIsLoading(true);
if (abortControllerRef.current) abortControllerRef.current.abort();
abortControllerRef.current = new AbortController();
try {
const ai = new GoogleGenAI({ apiKey: process.env.API_KEY || '' });
const prompt = `
You are a Senior Insurance Underwriter at Nivesh Insurance.
Analyze this 2-wheeler insurance profile and provide ONE professional, concise guidance tip (max 15 words).
Profile Details:
- Vehicle Reg: ${data.registrationNumber || 'Not provided'}
- Previous Claim: ${data.claimStatus}
- Current No Claim Bonus: ${data.ncb}%
- Chosen Cover: ${data.coverType}
Focus on technical insurance advice like NCB protection, Zero-Dep value, or IDV optimization.
Do NOT mention "AI", "Algorithms", or "Premium Discounts". Use an authoritative, professional tone.
`;
const response = await ai.models.generateContent({
model: 'gemini-3-flash-preview',
contents: prompt,
config: {
temperature: 0.6,
maxOutputTokens: 60,
}
});
const text = response.text;
if (text) {
setAdvice(text.trim());
}
} catch (error: any) {
if (error.name !== 'AbortError') {
setAdvice("Maintain a consistent insurance history for seamless future claim processing.");
}
} finally {
setIsLoading(false);
}
};
useEffect(() => {
const handler = setTimeout(() => {
getExpertAdvice(formData);
}, 1200);
return () => clearTimeout(handler);
}, [formData.registrationNumber, formData.claimStatus, formData.ncb, formData.coverType]);
return (
<div className="bg-white border-2 border-slate-100 rounded-3xl p-6 flex gap-5 items-center relative overflow-hidden group hover:border-[#1a2b4b]/20 transition-all duration-500 shadow-sm">
<div className="absolute top-0 right-0 -mr-4 -mt-4 w-24 h-24 bg-[#1a2b4b]/5 rounded-full blur-2xl group-hover:bg-[#e31e24]/5 transition-colors duration-500"></div>
<div className="flex-shrink-0 relative">
<div className={`w-12 h-12 bg-slate-50 border border-slate-100 rounded-2xl flex items-center justify-center shadow-inner transition-transform duration-500 ${isLoading ? 'scale-95' : 'group-hover:scale-105'}`}>
<svg className={`w-6 h-6 ${isLoading ? 'text-[#e31e24] animate-pulse' : 'text-[#1a2b4b]'}`} fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" />
</svg>
</div>
</div>
<div className="flex-grow">
<div className="flex items-center gap-2 mb-1">
<h4 className="text-[10px] font-black text-[#e31e24] uppercase tracking-[0.2em]">Smart Insight</h4>
{isLoading && <span className="text-[8px] font-bold text-slate-400 animate-pulse italic">Optimizing...</span>}
</div>
<p className={`text-sm font-semibold text-[#1a2b4b] leading-snug transition-all duration-500 ${isLoading ? 'opacity-40' : 'opacity-100'}`}>
{advice}
</p>
</div>
<div className="hidden md:block flex-shrink-0 ml-2">
<div className="px-3 py-1 bg-[#1a2b4b]/5 rounded-full border border-[#1a2b4b]/10">
<span className="text-[9px] font-black text-[#1a2b4b]">PROTECT</span>
</div>
</div>
</div>
);
};
export default AIAdvisor;

Powered by TurnKey Linux.