Spaces:
Running
Running
Add 3 files
Browse files- README.md +6 -4
- index.html +1060 -19
- prompts.txt +6 -0
README.md
CHANGED
@@ -1,10 +1,12 @@
|
|
1 |
---
|
2 |
-
title:
|
3 |
-
emoji:
|
4 |
colorFrom: purple
|
5 |
-
colorTo:
|
6 |
sdk: static
|
7 |
pinned: false
|
|
|
|
|
8 |
---
|
9 |
|
10 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
1 |
---
|
2 |
+
title: wealth-planner-v1
|
3 |
+
emoji: 🐳
|
4 |
colorFrom: purple
|
5 |
+
colorTo: red
|
6 |
sdk: static
|
7 |
pinned: false
|
8 |
+
tags:
|
9 |
+
- deepsite
|
10 |
---
|
11 |
|
12 |
+
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
index.html
CHANGED
@@ -1,19 +1,1060 @@
|
|
1 |
-
<!
|
2 |
-
<html>
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en">
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8">
|
5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6 |
+
<title>AI Wealth Management Planner</title>
|
7 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
8 |
+
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
9 |
+
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
|
10 |
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
11 |
+
<style>
|
12 |
+
@keyframes float {
|
13 |
+
0% { transform: translateY(0px); }
|
14 |
+
50% { transform: translateY(-10px); }
|
15 |
+
100% { transform: translateY(0px); }
|
16 |
+
}
|
17 |
+
.floating {
|
18 |
+
animation: float 3s ease-in-out infinite;
|
19 |
+
}
|
20 |
+
.fade-in {
|
21 |
+
animation: fadeIn 0.5s ease-in-out;
|
22 |
+
}
|
23 |
+
@keyframes fadeIn {
|
24 |
+
from { opacity: 0; transform: translateY(10px); }
|
25 |
+
to { opacity: 1; transform: translateY(0); }
|
26 |
+
}
|
27 |
+
.report-card {
|
28 |
+
transition: all 0.3s ease;
|
29 |
+
}
|
30 |
+
.report-card:hover {
|
31 |
+
transform: translateY(-5px);
|
32 |
+
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
|
33 |
+
}
|
34 |
+
.loading-dots:after {
|
35 |
+
content: '.';
|
36 |
+
animation: dots 1.5s steps(5, end) infinite;
|
37 |
+
}
|
38 |
+
@keyframes dots {
|
39 |
+
0%, 20% { content: '.'; }
|
40 |
+
40% { content: '..'; }
|
41 |
+
60% { content: '...'; }
|
42 |
+
80%, 100% { content: ''; }
|
43 |
+
}
|
44 |
+
.gradient-bg {
|
45 |
+
background: linear-gradient(135deg, #6b46c1 0%, #4299e1 50%, #38b2ac 100%);
|
46 |
+
}
|
47 |
+
.pulse {
|
48 |
+
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
49 |
+
}
|
50 |
+
@keyframes pulse {
|
51 |
+
0%, 100% { opacity: 1; }
|
52 |
+
50% { opacity: 0.5; }
|
53 |
+
}
|
54 |
+
.progress-bar {
|
55 |
+
height: 4px;
|
56 |
+
background: linear-gradient(90deg, #4f46e5 0%, #10b981 50%, #f59e0b 100%);
|
57 |
+
animation: progress 2s ease-in-out infinite;
|
58 |
+
background-size: 200% 100%;
|
59 |
+
}
|
60 |
+
@keyframes progress {
|
61 |
+
0% { background-position: 0% 50%; }
|
62 |
+
50% { background-position: 100% 50%; }
|
63 |
+
100% { background-position: 0% 50%; }
|
64 |
+
}
|
65 |
+
.chart-container {
|
66 |
+
position: relative;
|
67 |
+
height: 300px;
|
68 |
+
width: 100%;
|
69 |
+
}
|
70 |
+
.glow {
|
71 |
+
box-shadow: 0 0 20px rgba(99, 102, 241, 0.5);
|
72 |
+
}
|
73 |
+
.financial-freedom-card {
|
74 |
+
background: linear-gradient(135deg, #10b981 0%, #3b82f6 100%);
|
75 |
+
color: white;
|
76 |
+
}
|
77 |
+
.milestone-marker {
|
78 |
+
width: 12px;
|
79 |
+
height: 12px;
|
80 |
+
border-radius: 50%;
|
81 |
+
position: absolute;
|
82 |
+
top: -6px;
|
83 |
+
left: 50%;
|
84 |
+
transform: translateX(-50%);
|
85 |
+
}
|
86 |
+
.milestone-line {
|
87 |
+
position: absolute;
|
88 |
+
top: 0;
|
89 |
+
bottom: 0;
|
90 |
+
left: 50%;
|
91 |
+
width: 2px;
|
92 |
+
transform: translateX(-50%);
|
93 |
+
}
|
94 |
+
</style>
|
95 |
+
</head>
|
96 |
+
<body class="bg-gray-50 min-h-screen">
|
97 |
+
<div class="container mx-auto px-4 py-8">
|
98 |
+
<header class="text-center mb-12">
|
99 |
+
<h1 class="text-4xl font-bold text-transparent bg-clip-text bg-gradient-to-r from-indigo-600 to-blue-500 mb-2">AI Wealth Management Planner</h1>
|
100 |
+
<p class="text-lg text-gray-600">Get a personalized financial roadmap to achieve financial freedom</p>
|
101 |
+
</header>
|
102 |
+
|
103 |
+
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
104 |
+
<!-- Input Form -->
|
105 |
+
<div class="bg-white rounded-xl shadow-md p-6 lg:col-span-1 h-fit sticky top-8 glow">
|
106 |
+
<h2 class="text-2xl font-semibold text-gray-800 mb-6">Your Financial Profile</h2>
|
107 |
+
|
108 |
+
<form id="financialForm" class="space-y-4">
|
109 |
+
<div>
|
110 |
+
<label for="age" class="block text-sm font-medium text-gray-700 mb-1">Age</label>
|
111 |
+
<input type="number" id="age" min="18" max="100" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500" required>
|
112 |
+
</div>
|
113 |
+
|
114 |
+
<div>
|
115 |
+
<label for="income" class="block text-sm font-medium text-gray-700 mb-1">Annual Income ($)</label>
|
116 |
+
<input type="number" id="income" min="0" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500" required>
|
117 |
+
</div>
|
118 |
+
|
119 |
+
<div>
|
120 |
+
<label for="savings" class="block text-sm font-medium text-gray-700 mb-1">Current Savings ($)</label>
|
121 |
+
<input type="number" id="savings" min="0" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500" required>
|
122 |
+
</div>
|
123 |
+
|
124 |
+
<div>
|
125 |
+
<label for="debt" class="block text-sm font-medium text-gray-700 mb-1">Current Debt ($)</label>
|
126 |
+
<input type="number" id="debt" min="0" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500" value="0">
|
127 |
+
</div>
|
128 |
+
|
129 |
+
<div>
|
130 |
+
<label for="monthlySpending" class="block text-sm font-medium text-gray-700 mb-1">Monthly Spending ($)</label>
|
131 |
+
<input type="number" id="monthlySpending" min="0" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500" value="3000">
|
132 |
+
</div>
|
133 |
+
|
134 |
+
<div>
|
135 |
+
<label for="riskTolerance" class="block text-sm font-medium text-gray-700 mb-1">Risk Tolerance</label>
|
136 |
+
<select id="riskTolerance" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500">
|
137 |
+
<option value="conservative">Conservative</option>
|
138 |
+
<option value="moderate" selected>Moderate</option>
|
139 |
+
<option value="aggressive">Aggressive</option>
|
140 |
+
</select>
|
141 |
+
</div>
|
142 |
+
|
143 |
+
<div>
|
144 |
+
<label for="retirementAge" class="block text-sm font-medium text-gray-700 mb-1">Desired Retirement Age</label>
|
145 |
+
<input type="number" id="retirementAge" min="18" max="100" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500" value="65">
|
146 |
+
</div>
|
147 |
+
|
148 |
+
<div class="pt-2">
|
149 |
+
<button type="submit" id="generateBtn" class="w-full gradient-bg hover:opacity-90 text-white font-medium py-3 px-4 rounded-lg transition duration-200 flex items-center justify-center shadow-lg">
|
150 |
+
<span>Generate Wealth Plan</span>
|
151 |
+
<i class="fas fa-arrow-right ml-2"></i>
|
152 |
+
</button>
|
153 |
+
</div>
|
154 |
+
</form>
|
155 |
+
</div>
|
156 |
+
|
157 |
+
<!-- Results Section -->
|
158 |
+
<div class="bg-white rounded-xl shadow-md p-6 lg:col-span-2">
|
159 |
+
<div class="flex justify-between items-center mb-6">
|
160 |
+
<h2 class="text-2xl font-semibold text-gray-800">Your Wealth Management Plan</h2>
|
161 |
+
<button id="saveReportBtn" class="bg-indigo-100 hover:bg-indigo-200 text-indigo-800 font-medium py-2 px-4 rounded-lg transition duration-200 hidden">
|
162 |
+
<i class="fas fa-save mr-2"></i>Save Report
|
163 |
+
</button>
|
164 |
+
</div>
|
165 |
+
|
166 |
+
<div id="resultsContainer">
|
167 |
+
<div class="bg-blue-50 border-l-4 border-blue-500 p-4 rounded-lg">
|
168 |
+
<div class="flex">
|
169 |
+
<div class="flex-shrink-0">
|
170 |
+
<i class="fas fa-info-circle text-blue-500 text-xl"></i>
|
171 |
+
</div>
|
172 |
+
<div class="ml-3">
|
173 |
+
<p class="text-sm text-blue-700">
|
174 |
+
Enter your financial details and click "Generate Wealth Plan" to get personalized recommendations.
|
175 |
+
</p>
|
176 |
+
</div>
|
177 |
+
</div>
|
178 |
+
</div>
|
179 |
+
</div>
|
180 |
+
|
181 |
+
<!-- Loading Animation -->
|
182 |
+
<div id="loadingContainer" class="hidden mt-8">
|
183 |
+
<div class="text-center">
|
184 |
+
<div class="w-24 h-24 mx-auto mb-6 relative">
|
185 |
+
<div class="w-full h-full rounded-full bg-indigo-100 flex items-center justify-center floating">
|
186 |
+
<i class="fas fa-piggy-bank text-indigo-600 text-4xl"></i>
|
187 |
+
</div>
|
188 |
+
<div class="absolute inset-0 rounded-full border-4 border-indigo-200 border-t-indigo-600 animate-spin"></div>
|
189 |
+
</div>
|
190 |
+
<h3 class="text-xl font-semibold text-gray-800 mb-2">Crunching your numbers</h3>
|
191 |
+
<p class="text-gray-600 mb-4">We're analyzing your financial profile and building a personalized roadmap...</p>
|
192 |
+
<div class="w-full bg-gray-200 rounded-full h-2.5 max-w-md mx-auto">
|
193 |
+
<div class="progress-bar h-2.5 rounded-full"></div>
|
194 |
+
</div>
|
195 |
+
<div class="mt-6 grid grid-cols-3 gap-4 max-w-md mx-auto">
|
196 |
+
<div class="bg-purple-50 p-3 rounded-lg pulse">
|
197 |
+
<i class="fas fa-chart-line text-purple-600 text-xl mb-2"></i>
|
198 |
+
<p class="text-xs text-purple-800">Projecting growth</p>
|
199 |
+
</div>
|
200 |
+
<div class="bg-green-50 p-3 rounded-lg pulse" style="animation-delay: 0.2s">
|
201 |
+
<i class="fas fa-money-bill-wave text-green-600 text-xl mb-2"></i>
|
202 |
+
<p class="text-xs text-green-800">Optimizing savings</p>
|
203 |
+
</div>
|
204 |
+
<div class="bg-blue-50 p-3 rounded-lg pulse" style="animation-delay: 0.4s">
|
205 |
+
<i class="fas fa-calendar-check text-blue-600 text-xl mb-2"></i>
|
206 |
+
<p class="text-xs text-blue-800">Planning milestones</p>
|
207 |
+
</div>
|
208 |
+
</div>
|
209 |
+
</div>
|
210 |
+
</div>
|
211 |
+
|
212 |
+
<!-- Saved Reports Section -->
|
213 |
+
<div id="savedReportsContainer" class="mt-12">
|
214 |
+
<div class="flex justify-between items-center mb-4">
|
215 |
+
<h3 class="text-xl font-semibold text-gray-800">Saved Reports</h3>
|
216 |
+
<button id="clearReportsBtn" class="text-red-500 hover:text-red-700 text-sm font-medium">
|
217 |
+
<i class="fas fa-trash-alt mr-1"></i>Clear All
|
218 |
+
</button>
|
219 |
+
</div>
|
220 |
+
|
221 |
+
<div id="savedReportsList" class="grid grid-cols-1 gap-4">
|
222 |
+
<!-- Reports will be added here dynamically -->
|
223 |
+
</div>
|
224 |
+
</div>
|
225 |
+
</div>
|
226 |
+
</div>
|
227 |
+
</div>
|
228 |
+
|
229 |
+
<script>
|
230 |
+
document.addEventListener('DOMContentLoaded', function() {
|
231 |
+
const financialForm = document.getElementById('financialForm');
|
232 |
+
const generateBtn = document.getElementById('generateBtn');
|
233 |
+
const saveReportBtn = document.getElementById('saveReportBtn');
|
234 |
+
const clearReportsBtn = document.getElementById('clearReportsBtn');
|
235 |
+
const resultsContainer = document.getElementById('resultsContainer');
|
236 |
+
const loadingContainer = document.getElementById('loadingContainer');
|
237 |
+
const savedReportsList = document.getElementById('savedReportsList');
|
238 |
+
|
239 |
+
let currentReport = null;
|
240 |
+
let charts = [];
|
241 |
+
|
242 |
+
// Load saved reports from localStorage
|
243 |
+
loadSavedReports();
|
244 |
+
|
245 |
+
financialForm.addEventListener('submit', async function(e) {
|
246 |
+
e.preventDefault();
|
247 |
+
|
248 |
+
const age = parseInt(document.getElementById('age').value);
|
249 |
+
const income = parseInt(document.getElementById('income').value);
|
250 |
+
const savings = parseInt(document.getElementById('savings').value);
|
251 |
+
const debt = parseInt(document.getElementById('debt').value);
|
252 |
+
const monthlySpending = parseInt(document.getElementById('monthlySpending').value);
|
253 |
+
const riskTolerance = document.getElementById('riskTolerance').value;
|
254 |
+
const retirementAge = parseInt(document.getElementById('retirementAge').value);
|
255 |
+
|
256 |
+
// Show loading state
|
257 |
+
generateBtn.disabled = true;
|
258 |
+
generateBtn.innerHTML = '<span>Generating</span><span class="loading-dots"></span>';
|
259 |
+
resultsContainer.classList.add('hidden');
|
260 |
+
loadingContainer.classList.remove('hidden');
|
261 |
+
|
262 |
+
try {
|
263 |
+
// Generate AI response
|
264 |
+
const aiResponse = await generateWealthPlan(age, income, savings, debt, monthlySpending, riskTolerance, retirementAge);
|
265 |
+
|
266 |
+
// Calculate financial freedom projections
|
267 |
+
const projections = calculateProjections(age, income, savings, debt, monthlySpending, riskTolerance, retirementAge);
|
268 |
+
|
269 |
+
// Display results
|
270 |
+
displayResults(aiResponse, projections, { age, income, savings, debt, monthlySpending, riskTolerance, retirementAge });
|
271 |
+
|
272 |
+
// Store current report for potential saving
|
273 |
+
currentReport = {
|
274 |
+
data: { age, income, savings, debt, monthlySpending, riskTolerance, retirementAge },
|
275 |
+
plan: aiResponse,
|
276 |
+
projections: projections,
|
277 |
+
timestamp: new Date().toISOString()
|
278 |
+
};
|
279 |
+
|
280 |
+
// Show save button
|
281 |
+
saveReportBtn.classList.remove('hidden');
|
282 |
+
} catch (error) {
|
283 |
+
console.error('Error:', error);
|
284 |
+
resultsContainer.innerHTML = `
|
285 |
+
<div class="bg-red-50 border-l-4 border-red-500 p-4 rounded-lg fade-in">
|
286 |
+
<div class="flex">
|
287 |
+
<div class="flex-shrink-0">
|
288 |
+
<i class="fas fa-exclamation-circle text-red-500 text-xl"></i>
|
289 |
+
</div>
|
290 |
+
<div class="ml-3">
|
291 |
+
<p class="text-sm text-red-700">
|
292 |
+
An error occurred while generating your wealth plan. Please try again later.
|
293 |
+
</p>
|
294 |
+
</div>
|
295 |
+
</div>
|
296 |
+
</div>
|
297 |
+
`;
|
298 |
+
} finally {
|
299 |
+
// Reset button
|
300 |
+
generateBtn.disabled = false;
|
301 |
+
generateBtn.innerHTML = '<span>Generate Wealth Plan</span><i class="fas fa-arrow-right ml-2"></i>';
|
302 |
+
loadingContainer.classList.add('hidden');
|
303 |
+
resultsContainer.classList.remove('hidden');
|
304 |
+
}
|
305 |
+
});
|
306 |
+
|
307 |
+
saveReportBtn.addEventListener('click', function() {
|
308 |
+
if (currentReport) {
|
309 |
+
saveReport(currentReport);
|
310 |
+
currentReport = null;
|
311 |
+
saveReportBtn.classList.add('hidden');
|
312 |
+
|
313 |
+
// Show success message
|
314 |
+
const successMsg = document.createElement('div');
|
315 |
+
successMsg.className = 'bg-green-50 border-l-4 border-green-500 p-4 rounded-lg fade-in mb-4';
|
316 |
+
successMsg.innerHTML = `
|
317 |
+
<div class="flex">
|
318 |
+
<div class="flex-shrink-0">
|
319 |
+
<i class="fas fa-check-circle text-green-500 text-xl"></i>
|
320 |
+
</div>
|
321 |
+
<div class="ml-3">
|
322 |
+
<p class="text-sm text-green-700">
|
323 |
+
Report saved successfully!
|
324 |
+
</p>
|
325 |
+
</div>
|
326 |
+
</div>
|
327 |
+
`;
|
328 |
+
resultsContainer.insertBefore(successMsg, resultsContainer.firstChild);
|
329 |
+
|
330 |
+
// Remove message after 3 seconds
|
331 |
+
setTimeout(() => {
|
332 |
+
successMsg.classList.add('opacity-0', 'transition-opacity', 'duration-500');
|
333 |
+
setTimeout(() => successMsg.remove(), 500);
|
334 |
+
}, 3000);
|
335 |
+
}
|
336 |
+
});
|
337 |
+
|
338 |
+
clearReportsBtn.addEventListener('click', function() {
|
339 |
+
if (confirm('Are you sure you want to clear all saved reports?')) {
|
340 |
+
localStorage.removeItem('wealthReports');
|
341 |
+
savedReportsList.innerHTML = '';
|
342 |
+
}
|
343 |
+
});
|
344 |
+
|
345 |
+
async function generateWealthPlan(age, income, savings, debt, monthlySpending, riskTolerance, retirementAge) {
|
346 |
+
const yearsToRetirement = retirementAge - age;
|
347 |
+
const netWorth = savings - debt;
|
348 |
+
const annualSpending = monthlySpending * 12;
|
349 |
+
const financialFreedomNumber = annualSpending * 25; // 4% rule
|
350 |
+
|
351 |
+
// Simulate some processing time for a better UX
|
352 |
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
353 |
+
|
354 |
+
// Construct the prompt for the AI
|
355 |
+
const prompt = `Create a comprehensive wealth management plan for a ${age}-year-old individual with the following financial profile:
|
356 |
+
- Annual Income: $${income.toLocaleString()}
|
357 |
+
- Current Savings: $${savings.toLocaleString()}
|
358 |
+
- Current Debt: $${debt.toLocaleString()}
|
359 |
+
- Net Worth: $${netWorth.toLocaleString()}
|
360 |
+
- Monthly Spending: $${monthlySpending.toLocaleString()}
|
361 |
+
- Annual Spending: $${annualSpending.toLocaleString()}
|
362 |
+
- Financial Freedom Target: $${financialFreedomNumber.toLocaleString()}
|
363 |
+
- Risk Tolerance: ${riskTolerance}
|
364 |
+
- Years Until Desired Retirement: ${yearsToRetirement}
|
365 |
+
|
366 |
+
Please provide detailed recommendations covering:
|
367 |
+
1. Emergency fund target
|
368 |
+
2. Debt repayment strategy
|
369 |
+
3. Retirement savings goals and investment allocation
|
370 |
+
4. Tax optimization strategies
|
371 |
+
5. Insurance needs assessment
|
372 |
+
6. Projected path to financial freedom
|
373 |
+
7. Investment strategy based on risk tolerance
|
374 |
+
8. Any other relevant financial planning considerations
|
375 |
+
|
376 |
+
Structure the response with clear headings and bullet points for easy reading. Tailor the advice to the specified risk tolerance and time horizon. Include specific numbers and percentages where applicable.`;
|
377 |
+
|
378 |
+
// Call the DeepSeek API
|
379 |
+
const response = await fetch('https://api.deepseek.com/v1/chat/completions', {
|
380 |
+
method: 'POST',
|
381 |
+
headers: {
|
382 |
+
'Content-Type': 'application/json',
|
383 |
+
'Authorization': 'Bearer sk-0cce68e321854d11b01ee9227147a12d'
|
384 |
+
},
|
385 |
+
body: JSON.stringify({
|
386 |
+
model: 'deepseek-chat',
|
387 |
+
messages: [
|
388 |
+
{
|
389 |
+
role: 'user',
|
390 |
+
content: prompt
|
391 |
+
}
|
392 |
+
],
|
393 |
+
temperature: 0.7,
|
394 |
+
max_tokens: 1500
|
395 |
+
})
|
396 |
+
});
|
397 |
+
|
398 |
+
const data = await response.json();
|
399 |
+
|
400 |
+
if (!response.ok) {
|
401 |
+
throw new Error(data.error?.message || 'Failed to generate wealth plan');
|
402 |
+
}
|
403 |
+
|
404 |
+
return data.choices[0].message.content;
|
405 |
+
}
|
406 |
+
|
407 |
+
function calculateProjections(age, income, savings, debt, monthlySpending, riskTolerance, retirementAge) {
|
408 |
+
const yearsToRetirement = retirementAge - age;
|
409 |
+
const annualSpending = monthlySpending * 12;
|
410 |
+
const financialFreedomNumber = annualSpending * 25; // 4% rule
|
411 |
+
|
412 |
+
// Determine expected returns based on risk tolerance
|
413 |
+
let expectedReturn;
|
414 |
+
switch(riskTolerance) {
|
415 |
+
case 'conservative':
|
416 |
+
expectedReturn = 0.05; // 5%
|
417 |
+
break;
|
418 |
+
case 'moderate':
|
419 |
+
expectedReturn = 0.07; // 7%
|
420 |
+
break;
|
421 |
+
case 'aggressive':
|
422 |
+
expectedReturn = 0.09; // 9%
|
423 |
+
break;
|
424 |
+
default:
|
425 |
+
expectedReturn = 0.07;
|
426 |
+
}
|
427 |
+
|
428 |
+
// Calculate savings rate (simplified)
|
429 |
+
const savingsRate = 0.2; // Assume 20% savings rate for this example
|
430 |
+
const annualSavings = income * savingsRate;
|
431 |
+
|
432 |
+
// Project growth over years
|
433 |
+
const projections = [];
|
434 |
+
let currentNetWorth = savings - debt;
|
435 |
+
|
436 |
+
for (let i = 0; i <= yearsToRetirement; i++) {
|
437 |
+
const currentAge = age + i;
|
438 |
+
const investmentGrowth = currentNetWorth * expectedReturn;
|
439 |
+
currentNetWorth += annualSavings + investmentGrowth;
|
440 |
+
|
441 |
+
projections.push({
|
442 |
+
age: currentAge,
|
443 |
+
year: new Date().getFullYear() + i,
|
444 |
+
netWorth: Math.round(currentNetWorth),
|
445 |
+
savings: Math.round(annualSavings),
|
446 |
+
investmentGrowth: Math.round(investmentGrowth)
|
447 |
+
});
|
448 |
+
|
449 |
+
// Check if we've reached financial freedom
|
450 |
+
if (currentNetWorth >= financialFreedomNumber) {
|
451 |
+
break;
|
452 |
+
}
|
453 |
+
}
|
454 |
+
|
455 |
+
// Calculate financial freedom age
|
456 |
+
let financialFreedomAge = age;
|
457 |
+
for (let i = 0; i < projections.length; i++) {
|
458 |
+
if (projections[i].netWorth >= financialFreedomNumber) {
|
459 |
+
financialFreedomAge = projections[i].age;
|
460 |
+
break;
|
461 |
+
}
|
462 |
+
}
|
463 |
+
|
464 |
+
return {
|
465 |
+
projections: projections,
|
466 |
+
financialFreedomAge: financialFreedomAge,
|
467 |
+
financialFreedomNumber: financialFreedomNumber,
|
468 |
+
annualSpending: annualSpending,
|
469 |
+
expectedReturn: expectedReturn,
|
470 |
+
savingsRate: savingsRate
|
471 |
+
};
|
472 |
+
}
|
473 |
+
|
474 |
+
function displayResults(aiResponse, projections, userData) {
|
475 |
+
// Destroy any existing charts
|
476 |
+
charts.forEach(chart => chart.destroy());
|
477 |
+
charts = [];
|
478 |
+
|
479 |
+
const yearsToRetirement = userData.retirementAge - userData.age;
|
480 |
+
const netWorth = userData.savings - userData.debt;
|
481 |
+
const annualSpending = userData.monthlySpending * 12;
|
482 |
+
|
483 |
+
// Prepare data for charts
|
484 |
+
const projectionYears = projections.projections.map(p => p.year);
|
485 |
+
const projectionNetWorth = projections.projections.map(p => p.netWorth);
|
486 |
+
const projectionSavings = projections.projections.map(p => p.savings);
|
487 |
+
const projectionGrowth = projections.projections.map(p => p.investmentGrowth);
|
488 |
+
|
489 |
+
// Create allocation chart data
|
490 |
+
const allocationData = {
|
491 |
+
conservative: [60, 30, 10],
|
492 |
+
moderate: [40, 50, 10],
|
493 |
+
aggressive: [20, 60, 20]
|
494 |
+
};
|
495 |
+
|
496 |
+
resultsContainer.innerHTML = `
|
497 |
+
<div class="space-y-8 fade-in">
|
498 |
+
<!-- Financial Snapshot -->
|
499 |
+
<div class="bg-white rounded-lg shadow-sm p-6 border border-gray-100 glow">
|
500 |
+
<h3 class="text-xl font-semibold text-gray-800 mb-4">Financial Snapshot</h3>
|
501 |
+
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-4">
|
502 |
+
<div class="bg-gradient-to-br from-indigo-100 to-blue-100 p-4 rounded-lg">
|
503 |
+
<p class="text-sm text-indigo-600 font-medium">Age</p>
|
504 |
+
<p class="text-2xl font-bold text-indigo-800">${userData.age}</p>
|
505 |
+
</div>
|
506 |
+
<div class="bg-gradient-to-br from-green-100 to-teal-100 p-4 rounded-lg">
|
507 |
+
<p class="text-sm text-green-600 font-medium">Annual Income</p>
|
508 |
+
<p class="text-2xl font-bold text-green-800">$${userData.income.toLocaleString()}</p>
|
509 |
+
</div>
|
510 |
+
<div class="bg-gradient-to-br from-purple-100 to-pink-100 p-4 rounded-lg">
|
511 |
+
<p class="text-sm text-purple-600 font-medium">Net Worth</p>
|
512 |
+
<p class="text-2xl font-bold text-purple-800">$${netWorth.toLocaleString()}</p>
|
513 |
+
</div>
|
514 |
+
</div>
|
515 |
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
516 |
+
<div class="bg-gradient-to-br from-amber-100 to-yellow-100 p-4 rounded-lg">
|
517 |
+
<p class="text-sm text-amber-600 font-medium">Years to Retirement</p>
|
518 |
+
<p class="text-2xl font-bold text-amber-800">${yearsToRetirement}</p>
|
519 |
+
</div>
|
520 |
+
<div class="bg-gradient-to-br from-red-100 to-orange-100 p-4 rounded-lg">
|
521 |
+
<p class="text-sm text-red-600 font-medium">Risk Tolerance</p>
|
522 |
+
<p class="text-2xl font-bold text-red-800 capitalize">${userData.riskTolerance}</p>
|
523 |
+
</div>
|
524 |
+
</div>
|
525 |
+
</div>
|
526 |
+
|
527 |
+
<!-- Financial Freedom Projection -->
|
528 |
+
<div class="financial-freedom-card rounded-lg shadow-sm p-6 text-white">
|
529 |
+
<div class="flex flex-col md:flex-row justify-between items-start md:items-center">
|
530 |
+
<div>
|
531 |
+
<h3 class="text-xl font-semibold mb-2">Financial Freedom Projection</h3>
|
532 |
+
<p class="text-lg font-medium">$${projections.financialFreedomNumber.toLocaleString()} needed</p>
|
533 |
+
<p class="text-sm opacity-90">Based on annual spending of $${annualSpending.toLocaleString()}</p>
|
534 |
+
</div>
|
535 |
+
<div class="mt-4 md:mt-0 text-center">
|
536 |
+
<div class="text-4xl font-bold">${projections.financialFreedomAge}</div>
|
537 |
+
<div class="text-sm">Years old</div>
|
538 |
+
</div>
|
539 |
+
</div>
|
540 |
+
|
541 |
+
<div class="mt-6 chart-container">
|
542 |
+
<canvas id="netWorthChart"></canvas>
|
543 |
+
</div>
|
544 |
+
|
545 |
+
<div class="mt-4 grid grid-cols-3 gap-2 text-center">
|
546 |
+
<div class="bg-white bg-opacity-20 p-2 rounded">
|
547 |
+
<p class="text-xs opacity-80">Expected Return</p>
|
548 |
+
<p class="font-bold">${(projections.expectedReturn * 100).toFixed(1)}%</p>
|
549 |
+
</div>
|
550 |
+
<div class="bg-white bg-opacity-20 p-2 rounded">
|
551 |
+
<p class="text-xs opacity-80">Savings Rate</p>
|
552 |
+
<p class="font-bold">${(projections.savingsRate * 100).toFixed(0)}%</p>
|
553 |
+
</div>
|
554 |
+
<div class="bg-white bg-opacity-20 p-2 rounded">
|
555 |
+
<p class="text-xs opacity-80">Years to FI</p>
|
556 |
+
<p class="font-bold">${projections.financialFreedomAge - userData.age}</p>
|
557 |
+
</div>
|
558 |
+
</div>
|
559 |
+
</div>
|
560 |
+
|
561 |
+
<!-- Net Worth Growth Chart -->
|
562 |
+
<div class="bg-white rounded-lg shadow-sm p-6 border border-gray-100">
|
563 |
+
<h3 class="text-xl font-semibold text-gray-800 mb-4">Net Worth Growth Projection</h3>
|
564 |
+
<div class="chart-container">
|
565 |
+
<canvas id="growthChart"></canvas>
|
566 |
+
</div>
|
567 |
+
</div>
|
568 |
+
|
569 |
+
<!-- Investment Allocation -->
|
570 |
+
<div class="bg-white rounded-lg shadow-sm p-6 border border-gray-100">
|
571 |
+
<h3 class="text-xl font-semibold text-gray-800 mb-4">Recommended Investment Allocation</h3>
|
572 |
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
573 |
+
<div class="chart-container">
|
574 |
+
<canvas id="allocationChart"></canvas>
|
575 |
+
</div>
|
576 |
+
<div class="flex flex-col justify-center">
|
577 |
+
<div class="space-y-3">
|
578 |
+
<div class="flex items-center">
|
579 |
+
<div class="w-4 h-4 rounded-full bg-blue-500 mr-2"></div>
|
580 |
+
<span class="text-sm">Stocks</span>
|
581 |
+
</div>
|
582 |
+
<div class="flex items-center">
|
583 |
+
<div class="w-4 h-4 rounded-full bg-green-500 mr-2"></div>
|
584 |
+
<span class="text-sm">Bonds</span>
|
585 |
+
</div>
|
586 |
+
<div class="flex items-center">
|
587 |
+
<div class="w-4 h-4 rounded-full bg-yellow-500 mr-2"></div>
|
588 |
+
<span class="text-sm">Alternative Investments</span>
|
589 |
+
</div>
|
590 |
+
</div>
|
591 |
+
<div class="mt-6 bg-${userData.riskTolerance === 'conservative' ? 'blue' : userData.riskTolerance === 'moderate' ? 'purple' : 'red'}-50 p-4 rounded-lg">
|
592 |
+
<p class="text-sm text-${userData.riskTolerance === 'conservative' ? 'blue' : userData.riskTolerance === 'moderate' ? 'purple' : 'red'}-800">
|
593 |
+
<span class="font-medium">${userData.riskTolerance.charAt(0).toUpperCase() + userData.riskTolerance.slice(1)} Portfolio:</span>
|
594 |
+
${userData.riskTolerance === 'conservative' ?
|
595 |
+
'Lower risk with stable returns' :
|
596 |
+
userData.riskTolerance === 'moderate' ?
|
597 |
+
'Balanced approach for growth and stability' :
|
598 |
+
'Higher growth potential with increased volatility'}
|
599 |
+
</p>
|
600 |
+
</div>
|
601 |
+
</div>
|
602 |
+
</div>
|
603 |
+
</div>
|
604 |
+
|
605 |
+
<!-- Milestones Timeline -->
|
606 |
+
<div class="bg-white rounded-lg shadow-sm p-6 border border-gray-100">
|
607 |
+
<h3 class="text-xl font-semibold text-gray-800 mb-6">Financial Milestones</h3>
|
608 |
+
<div class="relative">
|
609 |
+
<!-- Timeline line -->
|
610 |
+
<div class="milestone-line bg-gray-200"></div>
|
611 |
+
|
612 |
+
<!-- Milestones -->
|
613 |
+
${createMilestones(userData.age, projections.financialFreedomAge, userData.retirementAge, netWorth, projections.financialFreedomNumber)}
|
614 |
+
</div>
|
615 |
+
</div>
|
616 |
+
|
617 |
+
<!-- AI Recommendations -->
|
618 |
+
<div class="bg-white rounded-lg shadow-sm p-6 border border-gray-100">
|
619 |
+
<h3 class="text-xl font-semibold text-gray-800 mb-4">Your Personalized Wealth Management Plan</h3>
|
620 |
+
<div class="prose max-w-none text-gray-700">
|
621 |
+
${formatAIResponse(aiResponse)}
|
622 |
+
</div>
|
623 |
+
</div>
|
624 |
+
</div>
|
625 |
+
`;
|
626 |
+
|
627 |
+
// Create charts after DOM is rendered
|
628 |
+
setTimeout(() => {
|
629 |
+
createNetWorthChart(projectionYears, projectionNetWorth, projections.financialFreedomNumber);
|
630 |
+
createGrowthChart(projectionYears, projectionNetWorth, projectionSavings, projectionGrowth);
|
631 |
+
createAllocationChart(allocationData[userData.riskTolerance]);
|
632 |
+
}, 100);
|
633 |
+
}
|
634 |
+
|
635 |
+
function createMilestones(currentAge, fiAge, retirementAge, currentNetWorth, fiNumber) {
|
636 |
+
const milestones = [
|
637 |
+
{
|
638 |
+
age: currentAge,
|
639 |
+
title: "Current Status",
|
640 |
+
description: `Net Worth: $${currentNetWorth.toLocaleString()}`,
|
641 |
+
color: "bg-indigo-500",
|
642 |
+
position: "left"
|
643 |
+
},
|
644 |
+
{
|
645 |
+
age: fiAge,
|
646 |
+
title: "Financial Freedom",
|
647 |
+
description: `Target: $${fiNumber.toLocaleString()}`,
|
648 |
+
color: "bg-green-500",
|
649 |
+
position: "right"
|
650 |
+
},
|
651 |
+
{
|
652 |
+
age: retirementAge,
|
653 |
+
title: "Retirement Age",
|
654 |
+
description: "Traditional retirement",
|
655 |
+
color: "bg-blue-500",
|
656 |
+
position: "left"
|
657 |
+
}
|
658 |
+
];
|
659 |
+
|
660 |
+
// Add a milestone at 50% of FI number if it's between current age and FI age
|
661 |
+
const halfWayAge = Math.floor(currentAge + (fiAge - currentAge) * 0.5);
|
662 |
+
if (halfWayAge > currentAge && halfWayAge < fiAge) {
|
663 |
+
milestones.splice(1, 0, {
|
664 |
+
age: halfWayAge,
|
665 |
+
title: "Halfway Point",
|
666 |
+
description: "50% to financial freedom",
|
667 |
+
color: "bg-yellow-500",
|
668 |
+
position: "right"
|
669 |
+
});
|
670 |
+
}
|
671 |
+
|
672 |
+
// Sort by age
|
673 |
+
milestones.sort((a, b) => a.age - b.age);
|
674 |
+
|
675 |
+
let html = '';
|
676 |
+
milestones.forEach(milestone => {
|
677 |
+
const isCurrent = milestone.age === currentAge;
|
678 |
+
const isFI = milestone.age === fiAge;
|
679 |
+
|
680 |
+
html += `
|
681 |
+
<div class="relative mb-8 ${milestone.position === 'left' ? 'pr-8 md:pr-16' : 'pl-8 md:pl-16'}">
|
682 |
+
<div class="milestone-marker ${milestone.color}"></div>
|
683 |
+
<div class="bg-white p-4 rounded-lg shadow-sm border border-gray-200 ${isFI ? 'financial-freedom-card text-white' : ''}">
|
684 |
+
<h4 class="font-semibold ${isFI ? '' : 'text-gray-800'}">${milestone.title}</h4>
|
685 |
+
<p class="text-sm ${isFI ? 'opacity-90' : 'text-gray-600'}">Age ${milestone.age} • ${milestone.description}</p>
|
686 |
+
${isCurrent ? '<div class="mt-2"><span class="inline-block px-2 py-1 text-xs font-medium bg-indigo-100 text-indigo-800 rounded-full">Current</span></div>' : ''}
|
687 |
+
${isFI ? '<div class="mt-2"><span class="inline-block px-2 py-1 text-xs font-medium bg-white bg-opacity-20 rounded-full">Goal</span></div>' : ''}
|
688 |
+
</div>
|
689 |
+
</div>
|
690 |
+
`;
|
691 |
+
});
|
692 |
+
|
693 |
+
return html;
|
694 |
+
}
|
695 |
+
|
696 |
+
function createNetWorthChart(years, netWorth, fiNumber) {
|
697 |
+
const ctx = document.getElementById('netWorthChart').getContext('2d');
|
698 |
+
const fiIndex = netWorth.findIndex(nw => nw >= fiNumber);
|
699 |
+
const fiYear = fiIndex !== -1 ? years[fiIndex] : null;
|
700 |
+
|
701 |
+
const chart = new Chart(ctx, {
|
702 |
+
type: 'line',
|
703 |
+
data: {
|
704 |
+
labels: years,
|
705 |
+
datasets: [
|
706 |
+
{
|
707 |
+
label: 'Projected Net Worth',
|
708 |
+
data: netWorth,
|
709 |
+
borderColor: 'rgba(255, 255, 255, 0.8)',
|
710 |
+
backgroundColor: 'rgba(255, 255, 255, 0.1)',
|
711 |
+
borderWidth: 2,
|
712 |
+
fill: true,
|
713 |
+
tension: 0.4
|
714 |
+
},
|
715 |
+
{
|
716 |
+
label: 'Financial Freedom Target',
|
717 |
+
data: Array(years.length).fill(fiNumber),
|
718 |
+
borderColor: 'rgba(255, 255, 255, 0.5)',
|
719 |
+
borderWidth: 1,
|
720 |
+
borderDash: [5, 5],
|
721 |
+
fill: false
|
722 |
+
}
|
723 |
+
]
|
724 |
+
},
|
725 |
+
options: {
|
726 |
+
responsive: true,
|
727 |
+
maintainAspectRatio: false,
|
728 |
+
plugins: {
|
729 |
+
legend: {
|
730 |
+
labels: {
|
731 |
+
color: 'white',
|
732 |
+
font: {
|
733 |
+
size: 12
|
734 |
+
}
|
735 |
+
}
|
736 |
+
},
|
737 |
+
tooltip: {
|
738 |
+
callbacks: {
|
739 |
+
label: function(context) {
|
740 |
+
let label = context.dataset.label || '';
|
741 |
+
if (label) {
|
742 |
+
label += ': ';
|
743 |
+
}
|
744 |
+
if (context.parsed.y !== null) {
|
745 |
+
label += '$' + context.parsed.y.toLocaleString();
|
746 |
+
}
|
747 |
+
return label;
|
748 |
+
}
|
749 |
+
}
|
750 |
+
}
|
751 |
+
},
|
752 |
+
scales: {
|
753 |
+
x: {
|
754 |
+
grid: {
|
755 |
+
color: 'rgba(255, 255, 255, 0.1)'
|
756 |
+
},
|
757 |
+
ticks: {
|
758 |
+
color: 'rgba(255, 255, 255, 0.8)'
|
759 |
+
}
|
760 |
+
},
|
761 |
+
y: {
|
762 |
+
grid: {
|
763 |
+
color: 'rgba(255, 255, 255, 0.1)'
|
764 |
+
},
|
765 |
+
ticks: {
|
766 |
+
color: 'rgba(255, 255, 255, 0.8)',
|
767 |
+
callback: function(value) {
|
768 |
+
return '$' + (value / 1000) + 'k';
|
769 |
+
}
|
770 |
+
}
|
771 |
+
}
|
772 |
+
},
|
773 |
+
annotation: fiYear ? {
|
774 |
+
annotations: {
|
775 |
+
line1: {
|
776 |
+
type: 'line',
|
777 |
+
xMin: fiYear,
|
778 |
+
xMax: fiYear,
|
779 |
+
borderColor: 'rgba(255, 255, 255, 0.7)',
|
780 |
+
borderWidth: 1,
|
781 |
+
label: {
|
782 |
+
content: 'FI Reached',
|
783 |
+
enabled: true,
|
784 |
+
position: 'top',
|
785 |
+
backgroundColor: 'rgba(16, 185, 129, 0.7)',
|
786 |
+
color: 'white',
|
787 |
+
font: {
|
788 |
+
weight: 'bold'
|
789 |
+
}
|
790 |
+
}
|
791 |
+
}
|
792 |
+
}
|
793 |
+
} : {}
|
794 |
+
}
|
795 |
+
});
|
796 |
+
|
797 |
+
charts.push(chart);
|
798 |
+
}
|
799 |
+
|
800 |
+
function createGrowthChart(years, netWorth, savings, growth) {
|
801 |
+
const ctx = document.getElementById('growthChart').getContext('2d');
|
802 |
+
|
803 |
+
const chart = new Chart(ctx, {
|
804 |
+
type: 'bar',
|
805 |
+
data: {
|
806 |
+
labels: years,
|
807 |
+
datasets: [
|
808 |
+
{
|
809 |
+
label: 'New Savings',
|
810 |
+
data: savings,
|
811 |
+
backgroundColor: 'rgba(59, 130, 246, 0.7)',
|
812 |
+
stack: 'stack_1'
|
813 |
+
},
|
814 |
+
{
|
815 |
+
label: 'Investment Growth',
|
816 |
+
data: growth,
|
817 |
+
backgroundColor: 'rgba(16, 185, 129, 0.7)',
|
818 |
+
stack: 'stack_1'
|
819 |
+
},
|
820 |
+
{
|
821 |
+
label: 'Net Worth',
|
822 |
+
data: netWorth,
|
823 |
+
type: 'line',
|
824 |
+
borderColor: 'rgba(139, 92, 246, 1)',
|
825 |
+
backgroundColor: 'rgba(0, 0, 0, 0)',
|
826 |
+
borderWidth: 3,
|
827 |
+
pointBackgroundColor: 'rgba(139, 92, 246, 1)',
|
828 |
+
pointRadius: 4
|
829 |
+
}
|
830 |
+
]
|
831 |
+
},
|
832 |
+
options: {
|
833 |
+
responsive: true,
|
834 |
+
maintainAspectRatio: false,
|
835 |
+
plugins: {
|
836 |
+
legend: {
|
837 |
+
position: 'top',
|
838 |
+
labels: {
|
839 |
+
font: {
|
840 |
+
size: 12
|
841 |
+
}
|
842 |
+
}
|
843 |
+
},
|
844 |
+
tooltip: {
|
845 |
+
callbacks: {
|
846 |
+
label: function(context) {
|
847 |
+
let label = context.dataset.label || '';
|
848 |
+
if (label) {
|
849 |
+
label += ': ';
|
850 |
+
}
|
851 |
+
if (context.parsed.y !== null) {
|
852 |
+
label += '$' + context.parsed.y.toLocaleString();
|
853 |
+
}
|
854 |
+
return label;
|
855 |
+
}
|
856 |
+
}
|
857 |
+
}
|
858 |
+
},
|
859 |
+
scales: {
|
860 |
+
x: {
|
861 |
+
stacked: true,
|
862 |
+
grid: {
|
863 |
+
display: false
|
864 |
+
}
|
865 |
+
},
|
866 |
+
y: {
|
867 |
+
stacked: false,
|
868 |
+
ticks: {
|
869 |
+
callback: function(value) {
|
870 |
+
return '$' + (value / 1000) + 'k';
|
871 |
+
}
|
872 |
+
}
|
873 |
+
}
|
874 |
+
}
|
875 |
+
}
|
876 |
+
});
|
877 |
+
|
878 |
+
charts.push(chart);
|
879 |
+
}
|
880 |
+
|
881 |
+
function createAllocationChart(allocationData) {
|
882 |
+
const ctx = document.getElementById('allocationChart').getContext('2d');
|
883 |
+
|
884 |
+
const chart = new Chart(ctx, {
|
885 |
+
type: 'doughnut',
|
886 |
+
data: {
|
887 |
+
labels: ['Stocks', 'Bonds', 'Alternatives'],
|
888 |
+
datasets: [{
|
889 |
+
data: allocationData,
|
890 |
+
backgroundColor: [
|
891 |
+
'rgba(59, 130, 246, 0.8)',
|
892 |
+
'rgba(16, 185, 129, 0.8)',
|
893 |
+
'rgba(234, 179, 8, 0.8)'
|
894 |
+
],
|
895 |
+
borderColor: [
|
896 |
+
'rgba(59, 130, 246, 1)',
|
897 |
+
'rgba(16, 185, 129, 1)',
|
898 |
+
'rgba(234, 179, 8, 1)'
|
899 |
+
],
|
900 |
+
borderWidth: 1
|
901 |
+
}]
|
902 |
+
},
|
903 |
+
options: {
|
904 |
+
responsive: true,
|
905 |
+
maintainAspectRatio: false,
|
906 |
+
plugins: {
|
907 |
+
legend: {
|
908 |
+
position: 'right',
|
909 |
+
labels: {
|
910 |
+
boxWidth: 12,
|
911 |
+
padding: 20,
|
912 |
+
font: {
|
913 |
+
size: 12
|
914 |
+
}
|
915 |
+
}
|
916 |
+
},
|
917 |
+
datalabels: {
|
918 |
+
formatter: (value) => {
|
919 |
+
return value + '%';
|
920 |
+
},
|
921 |
+
color: '#fff',
|
922 |
+
font: {
|
923 |
+
weight: 'bold'
|
924 |
+
}
|
925 |
+
},
|
926 |
+
tooltip: {
|
927 |
+
callbacks: {
|
928 |
+
label: function(context) {
|
929 |
+
return context.label + ': ' + context.raw + '%';
|
930 |
+
}
|
931 |
+
}
|
932 |
+
}
|
933 |
+
},
|
934 |
+
cutout: '65%'
|
935 |
+
},
|
936 |
+
plugins: [ChartDataLabels]
|
937 |
+
});
|
938 |
+
|
939 |
+
charts.push(chart);
|
940 |
+
}
|
941 |
+
|
942 |
+
function formatAIResponse(text) {
|
943 |
+
// Convert markdown-like formatting to HTML
|
944 |
+
let html = text.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');
|
945 |
+
html = html.replace(/\*(.*?)\*/g, '<em>$1</em>');
|
946 |
+
html = html.replace(/^### (.*$)/gm, '<h3 class="text-lg font-semibold text-gray-800 mt-6 mb-3">$1</h3>');
|
947 |
+
html = html.replace(/^## (.*$)/gm, '<h2 class="text-xl font-semibold text-gray-800 mt-8 mb-4">$1</h2>');
|
948 |
+
html = html.replace(/^# (.*$)/gm, '<h1 class="text-2xl font-semibold text-gray-800 mt-10 mb-6">$1</h1>');
|
949 |
+
html = html.replace(/^- (.*$)/gm, '<li class="mb-2">$1</li>');
|
950 |
+
html = html.replace(/\n/g, '<br>');
|
951 |
+
|
952 |
+
// Wrap lists in ul tags
|
953 |
+
html = html.replace(/(<li class="mb-2">.*?<\/li>)+/g, function(match) {
|
954 |
+
return '<ul class="list-disc pl-5 space-y-1 my-3">' + match + '</ul>';
|
955 |
+
});
|
956 |
+
|
957 |
+
// Highlight numbers and percentages
|
958 |
+
html = html.replace(/(\$[\d,]+|\d+%)/g, '<span class="font-bold text-indigo-600">$1</span>');
|
959 |
+
|
960 |
+
return html;
|
961 |
+
}
|
962 |
+
|
963 |
+
function saveReport(report) {
|
964 |
+
// Get existing reports from localStorage
|
965 |
+
const savedReports = JSON.parse(localStorage.getItem('wealthReports')) || [];
|
966 |
+
|
967 |
+
// Add new report
|
968 |
+
savedReports.push(report);
|
969 |
+
|
970 |
+
// Save back to localStorage
|
971 |
+
localStorage.setItem('wealthReports', JSON.stringify(savedReports));
|
972 |
+
|
973 |
+
// Reload the saved reports list
|
974 |
+
loadSavedReports();
|
975 |
+
}
|
976 |
+
|
977 |
+
function loadSavedReports() {
|
978 |
+
const savedReports = JSON.parse(localStorage.getItem('wealthReports')) || [];
|
979 |
+
|
980 |
+
if (savedReports.length === 0) {
|
981 |
+
savedReportsList.innerHTML = `
|
982 |
+
<div class="bg-gray-50 rounded-lg p-4 text-center text-gray-500">
|
983 |
+
<i class="fas fa-folder-open text-2xl mb-2"></i>
|
984 |
+
<p>No saved reports yet</p>
|
985 |
+
</div>
|
986 |
+
`;
|
987 |
+
return;
|
988 |
+
}
|
989 |
+
|
990 |
+
savedReportsList.innerHTML = '';
|
991 |
+
|
992 |
+
// Display reports in reverse chronological order
|
993 |
+
savedReports.reverse().forEach((report, index) => {
|
994 |
+
const reportDate = new Date(report.timestamp);
|
995 |
+
const formattedDate = reportDate.toLocaleDateString('en-US', {
|
996 |
+
year: 'numeric',
|
997 |
+
month: 'short',
|
998 |
+
day: 'numeric',
|
999 |
+
hour: '2-digit',
|
1000 |
+
minute: '2-digit'
|
1001 |
+
});
|
1002 |
+
|
1003 |
+
const fiAge = report.projections?.financialFreedomAge || 'N/A';
|
1004 |
+
const netWorth = report.data.savings - report.data.debt;
|
1005 |
+
|
1006 |
+
const reportCard = document.createElement('div');
|
1007 |
+
reportCard.className = 'report-card bg-white rounded-lg shadow-sm p-4 border border-gray-100 hover:border-indigo-200 cursor-pointer';
|
1008 |
+
reportCard.innerHTML = `
|
1009 |
+
<div class="flex justify-between items-start">
|
1010 |
+
<div>
|
1011 |
+
<h4 class="font-medium text-gray-800">Wealth Plan - ${formattedDate}</h4>
|
1012 |
+
<p class="text-sm text-gray-500 mt-1">
|
1013 |
+
Age ${report.data.age}, Income: $${report.data.income.toLocaleString()}, Net Worth: $${netWorth.toLocaleString()}
|
1014 |
+
</p>
|
1015 |
+
<div class="mt-2 flex items-center">
|
1016 |
+
<span class="inline-block px-2 py-1 text-xs font-medium ${fiAge <= report.data.retirementAge ? 'bg-green-100 text-green-800' : 'bg-amber-100 text-amber-800'} rounded-full">
|
1017 |
+
FI Age: ${fiAge}
|
1018 |
+
</span>
|
1019 |
+
</div>
|
1020 |
+
</div>
|
1021 |
+
<button class="text-gray-400 hover:text-red-500 delete-report" data-index="${savedReports.length - 1 - index}">
|
1022 |
+
<i class="fas fa-times"></i>
|
1023 |
+
</button>
|
1024 |
+
</div>
|
1025 |
+
`;
|
1026 |
+
|
1027 |
+
reportCard.addEventListener('click', () => {
|
1028 |
+
displayResults(report.plan, report.projections, report.data);
|
1029 |
+
saveReportBtn.classList.add('hidden');
|
1030 |
+
window.scrollTo({ top: 0, behavior: 'smooth' });
|
1031 |
+
});
|
1032 |
+
|
1033 |
+
savedReportsList.appendChild(reportCard);
|
1034 |
+
});
|
1035 |
+
|
1036 |
+
// Add event listeners to delete buttons
|
1037 |
+
document.querySelectorAll('.delete-report').forEach(button => {
|
1038 |
+
button.addEventListener('click', function(e) {
|
1039 |
+
e.stopPropagation();
|
1040 |
+
const index = parseInt(this.getAttribute('data-index'));
|
1041 |
+
deleteReport(index);
|
1042 |
+
});
|
1043 |
+
});
|
1044 |
+
}
|
1045 |
+
|
1046 |
+
function deleteReport(index) {
|
1047 |
+
const savedReports = JSON.parse(localStorage.getItem('wealthReports')) || [];
|
1048 |
+
|
1049 |
+
if (index >= 0 && index < savedReports.length) {
|
1050 |
+
if (confirm('Are you sure you want to delete this report?')) {
|
1051 |
+
savedReports.splice(index, 1);
|
1052 |
+
localStorage.setItem('wealthReports', JSON.stringify(savedReports));
|
1053 |
+
loadSavedReports();
|
1054 |
+
}
|
1055 |
+
}
|
1056 |
+
}
|
1057 |
+
});
|
1058 |
+
</script>
|
1059 |
+
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=JayStormX8/wealth-planner-v1" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
|
1060 |
+
</html>
|
prompts.txt
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Create a fun gamefied comprehensive app that you can generate process and systems flows in
|
2 |
+
Great but have it so they easily connect to eachother and have it so I can add times between them that the process takes since this is for process improvement
|
3 |
+
Create an epic modern 30 day content calendar app, ai powered using deepseek api key is (sk-0cce68e321854d11b01ee9227147a12d) and allow realestate agents to easily create 30 day content calendar, primary ones are IG/FB, tiktok, linkedin
|
4 |
+
Great but make it completely interactive where everything works and you can easily generate for certain days then add and move them
|
5 |
+
Create a comprehensive wealth management plan generator based off someones age, savings and income and give them a report based on what they input. Make it ai based as well and actually work, here is the deepseek api key:sk-0cce68e321854d11b01ee9227147a12d
|
6 |
+
Great, make the report thats generated in a really colorful way with lots of charts and see how much youll have at financial freedom age where your investment will cover the things you want to spend on, make it super creative and also the loading time way more interactive while the report data is generating and populating so people don't feel like they are waiting long
|