Initial import

This commit is contained in:
Flatlogic Bot 2026-03-07 06:53:12 +00:00
commit 657b6ecd75
12 changed files with 774 additions and 0 deletions

9
.env.example Normal file
View File

@ -0,0 +1,9 @@
# GEMINI_API_KEY: Required for Gemini AI API calls.
# AI Studio automatically injects this at runtime from user secrets.
# Users configure this via the Secrets panel in the AI Studio UI.
GEMINI_API_KEY="MY_GEMINI_API_KEY"
# APP_URL: The URL where this applet is hosted.
# AI Studio automatically injects this at runtime with the Cloud Run service URL.
# Used for self-referential links, OAuth callbacks, and API endpoints.
APP_URL="MY_APP_URL"

8
.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
node_modules/
build/
dist/
coverage/
.DS_Store
*.log
.env*
!.env.example

20
README.md Normal file
View File

@ -0,0 +1,20 @@
<div align="center">
<img width="1200" height="475" alt="GHBanner" src="https://github.com/user-attachments/assets/0aa67016-6eaf-458a-adb2-6e31a0763ed6" />
</div>
# Run and deploy your AI Studio app
This contains everything you need to run your app locally.
View your app in AI Studio: https://ai.studio/apps/aa0a996b-c612-43f6-a22a-d2d9e6b595df
## Run Locally
**Prerequisites:** Node.js
1. Install dependencies:
`npm install`
2. Set the `GEMINI_API_KEY` in [.env.local](.env.local) to your Gemini API key
3. Run the app:
`npm run dev`

13
index.html Normal file
View File

@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>My Google AI Studio App</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>

5
metadata.json Normal file
View File

@ -0,0 +1,5 @@
{
"name": "Generali Central Life Insurance Portal",
"description": "A comprehensive portal for exploring life insurance plans, understanding benefits, and generating custom benefit illustrations.",
"requestFramePermissions": []
}

0
package-lock.json generated Normal file
View File

35
package.json Normal file
View File

@ -0,0 +1,35 @@
{
"name": "react-example",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite --port=3000 --host=0.0.0.0",
"build": "vite build",
"preview": "vite preview",
"clean": "rm -rf dist",
"lint": "tsc --noEmit"
},
"dependencies": {
"@google/genai": "^1.29.0",
"@tailwindcss/vite": "^4.1.14",
"@vitejs/plugin-react": "^5.0.4",
"lucide-react": "^0.546.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"vite": "^6.2.0",
"express": "^4.21.2",
"dotenv": "^17.2.3",
"better-sqlite3": "^12.4.1",
"motion": "^12.23.24"
},
"devDependencies": {
"@types/node": "^22.14.0",
"autoprefixer": "^10.4.21",
"tailwindcss": "^4.1.14",
"tsx": "^4.21.0",
"typescript": "~5.8.2",
"vite": "^6.2.0",
"@types/express": "^4.17.21"
}
}

623
src/App.tsx Normal file
View File

