Refactor global currency to UAE standards (AED/Million) and update dummy data

This commit is contained in:
CycroftX
2026-02-15 18:49:13 +05:30
parent a493596ebe
commit 58fe801eab
10 changed files with 457 additions and 562 deletions

View File

@@ -6,6 +6,7 @@ import { Progress } from '@/components/ui/progress';
import { Input } from '@/components/ui/input'; import { Input } from '@/components/ui/input';
import { GlassCard } from '@/components/ui/GlassCard'; import { GlassCard } from '@/components/ui/GlassCard';
import { BudgetRing } from '@/components/BudgetRing'; import { BudgetRing } from '@/components/BudgetRing';
import { formatCurrency } from '@/lib/utils';
import { import {
TrendingUp, TrendingUp,
TrendingDown, TrendingDown,
@@ -25,26 +26,26 @@ import {
const Dashboard: React.FC = () => { const Dashboard: React.FC = () => {
const portfolioData = { const portfolioData = {
totalValue: 9850000, // ₹98.5 lakhs totalValue: 350000,
change: 3.2, change: 3.2,
isPositive: true isPositive: true
}; };
const budgetData = { const budgetData = {
spent: 45000, spent: 4500,
budget: 65000, budget: 6500,
categories: [ categories: [
{ name: 'Food', spent: 12500, budget: 18000, color: 'text-orange-500' }, { name: 'Food', spent: 1250, budget: 1800, color: 'text-orange-500' },
{ name: 'Transport', spent: 8500, budget: 12000, color: 'text-blue-500' }, { name: 'Transport', spent: 850, budget: 1200, color: 'text-blue-500' },
{ name: 'Entertainment', spent: 6000, budget: 8000, color: 'text-purple-500' }, { name: 'Entertainment', spent: 600, budget: 800, color: 'text-purple-500' },
{ name: 'Shopping', spent: 18000, budget: 27000, color: 'text-pink-500' } { name: 'Shopping', spent: 1800, budget: 2700, color: 'text-pink-500' }
] ]
}; };
const savingsGoals = [ const savingsGoals = [
{ name: 'Emergency Fund', current: 450000, target: 800000, color: 'from-green-400 to-green-600' }, { name: 'Emergency Fund', current: 45000, target: 80000, color: 'from-green-400 to-green-600' },
{ name: 'Goa Trip', current: 85000, target: 150000, color: 'from-blue-400 to-blue-600' }, { name: 'Dubai Trip', current: 8500, target: 15000, color: 'from-blue-400 to-blue-600' },
{ name: 'New Car', current: 620000, target: 1200000, color: 'from-purple-400 to-purple-600' } { name: 'New Car', current: 62000, target: 120000, color: 'from-purple-400 to-purple-600' }
]; ];
const creditScore = 768; const creditScore = 768;
@@ -115,7 +116,7 @@ const Dashboard: React.FC = () => {
</div> </div>
<div> <div>
<p className="text-sm text-slate-500 font-medium">Total Net Worth</p> <p className="text-sm text-slate-500 font-medium">Total Net Worth</p>
<h3 className="text-3xl font-bold text-slate-800 mt-1">{(portfolioData.totalValue / 100000).toFixed(2)}L</h3> <h3 className="text-3xl font-bold text-slate-800 mt-1">{formatCurrency(portfolioData.totalValue)}</h3>
</div> </div>
</GlassCard> </GlassCard>
@@ -131,7 +132,7 @@ const Dashboard: React.FC = () => {
</div> </div>
<div> <div>
<p className="text-sm text-slate-500 font-medium">Total Savings</p> <p className="text-sm text-slate-500 font-medium">Total Savings</p>
<h3 className="text-3xl font-bold text-slate-800 mt-1">{(portfolioData.totalValue * 0.15 / 100000).toFixed(2)}L</h3> <h3 className="text-3xl font-bold text-slate-800 mt-1">{formatCurrency(portfolioData.totalValue * 0.15)}</h3>
</div> </div>
</GlassCard> </GlassCard>
@@ -167,7 +168,7 @@ const Dashboard: React.FC = () => {
</div> </div>
<div> <div>
<h4 className="font-medium text-slate-800">Optimize Savings</h4> <h4 className="font-medium text-slate-800">Optimize Savings</h4>
<p className="text-sm text-slate-500 mt-1 leading-relaxed">Cancel unused Hotstar subscription to save ₹1,499/year. You haven't used it in 3 months.</p> <p className="text-sm text-slate-500 mt-1 leading-relaxed">Cancel unused streaming subscription to save {formatCurrency(150)}/year. You haven't used it in 3 months.</p>
</div> </div>
</div> </div>
<div className="p-4 rounded-xl bg-pink-50/50 border border-pink-100 flex gap-4 items-start"> <div className="p-4 rounded-xl bg-pink-50/50 border border-pink-100 flex gap-4 items-start">
@@ -176,7 +177,7 @@ const Dashboard: React.FC = () => {
</div> </div>
<div> <div>
<h4 className="font-medium text-slate-800">Credit utilization</h4> <h4 className="font-medium text-slate-800">Credit utilization</h4>
<p className="text-sm text-slate-500 mt-1 leading-relaxed">Pay down 12k on HDFC card to keep utilization under 30%.</p> <p className="text-sm text-slate-500 mt-1 leading-relaxed">Pay down {formatCurrency(1200)} on ADCB card to keep utilization under 30%.</p>
</div> </div>
</div> </div>
</div> </div>
@@ -192,7 +193,7 @@ const Dashboard: React.FC = () => {
<div key={idx}> <div key={idx}>
<div className="flex justify-between text-sm mb-2"> <div className="flex justify-between text-sm mb-2">
<span className="font-medium text-slate-700">{goal.name}</span> <span className="font-medium text-slate-700">{goal.name}</span>
<span className="text-slate-500">{(goal.current / 1000).toFixed(0)}k / {(goal.target / 1000).toFixed(0)}k</span> <span className="text-slate-500">{formatCurrency(goal.current)} / {formatCurrency(goal.target)}</span>
</div> </div>
<div className="h-2 w-full bg-slate-100 rounded-full overflow-hidden"> <div className="h-2 w-full bg-slate-100 rounded-full overflow-hidden">
<motion.div <motion.div

View File

@@ -14,13 +14,12 @@ import {
ArrowRight, ArrowRight,
AlertCircle AlertCircle
} from 'lucide-react'; } from 'lucide-react';
import { cn } from '@/lib/utils'; import { cn, formatCurrency } from '@/lib/utils';
// Mock Data // Mock Data
const budgetData = { const budgetData = {
limit: 15000, limit: 15000,
spent: 12500, spent: 12500,
currency: 'AED',
categories: [ categories: [
{ name: 'Housing', icon: Home, spent: 6500, limit: 7000, color: 'bg-blue-500' }, { name: 'Housing', icon: Home, spent: 6500, limit: 7000, color: 'bg-blue-500' },
{ name: 'Food & Dining', icon: Utensils, spent: 2800, limit: 3000, color: 'bg-green-500' }, { name: 'Food & Dining', icon: Utensils, spent: 2800, limit: 3000, color: 'bg-green-500' },
@@ -28,8 +27,8 @@ const budgetData = {
{ name: 'Shopping', icon: ShoppingCart, spent: 2000, limit: 1500, color: 'bg-pink-500' }, // Over budget { name: 'Shopping', icon: ShoppingCart, spent: 2000, limit: 1500, color: 'bg-pink-500' }, // Over budget
], ],
goals: [ goals: [
{ name: 'Buy a House', target: 2000000, current: 450000, color: 'bg-purple-500' }, { name: 'Buy a House', target: 800000, current: 200000, color: 'bg-purple-500' },
{ name: 'Retirement', target: 5000000, current: 120000, color: 'bg-indigo-500' }, { name: 'Retirement', target: 2000000, current: 150000, color: 'bg-indigo-500' },
] ]
}; };
@@ -88,10 +87,10 @@ export default function BudgetManager() {
<div className="absolute flex flex-col items-center"> <div className="absolute flex flex-col items-center">
<span className="text-xs sm:text-sm text-slate-500 font-medium uppercase tracking-wider">Total Spent</span> <span className="text-xs sm:text-sm text-slate-500 font-medium uppercase tracking-wider">Total Spent</span>
<span className="text-3xl sm:text-4xl font-bold text-slate-900 mt-1"> <span className="text-3xl sm:text-4xl font-bold text-slate-900 mt-1">
{budgetData.currency} {budgetData.spent.toLocaleString()} {formatCurrency(budgetData.spent)}
</span> </span>
<span className="text-xs sm:text-sm text-slate-400 mt-1"> <span className="text-xs sm:text-sm text-slate-400 mt-1">
of {budgetData.currency} {budgetData.limit.toLocaleString()} of {formatCurrency(budgetData.limit)}
</span> </span>
</div> </div>
</div> </div>
@@ -131,8 +130,8 @@ export default function BudgetManager() {
<span className="font-medium text-slate-700">{cat.name}</span> <span className="font-medium text-slate-700">{cat.name}</span>
</div> </div>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<span className="font-semibold">{budgetData.currency} {cat.spent.toLocaleString()}</span> <span className="font-semibold">{formatCurrency(cat.spent)}</span>
<span className="text-slate-400">/ {cat.limit.toLocaleString()}</span> <span className="text-slate-400">/ {formatCurrency(cat.limit)}</span>
</div> </div>
</div> </div>
<div className="h-2.5 bg-slate-100 rounded-full overflow-hidden"> <div className="h-2.5 bg-slate-100 rounded-full overflow-hidden">
@@ -176,8 +175,8 @@ export default function BudgetManager() {
</div> </div>
<Progress value={(goal.current / goal.target) * 100} className="h-2" indicatorClassName={goal.color} /> <Progress value={(goal.current / goal.target) * 100} className="h-2" indicatorClassName={goal.color} />
<div className="flex justify-between text-xs text-slate-400 pt-1"> <div className="flex justify-between text-xs text-slate-400 pt-1">
<span>{budgetData.currency} {(goal.current / 1000).toFixed(0)}k</span> <span>{formatCurrency(goal.current)}</span>
<span>{budgetData.currency} {(goal.target / 1000000).toFixed(1)}M</span> <span>{formatCurrency(goal.target)}</span>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -18,47 +18,47 @@ import {
Heart, Heart,
Trophy, Trophy,
Star, Star,
IndianRupee, AlertCircle,
Plus, Plus
AlertCircle
} from 'lucide-react'; } from 'lucide-react';
import { formatCurrency } from '@/lib/utils';
const GoalPlanning: React.FC = () => { const GoalPlanning: React.FC = () => {
const financialGoals = [ const financialGoals = [
{ {
id: 1, id: 1,
title: 'Emergency Fund', title: 'Emergency Fund',
description: '6-12 months of living expenses', description: '6 months of living expenses',
category: 'Security', category: 'Security',
icon: <Heart className="w-6 h-6" />, icon: <Heart className="w-6 h-6" />,
targetAmount: 600000, targetAmount: 60000,
currentAmount: 450000, currentAmount: 45000,
monthlyContribution: 15000, monthlyContribution: 2500,
targetDate: '2024-12-31', targetDate: '2024-12-31',
priority: 'high', priority: 'high',
status: 'on-track', status: 'on-track',
milestones: [ milestones: [
{ amount: 200000, completed: true, date: '2023-06-01' }, { amount: 20000, completed: true, date: '2023-06-01' },
{ amount: 400000, completed: true, date: '2023-12-01' }, { amount: 40000, completed: true, date: '2023-12-01' },
{ amount: 600000, completed: false, date: '2024-12-31' } { amount: 60000, completed: false, date: '2024-12-31' }
] ]
}, },
{ {
id: 2, id: 2,
title: 'Home Down Payment', title: 'Home Down Payment',
description: '20% down payment for ₹85L home', description: '20% down payment for home',
category: 'Investment', category: 'Investment',
icon: <Home className="w-6 h-6" />, icon: <Home className="w-6 h-6" />,
targetAmount: 1700000, targetAmount: 250000,
currentAmount: 850000, currentAmount: 120000,
monthlyContribution: 25000, monthlyContribution: 5000,
targetDate: '2025-08-31', targetDate: '2025-08-31',
priority: 'high', priority: 'high',
status: 'behind', status: 'behind',
milestones: [ milestones: [
{ amount: 500000, completed: true, date: '2023-08-01' }, { amount: 100000, completed: true, date: '2023-08-01' },
{ amount: 1000000, completed: false, date: '2024-06-01' }, { amount: 200000, completed: false, date: '2024-06-01' },
{ amount: 1700000, completed: false, date: '2025-08-31' } { amount: 250000, completed: false, date: '2025-08-31' }
] ]
}, },
{ {
@@ -67,16 +67,16 @@ const GoalPlanning: React.FC = () => {
description: '15-day Europe trip for family', description: '15-day Europe trip for family',
category: 'Lifestyle', category: 'Lifestyle',
icon: <Plane className="w-6 h-6" />, icon: <Plane className="w-6 h-6" />,
targetAmount: 350000, targetAmount: 35000,
currentAmount: 185000, currentAmount: 18500,
monthlyContribution: 12000, monthlyContribution: 1500,
targetDate: '2024-09-30', targetDate: '2024-09-30',
priority: 'medium', priority: 'medium',
status: 'on-track', status: 'on-track',
milestones: [ milestones: [
{ amount: 150000, completed: true, date: '2023-12-01' }, { amount: 15000, completed: true, date: '2023-12-01' },
{ amount: 250000, completed: false, date: '2024-05-01' }, { amount: 25000, completed: false, date: '2024-05-01' },
{ amount: 350000, completed: false, date: '2024-09-30' } { amount: 35000, completed: false, date: '2024-09-30' }
] ]
}, },
{ {
@@ -85,16 +85,16 @@ const GoalPlanning: React.FC = () => {
description: 'Higher education fund for children', description: 'Higher education fund for children',
category: 'Education', category: 'Education',
icon: <GraduationCap className="w-6 h-6" />, icon: <GraduationCap className="w-6 h-6" />,
targetAmount: 2500000, targetAmount: 500000,
currentAmount: 280000, currentAmount: 85000,
monthlyContribution: 18000, monthlyContribution: 2500,
targetDate: '2035-06-30', targetDate: '2035-06-30',
priority: 'medium', priority: 'medium',
status: 'on-track', status: 'on-track',
milestones: [ milestones: [
{ amount: 500000, completed: false, date: '2026-06-30' }, { amount: 150000, completed: false, date: '2026-06-30' },
{ amount: 1500000, completed: false, date: '2030-06-30' }, { amount: 300000, completed: false, date: '2030-06-30' },
{ amount: 2500000, completed: false, date: '2035-06-30' } { amount: 500000, completed: false, date: '2035-06-30' }
] ]
}, },
{ {
@@ -103,16 +103,16 @@ const GoalPlanning: React.FC = () => {
description: 'Premium SUV purchase', description: 'Premium SUV purchase',
category: 'Lifestyle', category: 'Lifestyle',
icon: <Car className="w-6 h-6" />, icon: <Car className="w-6 h-6" />,
targetAmount: 1200000, targetAmount: 150000,
currentAmount: 620000, currentAmount: 90000,
monthlyContribution: 20000, monthlyContribution: 5000,
targetDate: '2025-03-31', targetDate: '2025-03-31',
priority: 'low', priority: 'low',
status: 'ahead', status: 'ahead',
milestones: [ milestones: [
{ amount: 400000, completed: true, date: '2023-09-01' }, { amount: 40000, completed: true, date: '2023-09-01' },
{ amount: 800000, completed: false, date: '2024-08-01' }, { amount: 80000, completed: true, date: '2024-08-01' },
{ amount: 1200000, completed: false, date: '2025-03-31' } { amount: 150000, completed: false, date: '2025-03-31' }
] ]
} }
]; ];
@@ -121,8 +121,8 @@ const GoalPlanning: React.FC = () => {
{ {
goalId: 1, goalId: 1,
strategies: [ strategies: [
'Automate ₹15K monthly transfer to high-yield savings', 'Automate AED 2,500 monthly transfer to high-yield savings',
'Use liquid funds for better returns (6-7%)', 'Use liquid funds for better returns (4-5%)',
'Keep 3 months in savings, rest in liquid funds', 'Keep 3 months in savings, rest in liquid funds',
'Review and adjust monthly as expenses change' 'Review and adjust monthly as expenses change'
], ],
@@ -137,13 +137,13 @@ const GoalPlanning: React.FC = () => {
strategies: [ strategies: [
'Increase SIP allocation to equity funds', 'Increase SIP allocation to equity funds',
'Use step-up SIPs with salary increments', 'Use step-up SIPs with salary increments',
'Consider ELSS for tax benefits', 'Consider diversified ETFs for steady growth',
'Time market entry closer to purchase date' 'Time market entry closer to purchase date'
], ],
tips: [ tips: [
'Start researching locations 2 years before', 'Start researching locations 2 years before',
'Factor in registration and other costs (8-10%)', 'Factor in registration and agency fees (4-6%)',
'Consider pre-approved home loans for negotiation' 'Consider pre-approved mortgages for negotiation'
] ]
}, },
{ {
@@ -151,7 +151,7 @@ const GoalPlanning: React.FC = () => {
strategies: [ strategies: [
'Use conservative investments (debt funds)', 'Use conservative investments (debt funds)',
'Book travel during off-season for savings', 'Book travel during off-season for savings',
'Consider travel credit cards for rewards', 'Consider travel credit cards for rewards (Skywards)',
'Track flight prices for best deals' 'Track flight prices for best deals'
], ],
tips: [ tips: [
@@ -204,11 +204,11 @@ const GoalPlanning: React.FC = () => {
const now = new Date(); const now = new Date();
const diffTime = target.getTime() - now.getTime(); const diffTime = target.getTime() - now.getTime();
const diffMonths = Math.ceil(diffTime / (1000 * 60 * 60 * 24 * 30)); const diffMonths = Math.ceil(diffTime / (1000 * 60 * 60 * 24 * 30));
if (diffMonths < 0) return 'Overdue'; if (diffMonths < 0) return 'Overdue';
if (diffMonths === 0) return 'This month'; if (diffMonths === 0) return 'This month';
if (diffMonths < 12) return `${diffMonths} months`; if (diffMonths < 12) return `${diffMonths} months`;
const years = Math.floor(diffMonths / 12); const years = Math.floor(diffMonths / 12);
const months = diffMonths % 12; const months = diffMonths % 12;
return months > 0 ? `${years}y ${months}m` : `${years} years`; return months > 0 ? `${years}y ${months}m` : `${years} years`;
@@ -262,7 +262,7 @@ const GoalPlanning: React.FC = () => {
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div> <div>
<p className="text-sm font-medium text-muted-foreground">Target Amount</p> <p className="text-sm font-medium text-muted-foreground">Target Amount</p>
<p className="text-2xl font-bold">{(progressInsights.totalTargetAmount / 100000).toFixed(1)}L</p> <p className="text-2xl font-bold">{formatCurrency(progressInsights.totalTargetAmount)}</p>
<p className="text-sm text-muted-foreground">Total across goals</p> <p className="text-sm text-muted-foreground">Total across goals</p>
</div> </div>
<div className="w-12 h-12 rounded-xl bg-gradient-to-br from-blue-400 to-blue-600 flex items-center justify-center"> <div className="w-12 h-12 rounded-xl bg-gradient-to-br from-blue-400 to-blue-600 flex items-center justify-center">
@@ -277,7 +277,7 @@ const GoalPlanning: React.FC = () => {
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div> <div>
<p className="text-sm font-medium text-muted-foreground">Monthly SIP</p> <p className="text-sm font-medium text-muted-foreground">Monthly SIP</p>
<p className="text-2xl font-bold">{(progressInsights.monthlyCommitment / 1000).toFixed(0)}K</p> <p className="text-2xl font-bold">{formatCurrency(progressInsights.monthlyCommitment)}</p>
<p className="text-sm text-muted-foreground">Total commitment</p> <p className="text-sm text-muted-foreground">Total commitment</p>
</div> </div>
<div className="w-12 h-12 rounded-xl bg-gradient-to-br from-purple-400 to-purple-600 flex items-center justify-center"> <div className="w-12 h-12 rounded-xl bg-gradient-to-br from-purple-400 to-purple-600 flex items-center justify-center">
@@ -304,7 +304,7 @@ const GoalPlanning: React.FC = () => {
Add New Goal Add New Goal
</Button> </Button>
</div> </div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6"> <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{financialGoals.map((goal) => ( {financialGoals.map((goal) => (
<Card key={goal.id} className="widget"> <Card key={goal.id} className="widget">
@@ -334,18 +334,18 @@ const GoalPlanning: React.FC = () => {
<div> <div>
<div className="flex justify-between text-sm mb-2"> <div className="flex justify-between text-sm mb-2">
<span>Progress</span> <span>Progress</span>
<span>{(goal.currentAmount / 100000).toFixed(1)}L / {(goal.targetAmount / 100000).toFixed(1)}L</span> <span>{formatCurrency(goal.currentAmount)} / {formatCurrency(goal.targetAmount)}</span>
</div> </div>
<Progress value={(goal.currentAmount / goal.targetAmount) * 100} className="h-3" /> <Progress value={(goal.currentAmount / goal.targetAmount) * 100} className="h-3" />
<p className="text-xs text-muted-foreground mt-1"> <p className="text-xs text-muted-foreground mt-1">
{Math.round((goal.currentAmount / goal.targetAmount) * 100)}% completed {Math.round((goal.currentAmount / goal.targetAmount) * 100)}% completed
</p> </p>
</div> </div>
<div className="grid grid-cols-2 gap-4 text-sm"> <div className="grid grid-cols-2 gap-4 text-sm">
<div> <div>
<p className="text-muted-foreground">Monthly SIP</p> <p className="text-muted-foreground">Monthly SIP</p>
<p className="font-semibold">{(goal.monthlyContribution / 1000).toFixed(0)}K</p> <p className="font-semibold">{formatCurrency(goal.monthlyContribution)}</p>
</div> </div>
<div> <div>
<p className="text-muted-foreground">Time Remaining</p> <p className="text-muted-foreground">Time Remaining</p>
@@ -399,22 +399,22 @@ const GoalPlanning: React.FC = () => {
</Badge> </Badge>
</div> </div>
</div> </div>
<div className="space-y-3"> <div className="space-y-3">
<Progress value={(goal.currentAmount / goal.targetAmount) * 100} className="h-2" /> <Progress value={(goal.currentAmount / goal.targetAmount) * 100} className="h-2" />
<div className="grid grid-cols-3 gap-4 text-sm"> <div className="grid grid-cols-3 gap-4 text-sm">
<div> <div>
<p className="text-muted-foreground">Current</p> <p className="text-muted-foreground">Current</p>
<p className="font-semibold">{(goal.currentAmount / 100000).toFixed(1)}L</p> <p className="font-semibold">{formatCurrency(goal.currentAmount)}</p>
</div> </div>
<div> <div>
<p className="text-muted-foreground">Monthly SIP</p> <p className="text-muted-foreground">Monthly SIP</p>
<p className="font-semibold">{(goal.monthlyContribution / 1000).toFixed(0)}K</p> <p className="font-semibold">{formatCurrency(goal.monthlyContribution)}</p>
</div> </div>
<div> <div>
<p className="text-muted-foreground">Remaining</p> <p className="text-muted-foreground">Remaining</p>
<p className="font-semibold">{((goal.targetAmount - goal.currentAmount) / 100000).toFixed(1)}L</p> <p className="font-semibold">{formatCurrency(goal.targetAmount - goal.currentAmount)}</p>
</div> </div>
</div> </div>
</div> </div>
@@ -438,7 +438,7 @@ const GoalPlanning: React.FC = () => {
{goalStrategies.map((strategy) => { {goalStrategies.map((strategy) => {
const goal = financialGoals.find(g => g.id === strategy.goalId); const goal = financialGoals.find(g => g.id === strategy.goalId);
if (!goal) return null; if (!goal) return null;
return ( return (
<div key={strategy.goalId} className="p-4 rounded-lg border border-gray-200"> <div key={strategy.goalId} className="p-4 rounded-lg border border-gray-200">
<div className="flex items-center mb-4"> <div className="flex items-center mb-4">
@@ -450,7 +450,7 @@ const GoalPlanning: React.FC = () => {
<p className="text-sm text-muted-foreground">AI-optimized strategy</p> <p className="text-sm text-muted-foreground">AI-optimized strategy</p>
</div> </div>
</div> </div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6"> <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div> <div>
<h5 className="font-medium mb-3 text-blue-800">Recommended Strategies</h5> <h5 className="font-medium mb-3 text-blue-800">Recommended Strategies</h5>
@@ -463,7 +463,7 @@ const GoalPlanning: React.FC = () => {
))} ))}
</ul> </ul>
</div> </div>
<div> <div>
<h5 className="font-medium mb-3 text-green-800">Pro Tips</h5> <h5 className="font-medium mb-3 text-green-800">Pro Tips</h5>
<ul className="space-y-2"> <ul className="space-y-2">
@@ -507,7 +507,7 @@ const GoalPlanning: React.FC = () => {
</p> </p>
</div> </div>
</div> </div>
<div className="space-y-3"> <div className="space-y-3">
{goal.milestones.map((milestone, index) => ( {goal.milestones.map((milestone, index) => (
<div key={index} className="flex items-center justify-between p-3 rounded-lg bg-gray-50"> <div key={index} className="flex items-center justify-between p-3 rounded-lg bg-gray-50">
@@ -518,7 +518,7 @@ const GoalPlanning: React.FC = () => {
<Clock className="w-5 h-5 text-gray-400 mr-3" /> <Clock className="w-5 h-5 text-gray-400 mr-3" />
)} )}
<div> <div>
<p className="font-medium">{(milestone.amount / 100000).toFixed(1)}L</p> <p className="font-medium">{formatCurrency(milestone.amount)}</p>
<p className="text-sm text-muted-foreground"> <p className="text-sm text-muted-foreground">
Target: {new Date(milestone.date).toLocaleDateString()} Target: {new Date(milestone.date).toLocaleDateString()}
</p> </p>

View File

@@ -4,6 +4,7 @@ import { GlassCard } from '@/components/ui/GlassCard';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge'; import { Badge } from '@/components/ui/badge';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { formatCurrency } from '@/lib/utils';
import { import {
TrendingUp, TrendingUp,
TrendingDown, TrendingDown,
@@ -11,99 +12,99 @@ import {
Target, Target,
ArrowUpRight, ArrowUpRight,
ArrowDownRight, ArrowDownRight,
IndianRupee,
PieChart, PieChart,
Wallet Wallet,
Coins // Replaced IndianRupee with Coins as a generic financial icon or could use a custom Dirham icon
} from 'lucide-react'; } from 'lucide-react';
const PortfolioManager: React.FC = () => { const PortfolioManager: React.FC = () => {
const [selectedPeriod, setSelectedPeriod] = useState('1M'); const [selectedPeriod, setSelectedPeriod] = useState('1M');
const portfolioOverview = { const portfolioOverview = {
totalValue: 9850000, // ₹98.5L totalValue: 350000,
totalInvested: 8200000, // ₹82L totalInvested: 290000,
totalGains: 1650000, // ₹16.5L totalGains: 60000,
gainPercentage: 20.12, gainPercentage: 20.69,
dayChange: 45000, // ₹45K dayChange: 1500,
dayChangePercent: 0.46 dayChangePercent: 0.46
}; };
const holdings = [ const holdings = [
{ {
name: 'HDFC Bank', name: 'Emirates NBD',
symbol: 'HDFCBANK', symbol: 'ENBD',
shares: 150, shares: 1500,
currentPrice: 1680, currentPrice: 16.80,
invested: 225000, invested: 22500,
currentValue: 252000, currentValue: 25200,
gain: 27000, gain: 2700,
gainPercent: 12.0, gainPercent: 12.0,
sector: 'Banking' sector: 'Banking'
}, },
{ {
name: 'Infosys', name: 'Emaar Properties',
symbol: 'INFY', symbol: 'EMAAR',
shares: 200, shares: 3000,
currentPrice: 1420, currentPrice: 8.20,
invested: 260000, invested: 22000,
currentValue: 284000, currentValue: 24600,
gain: 24000, gain: 2600,
gainPercent: 9.23, gainPercent: 11.8,
sector: 'IT' sector: 'Real Estate'
}, },
{ {
name: 'Reliance Industries', name: 'DEWA',
symbol: 'RELIANCE', symbol: 'DEWA',
shares: 80, shares: 5000,
currentPrice: 2850, currentPrice: 2.50,
invested: 216000, invested: 12000,
currentValue: 228000, currentValue: 12500,
gain: 12000, gain: 500,
gainPercent: 5.56, gainPercent: 4.17,
sector: 'Oil & Gas' sector: 'Utilities'
}, },
{ {
name: 'SBI Bluechip Fund', name: 'US Tech ETF',
symbol: 'SBI-BC', symbol: 'QQQ',
units: 5000, units: 50,
currentPrice: 85.50, currentPrice: 450.50,
invested: 400000, invested: 20000,
currentValue: 427500, currentValue: 22525,
gain: 27500, gain: 2525,
gainPercent: 6.88, gainPercent: 12.6,
sector: 'Mutual Fund' sector: 'ETF'
} }
]; ];
const sectorAllocation = [ const sectorAllocation = [
{ sector: 'Banking', percentage: 35, value: 3447500, color: 'from-blue-400 to-blue-600' }, { sector: 'Banking', percentage: 35, value: 122500, color: 'from-blue-400 to-blue-600' },
{ sector: 'IT', percentage: 25, value: 2462500, color: 'from-green-400 to-green-600' }, { sector: 'Real Estate', percentage: 25, value: 87500, color: 'from-green-400 to-green-600' },
{ sector: 'Mutual Funds', percentage: 20, value: 1970000, color: 'from-purple-400 to-purple-600' }, { sector: 'Utilities', percentage: 20, value: 70000, color: 'from-purple-400 to-purple-600' },
{ sector: 'Oil & Gas', percentage: 15, value: 1477500, color: 'from-red-400 to-red-600' }, { sector: 'Telecom', percentage: 15, value: 52500, color: 'from-red-400 to-red-600' },
{ sector: 'Others', percentage: 5, value: 492500, color: 'from-yellow-400 to-yellow-600' } { sector: 'Others', percentage: 5, value: 17500, color: 'from-yellow-400 to-yellow-600' }
]; ];
const recommendations = [ const recommendations = [
{ {
type: 'rebalance', type: 'rebalance',
title: 'Rebalance Portfolio', title: 'Rebalance Portfolio',
description: 'Your banking allocation is 5% above target. Consider reducing exposure.', description: 'Your real estate allocation is 5% above target. Consider reducing exposure.',
priority: 'medium', priority: 'medium',
action: 'Sell ₹1.5L worth of banking stocks' action: `Sell ${formatCurrency(5000)} worth of real estate stocks`
}, },
{ {
type: 'opportunity', type: 'opportunity',
title: 'Investment Opportunity', title: 'Investment Opportunity',
description: 'HDFC Pharma Fund showing strong momentum with low correlation to your existing holdings.', description: 'Renewable energy ETF showing strong momentum with low correlation to your existing holdings.',
priority: 'high', priority: 'high',
action: 'Consider investing ₹2L' action: `Consider investing ${formatCurrency(10000)}`
}, },
{ {
type: 'risk', type: 'risk',
title: 'Risk Alert', title: 'Risk Alert',
description: 'High concentration in financial sector. Diversify across sectors.', description: 'High concentration in local equity. Diversify globally.',
priority: 'high', priority: 'high',
action: 'Add technology and healthcare exposure' action: 'Add US or Global ETFs'
} }
]; ];
@@ -136,7 +137,7 @@ const PortfolioManager: React.FC = () => {
<BarChart3 className="w-5 h-5 text-white" /> <BarChart3 className="w-5 h-5 text-white" />
</div> </div>
</div> </div>
<p className="text-2xl font-bold text-slate-900">{(portfolioOverview.totalValue / 100000).toFixed(1)}L</p> <p className="text-2xl font-bold text-slate-900">{formatCurrency(portfolioOverview.totalValue)}</p>
<div className="flex items-center mt-2"> <div className="flex items-center mt-2">
<TrendingUp className="w-4 h-4 text-green-500 mr-1" /> <TrendingUp className="w-4 h-4 text-green-500 mr-1" />
<span className="text-sm text-green-600 font-medium">+{portfolioOverview.gainPercentage}%</span> <span className="text-sm text-green-600 font-medium">+{portfolioOverview.gainPercentage}%</span>
@@ -150,18 +151,18 @@ const PortfolioManager: React.FC = () => {
<TrendingUp className="w-5 h-5 text-white" /> <TrendingUp className="w-5 h-5 text-white" />
</div> </div>
</div> </div>
<p className="text-2xl font-bold text-slate-900">{(portfolioOverview.totalGains / 100000).toFixed(1)}L</p> <p className="text-2xl font-bold text-slate-900">{formatCurrency(portfolioOverview.totalGains)}</p>
<p className="text-xs text-slate-400 mt-2">vs {(portfolioOverview.totalInvested / 100000).toFixed(1)}L invested</p> <p className="text-xs text-slate-400 mt-2">vs {formatCurrency(portfolioOverview.totalInvested)} invested</p>
</GlassCard> </GlassCard>
<GlassCard className="p-6"> <GlassCard className="p-6">
<div className="flex items-center justify-between mb-4"> <div className="flex items-center justify-between mb-4">
<p className="text-sm font-medium text-slate-500">Day Change</p> <p className="text-sm font-medium text-slate-500">Day Change</p>
<div className="w-10 h-10 rounded-xl bg-gradient-to-br from-cyan-400 to-cyan-600 flex items-center justify-center shadow-lg shadow-cyan-200"> <div className="w-10 h-10 rounded-xl bg-gradient-to-br from-cyan-400 to-cyan-600 flex items-center justify-center shadow-lg shadow-cyan-200">
<IndianRupee className="w-5 h-5 text-white" /> <Coins className="w-5 h-5 text-white" />
</div> </div>
</div> </div>
<p className="text-2xl font-bold text-slate-900">{(portfolioOverview.dayChange / 1000).toFixed(0)}K</p> <p className="text-2xl font-bold text-slate-900">{formatCurrency(portfolioOverview.dayChange)}</p>
<div className="flex items-center mt-2"> <div className="flex items-center mt-2">
<ArrowUpRight className="w-4 h-4 text-green-500 mr-1" /> <ArrowUpRight className="w-4 h-4 text-green-500 mr-1" />
<span className="text-sm text-green-600 font-medium">+{portfolioOverview.dayChangePercent}%</span> <span className="text-sm text-green-600 font-medium">+{portfolioOverview.dayChangePercent}%</span>
@@ -194,19 +195,19 @@ const PortfolioManager: React.FC = () => {
<div> <div>
<div className="flex justify-between items-start mb-4"> <div className="flex justify-between items-start mb-4">
<div className="p-2 bg-slate-100 rounded-lg"> <div className="p-2 bg-slate-100 rounded-lg">
<span className="font-bold text-slate-700">{holding.symbol.substring(0, 2)}</span> <span className="font-bold text-slate-700">{holding.symbol.substring(0, 4)}</span>
</div> </div>
<Badge variant="outline" className="bg-white/50">{holding.sector}</Badge> <Badge variant="outline" className="bg-white/50">{holding.sector}</Badge>
</div> </div>
<h3 className="font-bold text-lg text-slate-900">{holding.name}</h3> <h3 className="font-bold text-lg text-slate-900">{holding.name}</h3>
<p className="text-sm text-slate-500">{holding.shares} shares @ {holding.currentPrice}</p> <p className="text-sm text-slate-500">{holding.shares} shares @ {formatCurrency(holding.currentPrice)}</p>
</div> </div>
<div className="mt-6 pt-4 border-t border-slate-100"> <div className="mt-6 pt-4 border-t border-slate-100">
<div className="flex justify-between items-end"> <div className="flex justify-between items-end">
<div> <div>
<p className="text-xs text-slate-400">Current Value</p> <p className="text-xs text-slate-400">Current Value</p>
<p className="font-semibold text-lg">{(holding.currentValue / 1000).toFixed(1)}k</p> <p className="font-semibold text-lg">{formatCurrency(holding.currentValue)}</p>
</div> </div>
<div className={`text-right ${holding.gain > 0 ? 'text-green-600' : 'text-red-600'}`}> <div className={`text-right ${holding.gain > 0 ? 'text-green-600' : 'text-red-600'}`}>
<p className="text-xs font-medium flex items-center justify-end"> <p className="text-xs font-medium flex items-center justify-end">
@@ -214,7 +215,7 @@ const PortfolioManager: React.FC = () => {
{holding.gainPercent}% {holding.gainPercent}%
</p> </p>
<p className="text-sm font-bold"> <p className="text-sm font-bold">
{holding.gain > 0 ? '+' : ''}{(holding.gain / 1000).toFixed(1)}k {holding.gain > 0 ? '+' : ''}{formatCurrency(holding.gain)}
</p> </p>
</div> </div>
</div> </div>
@@ -236,7 +237,7 @@ const PortfolioManager: React.FC = () => {
</div> </div>
<div className="text-right"> <div className="text-right">
<span className="font-bold text-slate-900">{sector.percentage}%</span> <span className="font-bold text-slate-900">{sector.percentage}%</span>
<p className="text-xs text-slate-500">{(sector.value / 100000).toFixed(1)}L</p> <p className="text-xs text-slate-500">{formatCurrency(sector.value)}</p>
</div> </div>
</div> </div>
<div className="w-full bg-slate-100 rounded-full h-2 overflow-hidden"> <div className="w-full bg-slate-100 rounded-full h-2 overflow-hidden">

View File

@@ -12,7 +12,7 @@ import {
CheckCircle2, CheckCircle2,
PlayCircle PlayCircle
} from 'lucide-react'; } from 'lucide-react';
import { cn } from '@/lib/utils'; import { cn, formatCurrency } from '@/lib/utils';
import { ResponsiveContainer, AreaChart, Area, XAxis, YAxis, Tooltip } from 'recharts'; import { ResponsiveContainer, AreaChart, Area, XAxis, YAxis, Tooltip } from 'recharts';
// Mock Data // Mock Data
@@ -126,12 +126,12 @@ export default function SavingsBooster() {
<GlassCard className="p-6 flex flex-col justify-center space-y-2 relative overflow-hidden"> <GlassCard className="p-6 flex flex-col justify-center space-y-2 relative overflow-hidden">
<span className="text-slate-500 text-sm">Monthly Potential</span> <span className="text-slate-500 text-sm">Monthly Potential</span>
<div className="flex items-baseline gap-2"> <div className="flex items-baseline gap-2">
<span className="text-3xl font-bold text-slate-900">AED {savingsData.potential.toLocaleString()}</span> <span className="text-3xl font-bold text-slate-900">{formatCurrency(savingsData.potential)}</span>
<span className="text-sm text-slate-400">/mo</span> <span className="text-sm text-slate-400">/mo</span>
</div> </div>
<div className="flex items-center gap-2 text-green-600 text-sm font-medium bg-green-50 px-2 py-1 rounded w-fit"> <div className="flex items-center gap-2 text-green-600 text-sm font-medium bg-green-50 px-2 py-1 rounded w-fit">
<TrendingUp className="w-3 h-3" /> <TrendingUp className="w-3 h-3" />
+ AED {(savingsData.potential - savingsData.current).toLocaleString()} vs current + {formatCurrency(savingsData.potential - savingsData.current)} vs current
</div> </div>
<div className="absolute top-0 right-0 p-4 opacity-10"> <div className="absolute top-0 right-0 p-4 opacity-10">
<TrendingUp className="w-24 h-24 text-green-500" /> <TrendingUp className="w-24 h-24 text-green-500" />

View File

@@ -0,0 +1,272 @@
"use client";
import React from "react";
import { motion } from "framer-motion";
import { ArrowRight, CheckCircle, TrendingUp, Shield, Zap, Globe, Smartphone, CreditCard } from "lucide-react";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
import { useNavigate } from "react-router-dom";
// Animation variants
const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.1,
delayChildren: 0.3,
},
},
};
const itemVariants = {
hidden: { y: 20, opacity: 0 },
visible: {
y: 0,
opacity: 1,
transition: {
type: "spring" as const,
stiffness: 100,
},
},
};
const MoneyflowLandingPage = () => {
const navigate = useNavigate();
return (
<div className="min-h-screen bg-white text-slate-900 overflow-hidden font-sans selection:bg-purple-100 selection:text-purple-900">
{/* Navbar */}
<nav className="fixed top-0 w-full z-50 bg-white/80 backdrop-blur-md border-b border-slate-100">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex justify-between items-center h-16">
<div className="flex items-center gap-2">
<div className="w-8 h-8 rounded-lg bg-gradient-to-br from-purple-600 to-blue-600 flex items-center justify-center text-white font-bold text-lg shadow-lg">
W
</div>
<span className="font-bold text-xl tracking-tight text-slate-900">WealthWise</span>
</div>
<div className="hidden md:flex items-center gap-8 text-sm font-medium text-slate-600">
<a href="#features" className="hover:text-purple-600 transition-colors">Features</a>
<a href="#how-it-works" className="hover:text-purple-600 transition-colors">How it Works</a>
<a href="#pricing" className="hover:text-purple-600 transition-colors">Pricing</a>
</div>
<div className="flex items-center gap-4">
<Button variant="ghost" onClick={() => navigate('/app')} className="hidden sm:flex hover:bg-slate-100 text-slate-700">
Log In
</Button>
<Button onClick={() => navigate('/app')} className="bg-slate-900 hover:bg-slate-800 text-white rounded-full px-6 shadow-lg hover:shadow-xl transition-all">
Get Started
</Button>
</div>
</div>
</div>
</nav>
{/* Hero Section */}
<section className="relative pt-32 pb-20 lg:pt-48 lg:pb-32 overflow-hidden">
{/* Background Gradients */}
<div className="absolute top-0 left-1/2 -translate-x-1/2 w-full h-[500px] bg-gradient-to-b from-purple-50 to-white -z-10" />
<div className="absolute top-0 right-0 w-[800px] h-[800px] bg-blue-100/30 rounded-full blur-3xl -z-10 translate-x-1/3 -translate-y-1/4" />
<div className="absolute bottom-0 left-0 w-[600px] h-[600px] bg-purple-100/30 rounded-full blur-3xl -z-10 -translate-x-1/3 translate-y-1/4" />
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
<motion.div
initial="hidden"
animate="visible"
variants={containerVariants}
className="text-center max-w-4xl mx-auto"
>
<motion.div variants={itemVariants} className="inline-flex items-center px-3 py-1 rounded-full bg-white border border-slate-200 shadow-sm mb-6">
<span className="flex h-2 w-2 rounded-full bg-green-500 mr-2 animate-pulse"></span>
<span className="text-xs font-semibold uppercase tracking-wide text-slate-600">Finance AI Companion 2.0</span>
</motion.div>
<motion.h1 variants={itemVariants} className="text-5xl md:text-7xl font-bold tracking-tight text-slate-900 mb-8 leading-tight">
Master your money with <br />
<span className="bg-clip-text text-transparent bg-gradient-to-r from-purple-600 via-blue-600 to-cyan-500 animate-gradient-x">
Intelligent AI
</span>
</motion.h1>
<motion.p variants={itemVariants} className="text-xl text-slate-600 mb-10 max-w-2xl mx-auto leading-relaxed">
Experience the future of personal finance. Real-time insights, automated budgeting, and AI-driven investment adviceall in one beautiful app.
</motion.p>
<motion.div variants={itemVariants} className="flex flex-col sm:flex-row gap-4 justify-center items-center">
<Button onClick={() => navigate('/app')} size="lg" className="h-14 px-8 rounded-full text-lg w-full sm:w-auto bg-slate-900 text-white hover:bg-slate-800 shadow-xl hover:shadow-2xl transition-all duration-300 transform hover:-translate-y-1">
Start Free Trial <ArrowRight className="ml-2 w-5 h-5" />
</Button>
<Button size="lg" variant="outline" className="h-14 px-8 rounded-full text-lg w-full sm:w-auto border-slate-200 hover:bg-slate-50 hover:border-slate-300 transition-all">
View Live Demo
</Button>
</motion.div>
</motion.div>
{/* Hero Image/Dashboard Preview */}
<motion.div
initial={{ opacity: 0, y: 100, rotateX: 20 }}
animate={{ opacity: 1, y: 0, rotateX: 0 }}
transition={{ duration: 0.8, delay: 0.5, type: "spring" as const }}
className="mt-20 relative mx-auto max-w-5xl perspective-1000"
>
<div className="relative rounded-2xl bg-slate-900 p-2 shadow-2xl ring-1 ring-slate-900/10 backdrop-blur-3xl transform hover:scale-[1.01] transition-transform duration-500">
<div className="absolute top-0 left-0 w-full h-full bg-gradient-to-br from-purple-500/10 to-blue-500/10 rounded-2xl z-0 pointer-events-none" />
<div className="rounded-xl overflow-hidden border border-white/10 bg-slate-950/50 backdrop-blur-sm relative z-10 aspect-[16/9] flex items-center justify-center">
{/* Placeholder for actual dashboard screenshot */}
<div className="text-center p-10">
<div className="w-20 h-20 bg-gradient-to-br from-purple-500 to-blue-500 rounded-2xl mx-auto mb-4 animate-pulse flex items-center justify-center">
<TrendingUp className="w-10 h-10 text-white" />
</div>
<h3 className="text-2xl font-bold text-white mb-2">WealthWise Dashboard</h3>
<p className="text-slate-400">Interactive AI Financial Overview</p>
</div>
{/* Simulated UI Elements */}
<div className="absolute bottom-8 left-8 right-8 h-32 bg-gradient-to-r from-slate-800 to-slate-900 rounded-lg border border-slate-700/50 opacity-50" />
<div className="absolute top-8 right-8 w-64 h-full bg-slate-900/50 border-l border-slate-800/50 backdrop-blur-md" />
</div>
</div>
{/* Floating elements */}
<motion.div
animate={{ y: [0, -20, 0] }}
transition={{ duration: 4, repeat: Infinity, ease: "easeInOut" }}
className="absolute -top-12 -right-12 bg-white rounded-2xl p-4 shadow-xl border border-slate-100 w-48 z-20 hidden md:block"
>
<div className="flex items-center gap-3">
<div className="p-2 bg-green-100 rounded-lg text-green-600"><TrendingUp size={20} /></div>
<div>
<p className="text-xs text-slate-500 uppercase font-bold">Portfolio</p>
<p className="text-lg font-bold text-slate-900">+24.5%</p>
</div>
</div>
</motion.div>
<motion.div
animate={{ y: [0, 20, 0] }}
transition={{ duration: 5, repeat: Infinity, ease: "easeInOut", delay: 1 }}
className="absolute -bottom-8 -left-12 bg-white rounded-2xl p-4 shadow-xl border border-slate-100 w-56 z-20 hidden md:block"
>
<div className="flex items-center gap-3">
<div className="p-2 bg-purple-100 rounded-lg text-purple-600"><Shield size={20} /></div>
<div>
<p className="text-xs text-slate-500 uppercase font-bold">Protection</p>
<p className="text-sm font-medium text-slate-900">Assets Secured</p>
</div>
</div>
</motion.div>
</motion.div>
</div>
</section>
{/* Features Grid */}
<section id="features" className="py-24 bg-slate-50 relative overflow-hidden">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
<div className="text-center max-w-3xl mx-auto mb-16">
<h2 className="text-3xl font-bold text-slate-900 sm:text-4xl mb-4">
Everything you need to grow your wealth
</h2>
<p className="text-lg text-slate-600">
WealthWise combines advanced AI with intuitive design to give you complete control over your financial life.
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
{[
{
icon: <Smartphone className="w-6 h-6 text-purple-600" />,
title: "Mobile First Design",
desc: "Manage your finances on the go with our responsive, fluid mobile interface."
},
{
icon: <Zap className="w-6 h-6 text-yellow-500" />,
title: "Instant Analytics",
desc: "Get real-time insights into your spending habits and saving opportunities."
},
{
icon: <Globe className="w-6 h-6 text-blue-500" />,
title: "Global Markets",
desc: "Track international assets and currencies with seamless integration."
},
{
icon: <Shield className="w-6 h-6 text-green-500" />,
title: "Bank-Grade Security",
desc: "Your data is protected with state-of-the-art encryption and biometrics."
},
{
icon: <CreditCard className="w-6 h-6 text-indigo-500" />,
title: "Smart Budgeting",
desc: "AI automatically categorizes your expenses and sets smart limits."
},
{
icon: <TrendingUp className="w-6 h-6 text-pink-500" />,
title: "Investment AI",
desc: "Personalized portfolio recommendations based on your risk profile."
}
].map((feature, i) => (
<motion.div
key={i}
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ delay: i * 0.1 }}
className="bg-white p-8 rounded-2xl shadow-sm border border-slate-100 hover:shadow-md hover:border-purple-100 transition-all group"
>
<div className="w-12 h-12 bg-slate-50 rounded-xl flex items-center justify-center mb-6 group-hover:bg-purple-50 transition-colors">
{feature.icon}
</div>
<h3 className="text-xl font-bold text-slate-900 mb-3">{feature.title}</h3>
<p className="text-slate-600 leading-relaxed">
{feature.desc}
</p>
</motion.div>
))}
</div>
</div>
</section>
{/* CTA Section */}
<section className="py-24 relative overflow-hidden">
<div className="absolute inset-0 bg-slate-900" />
<div className="absolute inset-0 bg-[linear-gradient(to_right,#80808012_1px,transparent_1px),linear-gradient(to_bottom,#80808012_1px,transparent_1px)] bg-[size:24px_24px]" />
<div className="max-w-4xl mx-auto px-4 relative z-10 text-center">
<h2 className="text-3xl md:text-5xl font-bold text-white mb-6">
Ready to take control?
</h2>
<p className="text-xl text-slate-400 mb-10 max-w-2xl mx-auto">
Join thousands of users who are already building a better financial future with WealthWise.
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<Button onClick={() => navigate('/app')} size="lg" className="h-14 px-8 rounded-full bg-white text-slate-900 hover:bg-slate-100 text-lg font-bold shadow-lg">
Get Started Now
</Button>
<Button size="lg" variant="outline" className="h-14 px-8 rounded-full border-slate-700 text-white hover:bg-slate-800 hover:text-white text-lg">
Contact Sales
</Button>
</div>
</div>
</section>
{/* Footer */}
<footer className="bg-slate-50 py-12 border-t border-slate-200">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex flex-col md:flex-row justify-between items-center gap-6">
<div className="flex items-center gap-2">
<div className="w-6 h-6 rounded bg-gradient-to-br from-purple-600 to-blue-600 flex items-center justify-center text-white text-xs font-bold">
W
</div>
<span className="font-semibold text-slate-900">WealthWise</span>
</div>
<div className="text-slate-500 text-sm">
© 2024 WealthWise Inc. All rights reserved.
</div>
<div className="flex gap-6 text-slate-500">
<a href="#" className="hover:text-slate-900">Privacy</a>
<a href="#" className="hover:text-slate-900">Terms</a>
<a href="#" className="hover:text-slate-900">Twitter</a>
</div>
</div>
</footer>
</div>
);
};
export default MoneyflowLandingPage;

View File

@@ -128,9 +128,19 @@ export const ModernSignIn = () => {
</div> </div>
{/* UAE Pass */} {/* UAE Pass */}
<Button className="w-full h-11 bg-[#008955] hover:bg-[#007a4b] text-white shadow-md flex items-center justify-center gap-2"> <div className="space-y-3">
<Fingerprint className="w-5 h-5" /> Log in with UAE Pass <Button className="w-full h-11 bg-[#008955] hover:bg-[#007a4b] text-white shadow-md flex items-center justify-center gap-2">
</Button> <Fingerprint className="w-5 h-5" /> Log in with UAE Pass
</Button>
<Button
variant="secondary"
onClick={() => login('demo@wealthwise.com', 'demo123')}
className="w-full h-11 bg-slate-100 hover:bg-slate-200 text-slate-900 shadow-sm flex items-center justify-center gap-2 font-medium"
>
<Wallet className="w-5 h-5" /> Try Demo Account
</Button>
</div>
{/* Toggle Mode */} {/* Toggle Mode */}
<div className="mt-8 text-center text-sm text-gray-600"> <div className="mt-8 text-center text-sm text-gray-600">

View File

@@ -4,3 +4,12 @@ import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) { export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs)) return twMerge(clsx(inputs))
} }
export const formatCurrency = (amount: number) => {
return new Intl.NumberFormat('en-AE', {
style: 'currency',
currency: 'AED',
minimumFractionDigits: 0,
maximumFractionDigits: 0,
}).format(amount);
};

View File

@@ -1,415 +1,8 @@
import React, { Suspense, useRef, useState, useEffect } from 'react'; import React from 'react';
import { Canvas, useFrame } from '@react-three/fiber'; import MoneyflowLandingPage from "@/components/ui/fin-tech-landing-page";
import { Float, OrbitControls, Sphere, Box, Torus, Text3D, Center, Environment } from '@react-three/drei';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { useNavigate } from 'react-router-dom';
import {
DollarSign,
TrendingUp,
Shield,
Target,
Zap,
ArrowRight,
CheckCircle,
Star,
Users,
BarChart3,
Brain,
Clock
} from 'lucide-react';
import * as THREE from 'three';
// Error Boundary Component
class Scene3DErrorBoundary extends React.Component<
{ children: React.ReactNode; fallback: React.ReactNode },
{ hasError: boolean }
> {
constructor(props: { children: React.ReactNode; fallback: React.ReactNode }) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error: Error): { hasError: boolean } {
return { hasError: true };
}
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
console.warn('3D Scene Error:', error, errorInfo);
}
render() {
if (this.state.hasError) {
return this.props.fallback;
}
return this.props.children;
}
}
// 3D Scene Components
const FloatingCoin = ({ position }: { position: [number, number, number] }) => {
const meshRef = useRef<THREE.Mesh>(null);
useFrame((state) => {
try {
if (meshRef.current) {
meshRef.current.rotation.y = state.clock.elapsedTime * 0.5;
meshRef.current.rotation.x = Math.sin(state.clock.elapsedTime * 0.3) * 0.1;
}
} catch (error) {
console.warn('FloatingCoin animation error:', error);
}
});
return (
<Float speed={2} rotationIntensity={1} floatIntensity={0.5}>
<mesh ref={meshRef} position={position}>
<cylinderGeometry args={[0.5, 0.5, 0.1, 32]} />
<meshStandardMaterial color="#ffd700" metalness={0.8} roughness={0.2} />
</mesh>
</Float>
);
};
const AnimatedSphere = ({ position, color }: { position: [number, number, number], color: string }) => {
const meshRef = useRef<THREE.Mesh>(null);
useFrame((state) => {
try {
if (meshRef.current) {
meshRef.current.position.y = position[1] + Math.sin(state.clock.elapsedTime) * 0.2;
meshRef.current.rotation.x = state.clock.elapsedTime * 0.2;
meshRef.current.rotation.y = state.clock.elapsedTime * 0.3;
}
} catch (error) {
console.warn('AnimatedSphere animation error:', error);
}
});
return (
<mesh ref={meshRef} position={position}>
<sphereGeometry args={[0.3, 32, 32]} />
<meshStandardMaterial color={color} transparent opacity={0.8} />
</mesh>
);
};
const Scene3D = () => {
try {
return (
<>
<ambientLight intensity={0.5} />
<directionalLight position={[10, 10, 5]} intensity={1} />
{/* Floating Elements */}
<FloatingCoin position={[-2, 1, 0]} />
<FloatingCoin position={[2, -1, 0]} />
<FloatingCoin position={[0, 2, -1]} />
<AnimatedSphere position={[-3, 0, -1]} color="#22d3ee" />
<AnimatedSphere position={[3, 1, -1]} color="#3b82f6" />
<AnimatedSphere position={[0, -2, -1]} color="#8b5cf6" />
{/* Central rotating torus */}
<Float speed={1} rotationIntensity={2}>
<Torus args={[1.5, 0.3, 16, 100]} position={[0, 0, -2]}>
<meshStandardMaterial color="#06b6d4" transparent opacity={0.6} />
</Torus>
</Float>
<OrbitControls enableZoom={false} enablePan={false} autoRotate autoRotateSpeed={0.5} />
</>
);
} catch (error) {
console.warn('Scene3D render error:', error);
return (
<>
<ambientLight intensity={0.5} />
<mesh>
<sphereGeometry args={[1, 32, 32]} />
<meshBasicMaterial color="#06b6d4" transparent opacity={0.3} />
</mesh>
</>
);
}
};
const Landing: React.FC = () => { const Landing: React.FC = () => {
const navigate = useNavigate(); return <MoneyflowLandingPage />;
const features = [
{
icon: <TrendingUp className="w-8 h-8" />,
title: "Portfolio Manager",
description: "Analyze and optimize your investment portfolio with AI-powered insights. Track stocks, mutual funds, and get rebalancing recommendations.",
status: "available"
},
{
icon: <DollarSign className="w-8 h-8" />,
title: "Budget Manager",
description: "Take control of your spending with intelligent budget tracking. Monitor expenses, set category limits, and get spending insights.",
status: "available"
},
{
icon: <BarChart3 className="w-8 h-8" />,
title: "Savings Booster",
description: "Maximize your savings potential with AI-driven cost optimization. Find duplicate subscriptions and money-saving opportunities.",
status: "available"
},
{
icon: <CheckCircle className="w-8 h-8" />,
title: "Credit Manager",
description: "Optimize your credit health with intelligent payment strategies. Monitor CIBIL score and get improvement recommendations.",
status: "coming-soon"
},
{
icon: <Shield className="w-8 h-8" />,
title: "Insurance Advisor",
description: "Find the perfect insurance coverage for your needs. Get personalized recommendations and policy comparisons.",
status: "coming-soon"
},
{
icon: <Target className="w-8 h-8" />,
title: "AI Jar (Goal Planning)",
description: "Achieve your financial dreams with intelligent goal planning. Set targets, track progress, and get step-by-step guidance.",
status: "coming-soon"
},
{
icon: <Brain className="w-8 h-8" />,
title: "Voice Bot Assistant",
description: "Access your financial information hands-free with voice commands. Get spoken insights and natural language queries.",
status: "coming-soon"
},
{
icon: <Zap className="w-8 h-8" />,
title: "Commitment Advisor",
description: "Make informed decisions about major financial commitments. Get timing recommendations and affordability analysis.",
status: "coming-soon"
}
];
const stats = [
{ value: "₹50L+", label: "Money Saved" },
{ value: "10K+", label: "Happy Users" },
{ value: "95%", label: "Success Rate" },
{ value: "24/7", label: "AI Support" }
];
return (
<div className="min-h-screen bg-gradient-to-br from-cyan-50 via-blue-50 to-cyan-100 overflow-hidden">
{/* Hero Section */}
<section className="relative min-h-screen flex items-center justify-center">
{/* 3D Background */}
<div className="absolute inset-0 z-0">
<Scene3DErrorBoundary
fallback={
<div className="absolute inset-0 bg-gradient-to-br from-cyan-100/50 via-blue-100/50 to-purple-100/50">
<div className="absolute inset-0 bg-[radial-gradient(circle_at_50%_50%,rgba(6,182,212,0.1)_0%,transparent_50%)]"></div>
</div>
}
>
<Canvas camera={{ position: [0, 0, 5], fov: 75 }} gl={{ antialias: true, alpha: true }}>
<Suspense fallback={
<mesh>
<sphereGeometry args={[0.5, 32, 32]} />
<meshBasicMaterial color="#06b6d4" transparent opacity={0.3} />
</mesh>
}>
<Scene3D />
</Suspense>
</Canvas>
</Scene3DErrorBoundary>
</div>
{/* Background decorations */}
<div className="absolute inset-0 overflow-hidden pointer-events-none">
<div className="absolute -top-40 -right-40 w-96 h-96 bg-gradient-to-br from-cyan-400/20 to-blue-500/20 rounded-full blur-3xl"></div>
<div className="absolute -bottom-40 -left-40 w-96 h-96 bg-gradient-to-tr from-blue-400/20 to-cyan-500/20 rounded-full blur-3xl"></div>
</div>
{/* Content */}
<div className="relative z-10 text-center max-w-4xl mx-auto px-4 lg:px-6">
<Badge className="mb-4 lg:mb-6 bg-white/20 border-white/30 text-primary backdrop-blur-sm text-sm">
<Star className="w-3 h-3 lg:w-4 lg:h-4 mr-2" />
India's #1 AI Financial Assistant
</Badge>
<h1 className="text-3xl sm:text-4xl md:text-6xl lg:text-7xl font-bold mb-4 lg:mb-6 bg-gradient-to-r from-cyan-600 via-blue-600 to-purple-600 bg-clip-text text-transparent leading-tight">
Your Money,
<br />
<span className="bg-gradient-to-r from-purple-600 to-pink-600 bg-clip-text text-transparent">
Powered by AI
</span>
</h1>
<p className="text-base sm:text-lg lg:text-xl xl:text-2xl text-muted-foreground mb-6 lg:mb-8 max-w-3xl mx-auto leading-relaxed">
Transform your financial future with intelligent insights, automated savings,
and personalized investment strategies designed for Indian investors.
</p>
<div className="flex flex-col sm:flex-row gap-3 lg:gap-4 justify-center items-center mb-8 lg:mb-12">
<Button
size="lg"
className="w-full sm:w-auto text-base lg:text-lg px-6 lg:px-8 py-4 lg:py-6 bg-gradient-to-r from-cyan-600 to-blue-600 hover:from-cyan-700 hover:to-blue-700 text-white shadow-lg hover:shadow-xl transition-all duration-300 transform hover:scale-105"
onClick={() => navigate('/app')}
>
Start Your Journey
<ArrowRight className="ml-2 w-4 h-4 lg:w-5 lg:h-5" />
</Button>
<Button
variant="outline"
size="lg"
className="w-full sm:w-auto text-base lg:text-lg px-6 lg:px-8 py-4 lg:py-6 bg-white/20 border-white/30 backdrop-blur-sm hover:bg-white/30 transition-all duration-300"
>
Watch Demo
</Button>
</div>
{/* Stats */}
<div className="grid grid-cols-2 lg:grid-cols-4 gap-4 lg:gap-6 max-w-2xl mx-auto">
{stats.map((stat, index) => (
<div key={index} className="text-center">
<div className="text-2xl lg:text-3xl font-bold text-primary mb-1 lg:mb-2">{stat.value}</div>
<div className="text-xs lg:text-sm text-muted-foreground">{stat.label}</div>
</div>
))}
</div>
</div>
</section>
{/* Features Section */}
<section className="py-12 lg:py-20 px-4 lg:px-6 relative z-10">
<div className="max-w-7xl mx-auto">
<div className="text-center mb-12 lg:mb-16">
<h2 className="text-2xl sm:text-3xl lg:text-4xl xl:text-5xl font-bold mb-4 lg:mb-6 bg-gradient-to-r from-cyan-600 to-blue-600 bg-clip-text text-transparent">
Complete Financial Management Suite
</h2>
<p className="text-base lg:text-xl text-muted-foreground max-w-3xl mx-auto mb-6 lg:mb-8">
Discover how AI can revolutionize your relationship with money
</p>
{/* Available Features Highlight */}
<div className="bg-gradient-to-r from-green-50 to-blue-50 rounded-2xl p-4 lg:p-6 mb-8 lg:mb-12 border border-green-200">
<div className="flex items-center justify-center mb-3 lg:mb-4">
<CheckCircle className="w-5 h-5 lg:w-6 lg:h-6 text-green-600 mr-2" />
<span className="text-base lg:text-lg font-semibold text-green-800">Now Available</span>
</div>
<p className="text-sm lg:text-base text-green-700">
<strong>Portfolio Manager, Budget Tracker & Savings Booster</strong> are live and ready to transform your finances!
</p>
</div>
</div>
<div className="grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 gap-6 lg:gap-8">
{features.map((feature, index) => (
<Card key={index} className="group hover:shadow-xl transition-all duration-300 transform hover:-translate-y-2 bg-white/80 backdrop-blur-sm border-white/20 relative">
<CardHeader className="p-4 lg:p-6">
<div className="flex items-center justify-between mb-4">
<div className={`w-12 h-12 lg:w-16 lg:h-16 rounded-xl ${
feature.status === 'available'
? 'bg-gradient-to-br from-cyan-400 to-blue-600'
: 'bg-gradient-to-br from-gray-400 to-gray-600'
} flex items-center justify-center text-white group-hover:scale-110 transition-transform duration-300`}>
<div className="scale-75 lg:scale-100">
{feature.icon}
</div>
</div>
<Badge
variant={feature.status === 'available' ? 'default' : 'secondary'}
className={feature.status === 'available'
? 'bg-green-100 text-green-700 border-green-200'
: 'bg-orange-100 text-orange-700 border-orange-200'
}
>
{feature.status === 'available' ? (
<>
<CheckCircle className="w-3 h-3 mr-1" />
Available
</>
) : (
<>
<Clock className="w-3 h-3 mr-1" />
Coming Soon
</>
)}
</Badge>
</div>
<CardTitle className="text-lg lg:text-xl mb-2">{feature.title}</CardTitle>
</CardHeader>
<CardContent className="p-4 lg:p-6 pt-0">
<CardDescription className="text-sm lg:text-base leading-relaxed">
{feature.description}
</CardDescription>
{feature.status === 'available' && (
<Button
variant="outline"
size="sm"
className="mt-4 w-full"
onClick={() => navigate('/app')}
>
Try Now
<ArrowRight className="w-4 h-4 ml-2" />
</Button>
)}
</CardContent>
</Card>
))}
</div>
</div>
</section>
{/* CTA Section */}
<section className="py-20 px-6 relative z-10">
<div className="max-w-4xl mx-auto text-center">
<Card className="bg-gradient-to-r from-cyan-600 to-blue-600 text-white border-none shadow-2xl">
<CardContent className="p-12">
<h3 className="text-4xl font-bold mb-6">
Start Managing Your Money Smarter Today
</h3>
<p className="text-xl mb-6 opacity-90">
Get instant access to Portfolio Management, Budget Tracking, and Savings Optimization
</p>
{/* Feature Pills */}
<div className="flex flex-wrap justify-center gap-3 mb-8">
<Badge className="bg-white/20 text-white border-white/30 px-4 py-2 text-sm">
<TrendingUp className="w-4 h-4 mr-2" />
Track Investments
</Badge>
<Badge className="bg-white/20 text-white border-white/30 px-4 py-2 text-sm">
<DollarSign className="w-4 h-4 mr-2" />
Monitor Budget
</Badge>
<Badge className="bg-white/20 text-white border-white/30 px-4 py-2 text-sm">
<BarChart3 className="w-4 h-4 mr-2" />
Boost Savings
</Badge>
</div>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<Button
size="lg"
variant="secondary"
className="text-lg px-8 py-6 bg-white text-primary hover:bg-gray-100"
onClick={() => navigate('/app')}
>
Start Free Trial
<ArrowRight className="ml-2 w-5 h-5" />
</Button>
</div>
<p className="text-sm opacity-75 mt-4">
No credit card required Full access to available features More coming soon
</p>
</CardContent>
</Card>
</div>
</section>
</div>
);
}; };
export default Landing; export default Landing;

View File

@@ -0,0 +1,10 @@
server {
listen 80;
server_name wealthwise.eventifyplus.com;
root /var/www/wealthwise.eventifyplus.com;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}