@ -0,0 +1,623 @@
/**
* @license
* SPDX-License-Identifier: Apache-2.0
*/
import React, { useState, useMemo } from 'react';
import {
ShieldCheck,
TrendingUp,
Clock,
HeartPulse,
ChevronRight,
Info,
Calculator,
ArrowRight,
CheckCircle2,
FileText,
User,
Mail,
Phone,
Calendar
} from 'lucide-react';
import { motion, AnimatePresence } from 'motion/react';
// --- Types ---
type PlanType = 'money-back' | 'long-term-income';
interface QuoteData {
name: string;
age: number;
gender: 'male' | 'female';
planType: PlanType;
sumAssured: number;
policyTerm: number;
premiumTerm: number;
}
// --- Components ---
const Navbar = () => (
<nav className="sticky top-0 z-50 bg-white/80 backdrop-blur-md border-b border-zinc-100">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex justify-between h-16 items-center">
<div className="flex items-center gap-2">
<div className="w-16 h-16 bg-white-600 rounded-lg flex items-center justify-center">
<img src="https://image2url.com/r2/default/images/1772810627562-124d437f-8175-4a8a-a696-76d7573a2b3e.png" alt="image" />
</div>
<span className="font-bold text-xl tracking-tight text-zinc-900">Generali Central</span>
</div>
<div className="hidden md:flex items-center gap-8 text-sm font-medium text-zinc-600">
<a href="#plans" className="hover:text-red-600 transition-colors">Plans</a>
<a href="#explanations" className="hover:text-red-600 transition-colors">How it Works</a>
{/* <a href="#calculator" className="hover:text-red-600 transition-colors">Calculator</a> */}
<button className="bg-red-600 text-white px-5 py-2 rounded-full hover:bg-red-700 transition-all shadow-sm">
<a href="#contact" className="transition-colors">Contact Advisor</a>
</button>
</div>
</div>
</div>
</nav>
);
const Hero = () => (
<section className="relative py-20 overflow-hidden bg-zinc-50">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
<div className="grid lg:grid-cols-2 gap-12 items-center">
<motion.div
initial={{ opacity: 0, x: -20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.6 }}
>
<span className="inline-block px-3 py-1 bg-red-50 text-red-600 text-xs font-bold uppercase tracking-widest rounded-full mb-6">
Secure Your Future
</span>
<h1 className="text-5xl lg:text-6xl font-bold text-zinc-900 leading-[1.1] mb-6">
Protection that <br />
<span className="text-red-600">Grows with You.</span>
</h1>
<p className="text-lg text-zinc-600 mb-8 max-w-lg leading-relaxed">
Explore our range of Individual, Non-Linked, Non-Participating Savings Life Insurance Plans designed to provide both security and guaranteed returns.
</p>
<div className="flex flex-wrap gap-4">
<a href="#calculator" className="bg-zinc-900 text-white px-8 py-4 rounded-xl font-semibold flex items-center gap-2 hover:bg-zinc-800 transition-all shadow-lg shadow-zinc-200">
Get a Quote <ArrowRight className="w-4 h-4" />
</a>
<a href="#plans" className="bg-white text-zinc-900 border border-zinc-200 px-8 py-4 rounded-xl font-semibold hover:bg-zinc-50 transition-all">
View Plans
</a>
</div>
</motion.div>
<motion.div
initial={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.8, delay: 0.2 }}
className="relative"
>
<div className="aspect-square rounded-3xl overflow-hidden shadow-2xl">
<img
src="https://picsum.photos/seed/insurance/800/800"
alt="Family Security"
className="w-full h-full object-cover"
referrerPolicy="no-referrer"
/>
</div>
<div className="absolute -bottom-6 -left-6 bg-white p-6 rounded-2xl shadow-xl border border-zinc-100 max-w-[240px]">
<div className="flex items-center gap-3 mb-2">
<div className="p-2 bg-emerald-50 rounded-lg">
<TrendingUp className="text-emerald-600 w-5 h-5" />
</div>
<span className="font-bold text-zinc-900">Guaranteed Returns</span>
</div>
<p className="text-xs text-zinc-500">Fixed payouts and maturity benefits to ensure your financial goals are met.</p>
</div>
</motion.div>
</div>
</div>
</section>
);
const PlanExplanation = () => (
<section id="explanations" className="py-24 bg-white">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-16">
<h2 className="text-3xl font-bold text-zinc-900 mb-4">Understanding Your Policy</h2>
<p className="text-zinc-500 max-w-2xl mx-auto">Insurance can be complex. We break down the key terms from your benefit illustration so you can make an informed choice.</p>
</div>
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
{[
{
title: "Sum Assured",
desc: "The fixed amount guaranteed to be paid to the nominee in case of the life assured's death during the policy term.",
icon: ShieldCheck,
color: "bg-blue-50 text-blue-600"
},
{
title: "Annualized Premium",
desc: "The premium amount payable in a year, excluding taxes, rider premiums, and underwriting extra premiums.",
icon: Clock,
color: "bg-purple-50 text-purple-600"
},
{
title: "Guaranteed Additions",
desc: "Additional amounts added to your policy benefits, typically accruing after a certain number of policy years.",
icon: TrendingUp,
color: "bg-emerald-50 text-emerald-600"
},
{
title: "Survival Benefit",
desc: "Periodic payouts made to you during the policy term if the life assured survives to specified dates.",
icon: HeartPulse,
color: "bg-red-50 text-red-600"
},
{
title: "GSV vs SSV",
desc: "GSV (Guaranteed Surrender Value) is the minimum guaranteed amount if you cancel. SSV (Special Surrender Value) is often higher but not guaranteed.",
icon: Info,
color: "bg-amber-50 text-amber-600"
},
{
title: "Rider Benefits",
desc: "Optional add-ons like 'Accidental Death Benefit' that provide extra protection for a small additional premium.",
icon: CheckCircle2,
color: "bg-zinc-50 text-zinc-600"
}
].map((item, idx) => (
<motion.div
key={idx}
whileHover={{ y: -5 }}
className="p-8 rounded-2xl border border-zinc-100 bg-zinc-50/50 hover:bg-white hover:shadow-xl hover:shadow-zinc-200/50 transition-all"
>
<div className={`w-12 h-12 ${item.color} rounded-xl flex items-center justify-center mb-6`}>
<item.icon className="w-6 h-6" />
</div>
<h3 className="text-xl font-bold text-zinc-900 mb-3">{item.title}</h3>
<p className="text-zinc-600 text-sm leading-relaxed">{item.desc}</p>
</motion.div>
))}
</div>
</div>
</section>
);
const QuoteForm = () => {
const [formData, setFormData] = useState<QuoteData>({
name: '',
age: 30,
gender: 'male',
planType: 'money-back',
sumAssured: 1000000,
policyTerm: 20,
premiumTerm: 20
});
const [isCalculated, setIsCalculated] = useState(false);
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
setIsCalculated(true);
};
const illustration = useMemo(() => {
if (!isCalculated) return null;
// Simplified logic based on PDF data
const annualPremium = formData.sumAssured * 0.1; // Roughly 10% for 10L sum assured
const years = Array.from({ length: formData.policyTerm }, (_, i) => i + 1);
return years.map(year => {
const isPayoutYear = formData.planType === 'money-back' && year % 5 === 0 && year < formData.policyTerm;
const survivalBenefit = isPayoutYear ? formData.sumAssured * 0.11 : 0;
const guaranteedAddition = year >= 8 ? annualPremium * 0.838 : 0;
const deathBenefit = formData.sumAssured + (year >= 8 ? guaranteedAddition * (year - 7) : 0);
return {
year,
premium: annualPremium,
survivalBenefit,
guaranteedAddition,
deathBenefit,
surrenderValue: annualPremium * year * (year / formData.policyTerm) * 0.6 // Mock curve
};
});
}, [isCalculated, formData]);
return (
<section id="calculator" className="py-24 bg-zinc-50">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="grid lg:grid-cols-5 gap-12">
{/* Form Side */}
<div className="lg:col-span-2">
<div className="bg-white p-8 rounded-3xl shadow-xl border border-zinc-100">
<div className="flex items-center gap-3 mb-8">
<div className="p-2 bg-red-50 rounded-lg">
<Calculator className="text-red-600 w-6 h-6" />
</div>
<h2 className="text-2xl font-bold text-zinc-900">Illustration Builder</h2>
</div>
<form onSubmit={handleSubmit} className="space-y-6">
<div>
<label className="block text-sm font-semibold text-zinc-700 mb-2 flex items-center gap-2">
<User className="w-4 h-4 text-zinc-400" /> Full Name
</label>
<input
type="text"
required
className="w-full px-4 py-3 rounded-xl border border-zinc-200 focus:ring-2 focus:ring-red-500 focus:border-red-500 transition-all outline-none"
placeholder="e.g. Harmanjeet Singh"
value={formData.name}
onChange={e => setFormData({...formData, name: e.target.value})}
/>
</div>
<div className="grid grid-cols-2 gap-4">
<div>
<label className="block text-sm font-semibold text-zinc-700 mb-2 flex items-center gap-2">
<Calendar className="w-4 h-4 text-zinc-400" /> Age
</label>
<input
type="number"
min="18" max="65"
className="w-full px-4 py-3 rounded-xl border border-zinc-200 focus:ring-2 focus:ring-red-500 transition-all outline-none"
value={formData.age}
onChange={e => setFormData({...formData, age: parseInt(e.target.value)})}
/>
</div>
<div>
<label className="block text-sm font-semibold text-zinc-700 mb-2">Gender</label>
<select
className="w-full px-4 py-3 rounded-xl border border-zinc-200 focus:ring-2 focus:ring-red-500 transition-all outline-none"
value={formData.gender}
onChange={e => setFormData({...formData, gender: e.target.value as any})}
>
<option value="male">Male</option>
<option value="female">Female</option>
</select>
</div>
</div>
<div>
<label className="block text-sm font-semibold text-zinc-700 mb-2">Select Plan</label>
<div className="grid grid-cols-1 gap-3">
<button
type="button"
onClick={() => setFormData({...formData, planType: 'money-back'})}
className={`p-4 rounded-xl border-2 text-left transition-all ${formData.planType === 'money-back' ? 'border-red-600 bg-red-50/50' : 'border-zinc-100 hover:border-zinc-200'}`}
>
<div className="font-bold text-zinc-900">Money Back Super Plan</div>
<div className="text-xs text-zinc-500">Periodic survival benefits + Maturity</div>
</button>
<button
type="button"
onClick={() => setFormData({...formData, planType: 'long-term-income'})}
className={`p-4 rounded-xl border-2 text-left transition-all ${formData.planType === 'long-term-income' ? 'border-red-600 bg-red-50/50' : 'border-zinc-100 hover:border-zinc-200'}`}
>
<div className="font-bold text-zinc-900">Long Term Income Plan</div>
<div className="text-xs text-zinc-500">Regular income stream for up to 50 years</div>
</button>
</div>
</div>
<div>
<label className="block text-sm font-semibold text-zinc-700 mb-2">Sum Assured ()</label>
<input
type="range"
min="500000" max="5000000" step="100000"
className="w-full h-2 bg-zinc-200 rounded-lg appearance-none cursor-pointer accent-red-600"
value={formData.sumAssured}
onChange={e => setFormData({...formData, sumAssured: parseInt(e.target.value)})}
/>
<div className="flex justify-between mt-2 text-sm font-bold text-zinc-900">
<span>5L</span>
<span className="text-red-600">{(formData.sumAssured / 100000).toFixed(1)}L</span>
<span>50L</span>
</div>
</div>
<button
type="submit"
className="w-full bg-red-600 text-white py-4 rounded-xl font-bold text-lg hover:bg-red-700 transition-all shadow-lg shadow-red-200 flex items-center justify-center gap-2"
>
Generate Illustration <ChevronRight className="w-5 h-5" />
</button>
</form>
</div>
</div>
{/* Results Side */}
<div className="lg:col-span-3">
<AnimatePresence mode="wait">
{!isCalculated ? (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="h-full flex flex-col items-center justify-center text-center p-12 border-2 border-dashed border-zinc-200 rounded-3xl bg-white/50"
>
<div className="w-20 h-20 bg-zinc-100 rounded-full flex items-center justify-center mb-6">
<FileText className="w-10 h-10 text-zinc-300" />
</div>
<h3 className="text-2xl font-bold text-zinc-400">Ready to See Your Benefits?</h3>
<p className="text-zinc-400 max-w-xs mt-2">Fill out the form to generate a detailed year-by-year benefit illustration.</p>
</motion.div>
) : (
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
className="space-y-6"
>
<div className="bg-zinc-900 text-white p-8 rounded-3xl shadow-xl">
<div className="flex justify-between items-start mb-8">
<div>
<h3 className="text-zinc-400 text-xs font-bold uppercase tracking-widest mb-1">Illustration Summary</h3>
<div className="text-2xl font-bold">{formData.name || 'Valued Customer'}</div>
</div>
<div className="text-right">
<div className="text-zinc-400 text-xs font-bold uppercase tracking-widest mb-1">Plan Type</div>
<div className="font-bold text-red-400">{formData.planType === 'money-back' ? 'Money Back Super' : 'Long Term Income'}</div>
</div>
</div>
<div className="grid grid-cols-3 gap-4">
<div className="bg-white/5 p-4 rounded-2xl">
<div className="text-zinc-500 text-[10px] uppercase font-bold mb-1">Sum Assured</div>
<div className="text-lg font-bold">{(formData.sumAssured / 100000).toFixed(1)}L</div>
</div>
<div className="bg-white/5 p-4 rounded-2xl">
<div className="text-zinc-500 text-[10px] uppercase font-bold mb-1">Annual Premium</div>
<div className="text-lg font-bold">{(formData.sumAssured * 0.1 / 1000).toFixed(0)}K</div>
</div>
<div className="bg-white/5 p-4 rounded-2xl">
<div className="text-zinc-500 text-[10px] uppercase font-bold mb-1">Policy Term</div>
<div className="text-lg font-bold">{formData.policyTerm} Yrs</div>
</div>
</div>
</div>
<div className="bg-white rounded-3xl shadow-xl border border-zinc-100 overflow-hidden">
<div className="p-6 border-b border-zinc-100 flex justify-between items-center">
<h4 className="font-bold text-zinc-900">Yearly Benefit Projection</h4>
<span className="text-[10px] bg-emerald-50 text-emerald-600 px-2 py-1 rounded-full font-bold uppercase">Guaranteed Values</span>
</div>
<div className="overflow-x-auto">
<table className="w-full text-left text-sm">
<thead>
<tr className="bg-zinc-50 text-zinc-500 font-bold uppercase text-[10px] tracking-wider">
<th className="px-6 py-4">Year</th>
<th className="px-6 py-4">Premium</th>
<th className="px-6 py-4">Survival Benefit</th>
<th className="px-6 py-4">Death Benefit</th>
<th className="px-6 py-4 text-right">Surrender Value</th>
</tr>
</thead>
<tbody className="divide-y divide-zinc-50">
{illustration?.slice(0, 10).map((row) => (
<tr key={row.year} className="hover:bg-zinc-50/50 transition-colors">
<td className="px-6 py-4 font-bold text-zinc-900">{row.year}</td>
<td className="px-6 py-4 text-zinc-600">{row.premium.toLocaleString()}</td>
<td className="px-6 py-4">
{row.survivalBenefit > 0 ? (
<span className="text-emerald-600 font-bold">{row.survivalBenefit.toLocaleString()}</span>
) : (
<span className="text-zinc-300"></span>
)}
</td>
<td className="px-6 py-4 font-medium text-zinc-900">{row.deathBenefit.toLocaleString()}</td>
<td className="px-6 py-4 text-right font-mono text-zinc-500">{row.surrenderValue.toLocaleString(undefined, { maximumFractionDigits: 0 })}</td>
</tr>
))}
</tbody>
</table>
</div>
<div className="p-4 bg-zinc-50 text-center">
<button className="text-red-600 text-xs font-bold hover:underline">View Full 20-Year Illustration</button>
</div>
</div>
</motion.div>
)}
</AnimatePresence>
</div>
</div>
</div>
</section>
);
};
const Footer = () => (
<footer className="bg-zinc-900 text-white py-12">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="grid md:grid-cols-4 gap-12 mb-12">
<div className="col-span-2">
<div className="flex items-center gap-2 mb-6">
<div className="w-8 h-8 bg-red-600 rounded-lg flex items-center justify-center">
<ShieldCheck className="text-white w-5 h-5" />
</div>
<span className="font-bold text-xl tracking-tight">Generali Central</span>
</div>
<p className="text-zinc-500 max-w-sm text-sm leading-relaxed">
Generali Central Life Insurance Company Limited (Formerly known as Future Generali India Life Insurance Company Limited).
Registered Office: Unit 801 and 802, 8th floor, Tower C, Embassy 247 Park, L.B.S. Marg, Vikhroli (W), Mumbai 400083.
</p>
</div>
<div>
<h4 className="font-bold mb-6 text-sm uppercase tracking-widest text-zinc-400">Quick Links</h4>
<ul className="space-y-4 text-sm text-zinc-500">
<li><a href="#" className="hover:text-white transition-colors">About Us</a></li>
<li><a href="#" className="hover:text-white transition-colors">Claims Process</a></li>
<li><a href="#" className="hover:text-white transition-colors">Privacy Policy</a></li>
<li><a href="#" className="hover:text-white transition-colors">Terms & Conditions</a></li>
</ul>
</div>
<div>
<h4 className="font-bold mb-6 text-sm uppercase tracking-widest text-zinc-400">Contact</h4>
<ul className="space-y-4 text-sm text-zinc-500">
<li className="flex items-center gap-3"><Mail className="w-4 h-4" /> care@generalicentral.com</li>
<li className="flex items-center gap-3"><Phone className="w-4 h-4" /> 1800 102 2355</li>
</ul>
</div>
</div>
<div className="pt-12 border-t border-white/5 text-center text-xs text-zinc-600">
<p>© 2026 Generali Central Life Insurance Company Limited. IRDAI Regn. No.: 133 | CIN: U66010MH2006PLC165288</p>
<p className="mt-2 italic">Insurance is the subject matter of solicitation. For more details on risk factors, terms and conditions, please read sales brochure carefully before concluding a sale.</p>
</div>
</div>
</footer>
);
export default function App() {
return (
<div className="min-h-screen bg-white font-sans selection:bg-red-100 selection:text-red-900">
<Navbar />
<main>
<Hero />
{/* Quick Stats */}
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 -mt-12 relative z-20">
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
{[
{ label: "Claims Ratio", value: "98.4%", icon: ShieldCheck },
{ label: "Happy Families", value: "2.5M+", icon: User },
{ label: "Solvency Ratio", value: "1.92", icon: TrendingUp },
{ label: "Support", value: "24/7", icon: Phone },
].map((stat, i) => (
<div key={i} className="bg-white p-6 rounded-2xl shadow-xl border border-zinc-100 flex flex-col items-center text-center">
<stat.icon className="w-6 h-6 text-red-600 mb-3" />
<div className="text-2xl font-bold text-zinc-900">{stat.value}</div>
<div className="text-[10px] font-bold text-zinc-400 uppercase tracking-widest">{stat.label}</div>
</div>
))}
</div>
</div>
<PlanExplanation />
{/* Plan Comparison Section */}
<section id="plans" className="py-24 bg-zinc-900 text-white overflow-hidden">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex flex-col md:flex-row justify-between items-end mb-16 gap-8">
<div className="max-w-xl">
<h2 className="text-4xl font-bold mb-4">Choose Your Shield</h2>
<p className="text-zinc-400">Whether you need periodic payouts or a long-term income stream, we have the right plan for your life's milestones.</p>
</div>
<div className="flex gap-2">
<div className="w-12 h-12 rounded-full border border-white/10 flex items-center justify-center text-zinc-500">01</div>
<div className="w-12 h-12 rounded-full border border-white/10 flex items-center justify-center text-zinc-500">02</div>
</div>
</div>
<div className="grid md:grid-cols-2 gap-8">
<div className="group relative p-10 rounded-3xl bg-white/5 border border-white/10 hover:bg-white/10 transition-all cursor-pointer overflow-hidden">
<div className="absolute top-0 right-0 p-8 opacity-10 group-hover:opacity-20 transition-opacity">
<TrendingUp className="w-32 h-32" />
</div>
<span className="text-red-400 text-xs font-bold uppercase tracking-widest mb-4 block">Best for Milestones</span>
<h3 className="text-3xl font-bold mb-6">Money Back Super Plan</h3>
<ul className="space-y-4 mb-10 text-zinc-400">
<li className="flex items-center gap-3"><CheckCircle2 className="w-5 h-5 text-emerald-500" /> Guaranteed Survival Benefits every 5 years</li>
<li className="flex items-center gap-3"><CheckCircle2 className="w-5 h-5 text-emerald-500" /> Accrued Guaranteed Additions</li>
<li className="flex items-center gap-3"><CheckCircle2 className="w-5 h-5 text-emerald-500" /> Life cover for the entire policy term</li>
</ul>
{/*<button className="w-full py-4 rounded-xl bg-white text-zinc-900 font-bold hover:bg-zinc-100 transition-colors">Explore Plan</button>*/}
</div>
<div className="group relative p-10 rounded-3xl bg-white/5 border border-white/10 hover:bg-white/10 transition-all cursor-pointer overflow-hidden">
<div className="absolute top-0 right-0 p-8 opacity-10 group-hover:opacity-20 transition-opacity">
<Clock className="w-32 h-32" />
</div>
<span className="text-red-400 text-xs font-bold uppercase tracking-widest mb-4 block">Best for Retirement</span>
<h3 className="text-3xl font-bold mb-6">Long Term Income Plan</h3>
<ul className="space-y-4 mb-10 text-zinc-400">
<li className="flex items-center gap-3"><CheckCircle2 className="w-5 h-5 text-emerald-500" /> Regular income for up to 50 years</li>
<li className="flex items-center gap-3"><CheckCircle2 className="w-5 h-5 text-emerald-500" /> Immediate or Deferred income options</li>
<li className="flex items-center gap-3"><CheckCircle2 className="w-5 h-5 text-emerald-500" /> Maturity benefit equal to Sum Assured</li>
</ul>
{/*<button className="w-full py-4 rounded-xl bg-white text-zinc-900 font-bold hover:bg-zinc-100 transition-colors">Explore Plan</button>*/}
</div>
</div>
</div>
</section>
<section id="contact" className="py-24 bg-zinc-50 border-t border-zinc-100">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="bg-white rounded-[2rem] shadow-2xl overflow-hidden flex flex-col md:flex-row">
<div className="md:w-1/2 bg-red-600 p-12 text-white flex flex-col justify-center">
<h2 className="text-4xl font-bold mb-6">Talk to an Expert</h2>
<p className="text-red-100 mb-8 leading-relaxed">
Our certified financial advisors are ready to help you customize a plan that perfectly fits your family's needs and budget.
</p>
<div className="space-y-6">
<div className="flex items-center gap-4">
<div className="w-12 h-12 bg-white/10 rounded-xl flex items-center justify-center">
<Phone className="w-6 h-6" />
</div>
<div>
<div className="text-xs font-bold uppercase tracking-widest text-red-200">Call Us</div>
<div className="text-xl font-bold">1800 102 2355</div>
</div>
</div>
<div className="flex items-center gap-4">
<div className="w-12 h-12 bg-white/10 rounded-xl flex items-center justify-center">
<Mail className="w-6 h-6" />
</div>
<div>
<div className="text-xs font-bold uppercase tracking-widest text-red-200">Email Us</div>
<div className="text-xl font-bold">care@generalicentral.com</div>
</div>
</div>
</div>
</div>
<div className="md:w-1/2 p-12">
<form className="space-y-6">
<div className="grid grid-cols-2 gap-4">
<div>
<label className="block text-sm font-semibold text-zinc-700 mb-2">First Name</label>
<input type="text" className="w-full px-4 py-3 rounded-xl border border-zinc-200 focus:ring-2 focus:ring-red-500 outline-none transition-all" />
</div>
<div>
<label className="block text-sm font-semibold text-zinc-700 mb-2">Last Name</label>
<input type="text" className="w-full px-4 py-3 rounded-xl border border-zinc-200 focus:ring-2 focus:ring-red-500 outline-none transition-all" />
</div>
</div>
<div>
<label className="block text-sm font-semibold text-zinc-700 mb-2">Email Address</label>
<input type="email" className="w-full px-4 py-3 rounded-xl border border-zinc-200 focus:ring-2 focus:ring-red-500 outline-none transition-all" />
</div>
<div>
<label className="block text-sm font-semibold text-zinc-700 mb-2">Phone Number</label>
<input type="tel" className="w-full px-4 py-3 rounded-xl border border-zinc-200 focus:ring-2 focus:ring-red-500 outline-none transition-all" />
</div>
<div>
<label className="block text-sm font-semibold text-zinc-700 mb-2">Your Message</label>
<textarea rows={4} className="w-full px-4 py-3 rounded-xl border border-zinc-200 focus:ring-2 focus:ring-red-500 outline-none transition-all resize-none"></textarea>
</div>
<button type="button" className="w-full bg-zinc-900 text-white py-4 rounded-xl font-bold hover:bg-zinc-800 transition-all shadow-lg shadow-zinc-200">
Send Message
</button>
</form>
</div>
</div>
</div>
</section>
{/* <QuoteForm> */}
{/* Trust Section */}
{/*<section className="py-24 bg-white">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
<h2 className="text-zinc-400 text-xs font-bold uppercase tracking-widest mb-12">Trusted by Industry Leaders</h2>
<div className="flex flex-wrap justify-center items-center gap-12 opacity-30 grayscale">
<div className="text-2xl font-black italic">GENERALI</div>
<div className="text-2xl font-black italic">FUTURE GROUP</div>
<div className="text-2xl font-black italic">CENTRAL BANK</div>
<div className="text-2xl font-black italic">IRDAI</div>
</div>
</div>
</section> */}
</main>
<Footer />
</div>
);
}

1
src/index.css Normal file
View File

@ -0,0 +1 @@
@import "tailwindcss";

10
src/main.tsx Normal file
View File

@ -0,0 +1,10 @@
import {StrictMode} from 'react';
import {createRoot} from 'react-dom/client';
import App from './App.tsx';
import './index.css';
createRoot(document.getElementById('root')!).render(
<StrictMode>
<App />
</StrictMode>,
);

26
tsconfig.json Normal file
View File

@ -0,0 +1,26 @@
{
"compilerOptions": {
"target": "ES2022",
"experimentalDecorators": true,
"useDefineForClassFields": false,
"module": "ESNext",
"lib": [
"ES2022",
"DOM",
"DOM.Iterable"
],
"skipLibCheck": true,
"moduleResolution": "bundler",
"isolatedModules": true,
"moduleDetection": "force",
"allowJs": true,
"jsx": "react-jsx",
"paths": {
"@/*": [
"./*"
]
},
"allowImportingTsExtensions": true,
"noEmit": true
}
}

24
vite.config.ts Normal file
View File

@ -0,0 +1,24 @@
import tailwindcss from '@tailwindcss/vite';
import react from '@vitejs/plugin-react';
import path from 'path';
import {defineConfig, loadEnv} from 'vite';
export default defineConfig(({mode}) => {
const env = loadEnv(mode, '.', '');
return {
plugins: [react(), tailwindcss()],
define: {
'process.env.GEMINI_API_KEY': JSON.stringify(env.GEMINI_API_KEY),
},
resolve: {
alias: {
'@': path.resolve(__dirname, '.'),
},
},
server: {
// HMR is disabled in AI Studio via DISABLE_HMR env var.
// Do not modify—file watching is disabled to prevent flickering during agent edits.
hmr: process.env.DISABLE_HMR !== 'true',
},
};
});