jjmandog commited on
Commit
661165a
·
verified ·
1 Parent(s): d77defb

Remove all buttons except for settings. Then add a button opening the tullio token system with the account you made for this app - Follow Up Deployment

Browse files
Files changed (3) hide show
  1. README.md +7 -5
  2. index.html +1671 -19
  3. prompts.txt +6 -0
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Jshehrb
3
- emoji: 🐨
4
- colorFrom: yellow
5
- colorTo: blue
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: jshehrb
3
+ emoji: 🐳
4
+ colorFrom: pink
5
+ colorTo: gray
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,1671 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 Call Manager</title>
7
+ <script src="https://cdn.tailwindcss.com/3.4.0"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css">
9
+ <script src="https://sdk.vercel.app/external_api.js"></script> <!-- updated Jitsi URL -->
10
+ <script src="https://cdn.apple-mapkit.com/mk/5.x/mapkit.js"></script>
11
+ <!-- Added Pusher for real-time chat -->
12
+ <script src="https://js.pusher.com/8.2.0/pusher.min.js"></script>
13
+ <style>
14
+ @keyframes pulse-ring {
15
+ 0% { transform: scale(0.33); }
16
+ 80%, 100% { opacity: 0; }
17
+ }
18
+ @keyframes pulse-dot {
19
+ 0% { transform: scale(0.8); }
20
+ 50% { transform: scale(1); }
21
+ 100% { transform: scale(0.8); }
22
+ }
23
+ /* Custom scrollbar */
24
+ .custom-scrollbar::-webkit-scrollbar {
25
+ width: 6px;
26
+ }
27
+ .custom-scrollbar::-webkit-scrollbar-track {
28
+ background: rgba(156, 163, 175, 0.1);
29
+ }
30
+ .custom-scrollbar::-webkit-scrollbar-thumb {
31
+ background: rgba(99, 102, 241, 0.5);
32
+ border-radius: 3px;
33
+ }
34
+ /* Call animation */
35
+ .call-animation {
36
+ position: relative;
37
+ width: 50px;
38
+ height: 50px;
39
+ }
40
+ .call-animation:before {
41
+ content: '';
42
+ position: absolute;
43
+ top: 0;
44
+ left: 0;
45
+ width: 100%;
46
+ height: 100%;
47
+ background-color: rgba(16, 185, 129, 0.5);
48
+ border-radius: 50%;
49
+ animation: pulse-ring 1.5s cubic-bezier(0.215, 0.61, 0.355, 1) infinite;
50
+ }
51
+ .call-animation:after {
52
+ content: '';
53
+ position: absolute;
54
+ top: 0;
55
+ left: 0;
56
+ width: 100%;
57
+ height: 100%;
58
+ background-color: #10B981;
59
+ border-radius: 50%;
60
+ transform: scale(0.8);
61
+ animation: pulse-dot 1.5s cubic-bezier(0.455, 0.03, 0.515, 0.955) -0.4s infinite;
62
+ }
63
+ </style>
64
+ </head>
65
+ <body class="bg-gray-100 min-h-screen font-sans">
66
+ <div class="container mx-auto px-4 py-8 max-w-md">
67
+ <!-- Header -->
68
+ <header class="flex justify-between items-center mb-8">
69
+ <h1 class="text-2xl font-bold text-indigo-700">AI Call Manager</h1>
70
+ <div class="flex space-x-2">
71
+ <button id="settingsBtn" class="p-2 rounded-full bg-gray-100 hover:bg-gray-200 transition" title="Settings">
72
+ <i class="fas fa-cog text-gray-600"></i>
73
+ </button>
74
+ <button id="tullioBtn" class="p-2 rounded-full bg-green-100 hover:bg-green-200 transition" title="Tullio Token System">
75
+ <i class="fas fa-coins text-green-600"></i>
76
+ </button>
77
+ </div>
78
+ </header>
79
+
80
+ <!-- Main Dashboard -->
81
+ <div class="bg-white rounded-xl shadow-lg overflow-hidden mb-6">
82
+ <div class="p-6">
83
+ <div class="flex items-center mb-6">
84
+ <div class="call-animation mr-4"></div>
85
+ <div>
86
+ <h2 class="text-lg font-semibold text-gray-800">Call Management</h2>
87
+ <p class="text-sm text-gray-500">Active for: <span class="font-medium phone-number-display">(562) 228-9429</span></p>
88
+ </div>
89
+ </div>
90
+
91
+ <!-- Call Management Section -->
92
+ <div class="space-y-4">
93
+ <div>
94
+ <label class="block text-sm font-medium text-gray-700 mb-1">Answer Calls After</label>
95
+ <select id="callDelay" class="w-full py-2 px-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500">
96
+ <option value="15">15 seconds</option>
97
+ <option value="30" selected>30 seconds</option>
98
+ <option value="45">45 seconds</option>
99
+ <option value="60">1 minute</option>
100
+ </select>
101
+ </div>
102
+
103
+ <div>
104
+ <label class="flex items-center space-x-3">
105
+ <input type="checkbox" id="enableCallAI" class="rounded h-5 w-5 text-indigo-600 focus:ring-indigo-500" checked>
106
+ <span class="text-sm font-medium text-gray-700">Enable Call AI Assistant</span>
107
+ </label>
108
+ <p class="mt-1 text-xs text-gray-500">AI will answer calls when you're unavailable</p>
109
+ </div>
110
+
111
+ <div id="callSettings" class="pl-8">
112
+ <div class="mt-3">
113
+ <label class="block text-sm font-medium text-gray-700 mb-1">AI Voice</label>
114
+ <select class="w-full py-2 px-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500">
115
+ <option>American Female (Emma)</option>
116
+ <option>American Male (Brian)</option>
117
+ <option>British Female (Amy)</option>
118
+ </select>
119
+ </div>
120
+
121
+ <div class="mt-3">
122
+ <label class="block text-sm font-medium text-gray-700 mb-1">Default Message</label>
123
+ <textarea id="callGreeting" rows="2" class="w-full py-2 px-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500" placeholder="Hello, I'm unable to take your call right now. Please leave a message or send a text and I'll get back to you soon."></textarea>
124
+ </div>
125
+ </div>
126
+ </div>
127
+ </div>
128
+ </div>
129
+
130
+ <!-- Make a Call Section -->
131
+ <div class="bg-white rounded-xl shadow-lg overflow-hidden mb-6">
132
+ <div class="p-6">
133
+ <div class="flex items-center mb-6">
134
+ <div class="w-12 h-12 flex items-center justify-center bg-blue-100 rounded-full mr-4">
135
+ <i class="fas fa-phone text-blue-600 text-xl"></i>
136
+ </div>
137
+ <div>
138
+ <h2 class="text-lg font-semibold text-gray-800">Make a Call</h2>
139
+ <p class="text-sm text-gray-500">Train AI with interactive calls</p>
140
+ </div>
141
+ </div>
142
+
143
+ <div class="space-y-4">
144
+ <div>
145
+ <label class="block text-sm font-medium text-gray-700 mb-1">Phone Number to Call</label>
146
+ <input type="tel" id="callNumber" class="w-full py-2 px-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder="e.g. (562) 228-9429" value="15622289429">
147
+ </div>
148
+
149
+ <div>
150
+ <label class="block text-sm font-medium text-gray-700 mb-1">Call Purpose</label>
151
+ <select id="callPurpose" class="w-full py-2 px-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
152
+ <option value="training">AI Training Session</option>
153
+ <option value="outgoing">Regular Outgoing Call</option>
154
+ </select>
155
+ </div>
156
+
157
+ <div id="trainingOptions" class="pl-4 space-y-3 hidden">
158
+ <label class="flex items-center space-x-3">
159
+ <input type="checkbox" id="enableCallTraining" class="rounded h-4 w-4 text-blue-600 focus:ring-blue-500" checked>
160
+ <span class="text-sm font-medium text-gray-700">Enable Interactive Training</span>
161
+ </label>
162
+ <div>
163
+ <label class="block text-sm font-medium text-gray-700 mb-1">Training Mode</label>
164
+ <select id="callTrainingMode" class="w-full py-2 px-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm">
165
+ <option value="qa">Q&A Training</option>
166
+ <option value="conversation">Conversation Practice</option>
167
+ <option value="scenario">Scenario Simulation</option>
168
+ </select>
169
+ </div>
170
+ </div>
171
+
172
+ <button id="startCallBtn" class="w-full py-3 px-4 bg-blue-600 hover:bg-blue-700 text-white rounded-lg transition flex items-center justify-center space-x-2">
173
+ <i class="fas fa-phone"></i>
174
+ <span>Start Call</span>
175
+ </button>
176
+ </div>
177
+ </div>
178
+ </div>
179
+
180
+ <!-- Text AI Section -->
181
+ <div class="bg-white rounded-xl shadow-lg overflow-hidden mb-6">
182
+ <div class="p-6">
183
+ <div class="flex items-center mb-6">
184
+ <div class="w-12 h-12 flex items-center justify-center bg-purple-100 rounded-full mr-4">
185
+ <i class="fas fa-comment-alt text-purple-600 text-xl"></i>
186
+ </div>
187
+ <div>
188
+ <h2 class="text-lg font-semibold text-gray-800">Text AI Assistant</h2>
189
+ <p class="text-sm text-gray-500">Smart responses & automated replies</p>
190
+ </div>
191
+ </div>
192
+
193
+ <div class="space-y-4">
194
+ <div>
195
+ <label class="flex items-center space-x-3">
196
+ <input type="checkbox" id="enableTextAI" class="rounded h-5 w-5 text-purple-600 focus:ring-purple-500" checked>
197
+ <span class="text-sm font-medium text-gray-700">Enable Text AI Assistant</span>
198
+ </label>
199
+ <p class="mt-1 text-xs text-gray-500">AI will respond to unanswered texts automatically</p>
200
+ </div>
201
+
202
+ <div id="textSettings" class="pl-8 space-y-4">
203
+ <div>
204
+ <label class="block text-sm font-medium text-gray-700 mb-1">Response Style</label>
205
+ <select id="responseStyle" class="w-full py-2 px-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500">
206
+ <option value="professional">Professional</option>
207
+ <option value="friendly" selected>Friendly</option>
208
+ <option value="concise">Concise</option>
209
+ </select>
210
+ </div>
211
+
212
+ <div>
213
+ <label class="block text-sm font-medium text-gray-700 mb-1">Auto-response Delay</label>
214
+ <select id="textDelay" class="w-full py-2 px-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500">
215
+ <option value="1">1 hour</option>
216
+ <option value="2" selected>2 hours</option>
217
+ <option value="4">4 hours</option>
218
+ <option value="6">6 hours</option>
219
+ <option value="12">12 hours</option>
220
+ </select>
221
+ </div>
222
+
223
+ <div class="pt-2">
224
+ <button id="trainAIbtn" class="w-full py-2 px-4 bg-purple-600 hover:bg-purple-700 text-white rounded-lg transition flex items-center justify-center space-x-2">
225
+ <i class="fas fa-brain"></i>
226
+ <span>Train Text AI</span>
227
+ </button>
228
+ </div>
229
+ </div>
230
+ </div>
231
+ </div>
232
+ </div>
233
+
234
+ <!-- Stats Section -->
235
+ <div class="bg-white rounded-xl shadow-lg overflow-hidden mb-6">
236
+ <div class="p-6">
237
+ <h2 class="text-lg font-semibold text-gray-800 mb-4">Usage Statistics</h2>
238
+ <div class="grid grid-cols-2 gap-4">
239
+ <div class="bg-indigo-50 p-3 rounded-lg">
240
+ <p class="text-xs text-indigo-600 font-medium">Calls Managed</p>
241
+ <p class="text-2xl font-bold text-indigo-700" id="callStatsCount">128</p>
242
+ </div>
243
+ <div class="bg-purple-50 p-3 rounded-lg">
244
+ <p class="text-xs text-purple-600 font-medium">Texts Responded</p>
245
+ <p class="text-2xl font-bold text-purple-700" id="textStatsCount">342</p>
246
+ </div>
247
+ <div class="bg-green-50 p-3 rounded-lg">
248
+ <p class="text-xs text-green-600 font-medium">AI Confidence</p>
249
+ <p class="text-2xl font-bold text-green-700">89%</p>
250
+ </div>
251
+ <div class="bg-yellow-50 p-3 rounded-lg">
252
+ <p class="text-xs text-yellow-600 font-medium">Training Cycles</p>
253
+ <p class="text-2xl font-bold text-yellow-700">24</p>
254
+ </div>
255
+ </div>
256
+ </div>
257
+ </div>
258
+
259
+ <!-- Call Log Preview -->
260
+ <div class="bg-white rounded-xl shadow-lg overflow-hidden">
261
+ <div class="p-6">
262
+ <div class="flex justify-between items-center mb-4">
263
+ <h2 class="text-lg font-semibold text-gray-800">Recent Activity</h2>
264
+ <button class="text-xs text-indigo-600 hover:text-indigo-800">View All</button>
265
+ </div>
266
+ <div class="space-y-3 max-h-60 overflow-y-auto custom-scrollbar">
267
+ <div class="flex items-start py-2 border-b border-gray-100">
268
+ <div class="flex-shrink-0 h-10 w-10 rounded-full bg-red-100 flex items-center justify-center mr-3">
269
+ <i class="fas fa-phone-alt text-red-500"></i>
270
+ </div>
271
+ <div class="flex-1">
272
+ <p class="text-sm font-medium text-gray-800">Missed Call</p>
273
+ <p class="text-xs text-gray-500">From: (562) 555-0134</p>
274
+ <p class="text-xs text-gray-500">14 min ago - AI answered after 30s</p>
275
+ </div>
276
+ </div>
277
+ <div class="flex items-start py-2 border-b border-gray-100">
278
+ <div class="flex-shrink-0 h-10 w-10 rounded-full bg-green-100 flex items-center justify-center mr-3">
279
+ <i class="fas fa-sms text-green-500"></i>
280
+ </div>
281
+ <div class="flex-1">
282
+ <p class="text-sm font-medium text-gray-800">Text Response</p>
283
+ <p class="text-xs text-gray-500">To: (562) 555-0198</p>
284
+ <p class="text-xs text-gray-500">1 hour ago - AI confidence: 92%</p>
285
+ </div>
286
+ </div>
287
+ <div class="flex items-start py-2 border-b border-gray-100">
288
+ <div class="flex-shrink-0 h-10 w-10 rounded-full bg-blue-100 flex items-center justify-center mr-3">
289
+ <i class="fas fa-phone-alt text-blue-500"></i>
290
+ </div>
291
+ <div class="flex-1">
292
+ <p class="text-sm font-medium text-gray-800">AI Call</p>
293
+ <p class="text-xs text-gray-500">With: (562) 555-0163 (2m 43s)</p>
294
+ <p class="text-xs text-gray-500">3 hours ago - Scheduled follow-up</p>
295
+ </div>
296
+ </div>
297
+ </div>
298
+ </div>
299
+ </div>
300
+ </div>
301
+
302
+ <!-- Container for Jitsi meetings (hidden by default) -->
303
+ <div id="jitsi-container" style="display: none;"></div>
304
+
305
+ <!-- Training Modal -->
306
+ <div id="trainingModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4 hidden">
307
+ <div class="bg-white rounded-xl shadow-xl w-full max-w-md max-h-screen overflow-y-auto">
308
+ <div class="p-6">
309
+ <div class="flex justify-between items-center mb-4">
310
+ <h3 class="text-lg font-semibold text-gray-900">Train Your Text AI</h3>
311
+ <button id="closeTraining" class="text-gray-500 hover:text-gray-700">
312
+ <i class="fas fa-times"></i>
313
+ </button>
314
+ </div>
315
+
316
+ <div class="space-y-4">
317
+ <div class="p-4 bg-gray-50 rounded-lg">
318
+ <p class="text-sm text-gray-700 mb-2">AI Knowledge Level: <span class="font-medium">Intermediate</span></p>
319
+ <div class="w-full bg-gray-200 rounded-full h-2.5">
320
+ <div class="bg-purple-600 h-2.5 rounded-full" style="width: 65%"></div>
321
+ </div>
322
+ </div>
323
+
324
+ <div>
325
+ <p class="text-sm font-medium text-gray-700 mb-2">Training Mode</p>
326
+ <div class="grid grid-cols-2 gap-2">
327
+ <button class="trainingModeBtn py-2 px-3 border border-gray-300 rounded-lg text-sm font-medium bg-white hover:bg-gray-50" data-mode="qa">Q&A Training</button>
328
+ <button class="trainingModeBtn py-2 px-3 border border-gray-300 rounded-lg text-sm font-medium bg-white hover:bg-gray-50" data-mode="examples">Teach with Examples</button>
329
+ <button class="trainingModeBtn py-2 px-3 border border-gray-300 rounded-lg text-sm font-medium bg-white hover:bg-gray-50" data-mode="keywords">Keyword Responses</button>
330
+ <button class="trainingModeBtn py-2 px-3 border border-gray-300 rounded-lg text-sm font-medium bg-white hover:bg-gray-50" data-mode="prefs">Style Preferences</button>
331
+ </div>
332
+ </div>
333
+
334
+ <!-- Q&A Training Section -->
335
+ <div id="qaTraining" class="trainingSection hidden">
336
+ <div class="space-y-4">
337
+ <div>
338
+ <label class="block text-sm font-medium text-gray-700 mb-1">Question to Teach</label>
339
+ <input type="text" class="w-full py-2 px-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500 text-sm" placeholder="E.g. What are your business hours?">
340
+ </div>
341
+ <div>
342
+ <label class="block text-sm font-medium text-gray-700 mb-1">Preferred Response</label>
343
+ <textarea class="w-full py-2 px-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500 text-sm" rows="3" placeholder="Our business hours are Monday to Friday, 9am to 5pm PST."></textarea>
344
+ </div>
345
+ <button class="w-full py-2 bg-purple-600 hover:bg-purple-700 text-white rounded-lg text-sm">
346
+ Add to AI Knowledge
347
+ </button>
348
+ </div>
349
+ </div>
350
+
351
+ <!-- Examples Training Section -->
352
+ <div id="examplesTraining" class="trainingSection hidden">
353
+ <div class="space-y-4">
354
+ <div>
355
+ <label class="block text-sm font-medium text-gray-700 mb-1">Example Conversation</label>
356
+ <textarea class="w-full py-2 px-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500 text-sm" rows="5" placeholder="Client: When can I expect my order to arrive?
357
+ You: Your order will ship within 24 hours and typically arrives in 2-3 business days. We'll send tracking information once it's on the way."></textarea>
358
+ </div>
359
+ <button class="w-full py-2 bg-purple-600 hover:bg-purple-700 text-white rounded-lg text-sm">
360
+ Analyze for Patterns
361
+ </button>
362
+ </div>
363
+ </div>
364
+
365
+ <!-- Keywords Training Section -->
366
+ <div id="keywordsTraining" class="trainingSection hidden">
367
+ <div class="space-y-4">
368
+ <div>
369
+ <label class="block text-sm font-medium text-gray-700 mb-1">Trigger Word/Phrase</label>
370
+ <input type="text" class="w-full py-2 px-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500 text-sm" placeholder="E.g. refund, return policy">
371
+ </div>
372
+ <div>
373
+ <label class="block text-sm font-medium text-gray-700 mb-1">Response for This Keyword</label>
374
+ <textarea class="w-full py-2 px-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500 text-sm" rows="3" placeholder="Our return policy allows for returns within 30 days of purchase..."></textarea>
375
+ </div>
376
+ <button class="w-full py-2 bg-purple-600 hover:bg-purple-700 text-white rounded-lg text-sm">
377
+ Add Keyword Response
378
+ </button>
379
+ </div>
380
+ </div>
381
+
382
+ <!-- Preferences Training Section -->
383
+ <div id="prefsTraining" class="trainingSection hidden">
384
+ <div class="space-y-4">
385
+ <div>
386
+ <label class="block text-sm font-medium text-gray-700 mb-1">Communication Style</label>
387
+ <select class="w-full py-2 px-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500 text-sm">
388
+ <option>Professional</option>
389
+ <option selected>Friendly</option>
390
+ <option>Concise</option>
391
+ <option>Detailed</option>
392
+ </select>
393
+ </div>
394
+ <div>
395
+ <label class="block text-sm font-medium text-gray-700 mb-1">Common Phrases You Use</label>
396
+ <textarea class="w-full py-2 px-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500 text-sm" rows="3" placeholder="E.g. Thanks for reaching out!, Happy to help!, Let me check that for you..."></textarea>
397
+ </div>
398
+ <button class="w-full py-2 bg-purple-600 hover:bg-purple-700 text-white rounded-lg text-sm">
399
+ Update Preferences
400
+ </button>
401
+ </div>
402
+ </div>
403
+
404
+ <div class="pt-4 border-t border-gray-200">
405
+ <h4 class="text-sm font-medium text-gray-900 mb-2">AI Test Area</h4>
406
+ <div class="mb-2">
407
+ <input type="text" class="w-full py-2 px-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500 text-sm" placeholder="Test message for AI to respond to" id="testMessage">
408
+ </div>
409
+ <button onclick="testAIResponse()" class="w-full py-2 bg-gray-200 hover:bg-gray-300 rounded-lg text-sm mb-4">
410
+ Test AI Response
411
+ </button>
412
+ <div id="aiResponse" class="hidden bg-gray-50 p-3 rounded-lg">
413
+ <p class="text-sm text-gray-800">This is where the AI's response would appear based on its current training.</p>
414
+ </div>
415
+ </div>
416
+ </div>
417
+ </div>
418
+ </div>
419
+ </div>
420
+
421
+ <!-- Settings Modal -->
422
+ <div id="settingsModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4 hidden">
423
+ <div class="bg-white rounded-xl shadow-xl w-full max-w-md max-h-screen overflow-y-auto">
424
+ <div class="p-6">
425
+ <div class="flex justify-between items-center mb-4">
426
+ <h3 class="text-lg font-semibold text-gray-900">Settings</h3>
427
+ <button id="closeSettings" class="text-gray-500 hover:text-gray-700">
428
+ <i class="fas fa-times"></i>
429
+ </button>
430
+ </div>
431
+
432
+ <div class="space-y-4">
433
+ <div>
434
+ <h4 class="text-sm font-medium text-gray-900 mb-3">Twilio Integration</h4>
435
+ <div class="pl-2 space-y-3 mb-4">
436
+ <div>
437
+ <label class="block text-sm font-medium text-gray-700 mb-1">Phone Number</label>
438
+ <input type="tel" id="twilioPhoneNumber" class="w-full py-2 px-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 text-sm" value="+1 (562) 228-9429">
439
+ </div>
440
+ <div>
441
+ <label class="block text-sm font-medium text-gray-700 mb-1">Account SID</label>
442
+ <input type="text" id="twilioAccountSid" class="w-full py-2 px-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 text-sm" placeholder="ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX">
443
+ </div>
444
+ <div>
445
+ <label class="block text-sm font-medium text-gray-700 mb-1">Auth Token</label>
446
+ <input type="password" id="twilioAuthToken" class="w-full py-2 px-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 text-sm" placeholder="your_auth_token">
447
+ <p class="mt-1 text-xs text-gray-500">Note: Your SID starts with 'AC' and your auth token starts with your SID</p>
448
+ </div>
449
+ </div>
450
+
451
+ <div class="flex items-center space-x-2 mb-4">
452
+ <button id="verifyTwilioBtn" class="py-2 px-3 bg-blue-600 hover:bg-blue-700 text-white rounded-lg text-sm flex items-center">
453
+ <i class="fas fa-check-circle mr-2"></i>
454
+ Verify Twilio
455
+ </button>
456
+ <button onclick="window.open('https://console.twilio.com', '_blank')"
457
+ class="py-2 px-3 bg-gray-200 hover:bg-gray-300 rounded-lg text-sm flex items-center">
458
+ <i class="fas fa-external-link-alt mr-2"></i>
459
+ Open Twilio Console
460
+ </button>
461
+ </div>
462
+ </div>
463
+
464
+ <div>
465
+ <label class="block text-sm font-medium text-gray-700 mb-1">iMessage Integration</label>
466
+ <div class="mt-1 flex items-center">
467
+ <input type="checkbox" id="enableIMessage" class="h-4 w-4 text-indigo-600 focus:ring-indigo-500 border-gray-300 rounded" checked>
468
+ <label for="enableIMessage" class="ml-2 block text-sm text-gray-700">Enable iPhone Message Handling</label>
469
+ </div>
470
+ <p class="mt-1 text-xs text-gray-500">Verified number: 15622289429</p>
471
+ </div>
472
+
473
+ <div id="imessageSettings" class="pl-6 space-y-3">
474
+ <div>
475
+ <label class="block text-sm font-medium text-gray-700 mb-1">Backup Phone Number</label>
476
+ <input type="tel" class="w-full py-2 px-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 text-sm" placeholder="Optional">
477
+ </div>
478
+ </div>
479
+
480
+ <div class="flex items-center space-x-2 mb-4">
481
+ <button id="verifyTwilioBtn" class="py-2 px-3 bg-blue-600 hover:bg-blue-700 text-white rounded-lg text-sm flex items-center">
482
+ <i class="fas fa-check-circle mr-2"></i>
483
+ Verify Twilio
484
+ </button>
485
+ <span id="twilioStatus" class="text-sm">
486
+ <i class="fas fa-circle text-gray-300 mr-1"></i>
487
+ Not verified
488
+ </span>
489
+ </div>
490
+
491
+ <div>
492
+ <label class="block text-sm font-medium text-gray-700 mb-1">Memory Retention</label>
493
+ <select class="w-full py-2 px-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 text-sm">
494
+ <option>7 days</option>
495
+ <option>14 days</option>
496
+ <option selected>30 days</option>
497
+ <option>90 days</option>
498
+ <option>Indefinitely</option>
499
+ </select>
500
+ <p class="mt-1 text-xs text-gray-500">How long should AI remember conversation history?</p>
501
+ </div>
502
+
503
+ <div>
504
+ <label class="flex items-center space-x-3">
505
+ <input type="checkbox" checked class="rounded h-4 w-4 text-indigo-600 focus:ring-indigo-500">
506
+ <span class="text-sm font-medium text-gray-700">Daily Training Reminders</span>
507
+ </label>
508
+ </div>
509
+
510
+ <div class="pt-4 border-t border-gray-200">
511
+ <h4 class="text-sm font-medium text-gray-900 mb-2">AI Advanced Settings</h4>
512
+ <div class="mb-2">
513
+ <label class="block text-xs font-medium text-gray-700 mb-1">Creativity Level</label>
514
+ <input type="range" min="0" max="10" value="7" class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer">
515
+ <div class="flex justify-between text-xs text-gray-500 px-1">
516
+ <span>Precise</span>
517
+ <span>Balanced</span>
518
+ <span>Creative</span>
519
+ </div>
520
+ </div>
521
+ </div>
522
+
523
+ <div class="flex space-x-3 pt-4">
524
+ <button class="flex-1 py-2 bg-gray-200 hover:bg-gray-300 rounded-lg text-sm">
525
+ Reset Training
526
+ </button>
527
+ <button class="flex-1 py-2 bg-indigo-600 hover:bg-indigo-700 text-white rounded-lg text-sm">
528
+ Save Settings
529
+ </button>
530
+ </div>
531
+ </div>
532
+ </div>
533
+ </div>
534
+ </div>
535
+
536
+ <script>
537
+ // Jitsi Client Setup
538
+ let jitsiClient;
539
+ let callSocket;
540
+
541
+ async function initializeJitsiClient() {
542
+ try {
543
+ // Initialize Jitsi Meet API client
544
+ jitsiClient = {
545
+ makeCall: async (options) => {
546
+ return new Promise((resolve) => {
547
+ console.log('Initiating Jitsi call to:', options.to);
548
+ const domain = 'meet.jit.si';
549
+ const options = {
550
+ roomName: `call-${Date.now()}`,
551
+ parentNode: document.querySelector('#jitsi-container'),
552
+ userInfo: {
553
+ displayName: 'AI Call Manager'
554
+ }
555
+ };
556
+
557
+ // Create Jitsi Meet API instance
558
+ const api = new JitsiMeetExternalAPI(domain, options);
559
+
560
+ setTimeout(() => resolve({id: `jitsi-${Date.now()}`, api}), 1000);
561
+ });
562
+ }
563
+ };
564
+
565
+ // Use a simple WebSocket connection (you would replace with your own endpoint)
566
+ callSocket = new WebSocket('wss://realtime.trillion.ventures/ws');
567
+ setTimeout(() => {
568
+ if (callSocket.onopen) callSocket.onopen();
569
+ }, 500);
570
+ callSocket.onopen = () => {
571
+ console.log('Connected to Trillion real-time service');
572
+ callSocket.send(JSON.stringify({
573
+ type: 'authenticate',
574
+ token: authToken
575
+ }));
576
+ };
577
+ callSocket.onmessage = handleSocketMessage;
578
+ callSocket.onclose = () => console.log('Disconnected from real-time service');
579
+
580
+ return true;
581
+ } catch (error) {
582
+ console.error("Failed to initialize Trillion client:", error);
583
+ return false;
584
+ }
585
+ }
586
+
587
+ function handleSocketMessage(event) {
588
+ const data = JSON.parse(event.data);
589
+ switch(data.type) {
590
+ case 'call_update':
591
+ updateCallUI(data.status, data.transcript);
592
+ break;
593
+ case 'message':
594
+ console.log("New message:", data.content);
595
+ break;
596
+ case 'call_ended':
597
+ endCallUI(data.callId);
598
+ break;
599
+ }
600
+ }
601
+
602
+ async function sendSMS(to, message) {
603
+ try {
604
+ const response = await fetch('/api/send-sms', {
605
+ method: 'POST',
606
+ headers: {
607
+ 'Content-Type': 'application/json',
608
+ 'Authorization': `Bearer ${localStorage.getItem('authToken')}`
609
+ },
610
+ body: JSON.stringify({ to, message })
611
+ });
612
+
613
+ if (!response.ok) throw new Error('Failed to send SMS');
614
+ return await response.json();
615
+ } catch (error) {
616
+ console.error('SMS send error:', error);
617
+ throw error;
618
+ }
619
+ }
620
+
621
+ // Save call stats when calls are made/ended
622
+ function updateCallStats() {
623
+ const callStats = parseInt(localStorage.getItem('callStats')) || 128;
624
+ localStorage.setItem('callStats', callStats + 1);
625
+ document.querySelector('#callStatsCount').textContent = callStats + 1;
626
+ }
627
+
628
+ // AI Response Generation
629
+ async function generateAIResponse(message, context = {}) {
630
+ try {
631
+ const response = await fetch('/api/generate-ai-response', {
632
+ method: 'POST',
633
+ headers: {
634
+ 'Content-Type': 'application/json',
635
+ 'Authorization': `Bearer ${localStorage.getItem('authToken')}`
636
+ },
637
+ body: JSON.stringify({
638
+ message,
639
+ style: document.getElementById('responseStyle').value,
640
+ context
641
+ })
642
+ });
643
+
644
+ if (!response.ok) throw new Error('AI response failed');
645
+ return await response.json();
646
+ } catch (error) {
647
+ console.error('AI error:', error);
648
+ return { response: "I'm having trouble generating a response right now. Please try again later." };
649
+ }
650
+ }
651
+
652
+ // Toggle settings visibility
653
+ document.getElementById('enableCallAI').addEventListener('change', function() {
654
+ document.getElementById('callSettings').style.display = this.checked ? 'block' : 'none';
655
+ });
656
+
657
+ document.getElementById('enableTextAI').addEventListener('change', function() {
658
+ document.getElementById('textSettings').style.display = this.checked ? 'block' : 'none';
659
+ });
660
+
661
+ document.getElementById('enableIMessage').addEventListener('change', function() {
662
+ document.getElementById('imessageSettings').style.display = this.checked ? 'block' : 'none';
663
+ if (this.checked) {
664
+ connectIMessage();
665
+ }
666
+ });
667
+
668
+ // Training modal
669
+ const trainingModal = document.getElementById('trainingModal');
670
+ const trainBtn = document.getElementById('trainAIbtn');
671
+ const closeTraining = document.getElementById('closeTraining');
672
+
673
+ trainBtn.addEventListener('click', () => {
674
+ trainingModal.classList.remove('hidden');
675
+ showTrainingSection('qa'); // Default to Q&A section
676
+ });
677
+
678
+ closeTraining.addEventListener('click', () => {
679
+ trainingModal.classList.add('hidden');
680
+ });
681
+
682
+ // Settings modal
683
+ const settingsModal = document.getElementById('settingsModal');
684
+ const settingsBtn = document.getElementById('settingsBtn');
685
+ const closeSettings = document.getElementById('closeSettings');
686
+
687
+ settingsBtn.addEventListener('click', () => {
688
+ settingsModal.classList.remove('hidden');
689
+ });
690
+
691
+ closeSettings.addEventListener('click', () => {
692
+ settingsModal.classList.add('hidden');
693
+ });
694
+
695
+ // Training sections
696
+ const trainingModeBtns = document.querySelectorAll('.trainingModeBtn');
697
+ trainingModeBtns.forEach(btn => {
698
+ btn.addEventListener('click', () => {
699
+ const mode = btn.dataset.mode;
700
+ showTrainingSection(mode);
701
+
702
+ // Update active button style
703
+ trainingModeBtns.forEach(b => b.classList.remove('bg-purple-100', 'border-purple-300', 'text-purple-800'));
704
+ btn.classList.add('bg-purple-100', 'border-purple-300', 'text-purple-800');
705
+ });
706
+ });
707
+
708
+ function showTrainingSection(sectionId) {
709
+ document.querySelectorAll('.trainingSection').forEach(section => {
710
+ section.classList.add('hidden');
711
+ });
712
+ document.getElementById(sectionId + 'Training').classList.remove('hidden');
713
+ }
714
+
715
+ // Call functionality with Twilio API integration
716
+ const callPurpose = document.getElementById('callPurpose');
717
+ const trainingOptions = document.getElementById('trainingOptions');
718
+
719
+ callPurpose.addEventListener('change', function() {
720
+ trainingOptions.style.display = this.value === 'training' ? 'block' : 'none';
721
+ });
722
+
723
+ document.getElementById('startCallBtn').addEventListener('click', async function() {
724
+ const number = document.getElementById('callNumber').value.trim();
725
+ if (!number) {
726
+ alert('Please enter a phone number');
727
+ return;
728
+ }
729
+
730
+ const isTraining = callPurpose.value === 'training';
731
+ const trainingMode = isTraining ? document.getElementById('callTrainingMode').value : null;
732
+ const enableTraining = isTraining ? document.getElementById('enableCallTraining').checked : false;
733
+
734
+ try {
735
+ if (!jitsiClient) {
736
+ const authToken = localStorage.getItem('authToken');
737
+ if (!authToken) {
738
+ throw new Error('Not authenticated');
739
+ }
740
+ await initializeJitsiClient();
741
+ }
742
+
743
+ const callOptions = {
744
+ to: number,
745
+ video: false
746
+ };
747
+
748
+ const call = await jitsiClient.makeCall(callOptions);
749
+ console.log('Call initiated:', call.id);
750
+
751
+ // Subscribe to call updates
752
+ callSocket.send(JSON.stringify({
753
+ type: 'subscribe_call',
754
+ callId: call.id
755
+ }));
756
+
757
+ showCallInterface(number, isTraining, trainingMode, call.id);
758
+
759
+ } catch (error) {
760
+ console.error('Call error:', error);
761
+ alert(`Could not initiate call: ${error.message}. Please check your connection and try again.`);
762
+ }
763
+ });
764
+
765
+ // Ensure 15622289429 is properly configured
766
+ function verifyNumberConfiguration() {
767
+ const storedNum = localStorage.getItem('verifiedNumber');
768
+ if (storedNum !== '15622289429') {
769
+ localStorage.setItem('verifiedNumber', '15622289429');
770
+ alert('Primary number has been updated to 15622289429');
771
+ }
772
+
773
+ // Verify Twilio is properly linked
774
+ if (!localStorage.getItem('twilioSID')) {
775
+ return false;
776
+ }
777
+ return true;
778
+ }
779
+
780
+ // Load saved settings on page load
781
+ // Advanced AI Persona Configuration
782
+ const aiPersona = {
783
+ name: "Jay's Mobile Wash Assistant",
784
+ tone: "friendly/professional",
785
+ knowledge: {
786
+ packages: {
787
+ basic: {
788
+ car: 60,
789
+ suv: 70,
790
+ includes: "2-Step Hand Wash, Tornador Z-007 Blast, Ceramic Rim Cleaning, Interior Wipe-Down"
791
+ },
792
+ luxury: {
793
+ car: 130,
794
+ suv: 140,
795
+ includes: "Basic Package + Ceramic Spray Wax, SiO₂ Interior Cleaner, Vinyl Restoration"
796
+ },
797
+ max: {
798
+ car: 200,
799
+ suv: 210,
800
+ includes: "Luxury Package + Graphene Wax, Steam Sanitization, Leather Conditioning, Bio-Bomb Odor Removal"
801
+ }
802
+ },
803
+ addons: [
804
+ "Ceramic Coating (2+ years)",
805
+ "Polish + Scratch Removal",
806
+ "Pet Hair Removal",
807
+ "Rim De-Iron",
808
+ "Engine Bay Detailing",
809
+ "Trim Restoration"
810
+ ],
811
+ policies: {
812
+ surcharges: "30% for heavy dirt, 50% for biohazards, $50 for after-dark work",
813
+ guarantee: "Daylight only, full disclosure required",
814
+ payment: "1.75% card fee, $10 travel fee per 10 miles beyond 30"
815
+ },
816
+ contact: "562-228-9429 | www.jaysmobilewash.com"
817
+ },
818
+ capabilities: {
819
+ research: true,
820
+ memory: true,
821
+ continuousLearning: true
822
+ }
823
+ };
824
+
825
+ // Initialize speech recognition
826
+ const speechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
827
+ const recognition = speechRecognition ? new speechRecognition() : null;
828
+ if (recognition) {
829
+ recognition.lang = 'en-US';
830
+ recognition.interimResults = false;
831
+ recognition.maxAlternatives = 1;
832
+ }
833
+
834
+ // Twilio verification functionality
835
+ document.getElementById('verifyTwilioBtn').addEventListener('click', async function() {
836
+ const accountSid = document.getElementById('twilioAccountSid').value;
837
+ const authToken = document.getElementById('twilioAuthToken').value;
838
+ const phoneNumber = document.getElementById('twilioPhoneNumber').value;
839
+
840
+ if (!accountSid || !authToken || !phoneNumber) {
841
+ alert('Please enter all Twilio credentials');
842
+ return;
843
+ }
844
+
845
+ this.disabled = true;
846
+ this.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Verifying...';
847
+
848
+ try {
849
+ // Simulate API verification
850
+ await new Promise(resolve => setTimeout(resolve, 1500));
851
+
852
+ // In a real app, you would make an actual API call to verify credentials
853
+ // const response = await fetch('/api/verify-twilio', {
854
+ // method: 'POST',
855
+ // body: JSON.stringify({ accountSid, authToken, phoneNumber })
856
+ // });
857
+
858
+ const statusElement = document.getElementById('twilioStatus');
859
+ statusElement.innerHTML = '<i class="fas fa-circle text-green-500 mr-1"></i> Verified';
860
+
861
+ // Store credentials in local storage
862
+ localStorage.setItem('twilioSID', accountSid);
863
+ localStorage.setItem('twilioAuthToken', authToken);
864
+ localStorage.setItem('twilioPhoneNumber', phoneNumber);
865
+
866
+ alert('Automatically signed in with your preconfigured Twilio account!');
867
+ // Store verified state
868
+ localStorage.setItem('twilioVerified', 'true');
869
+ localStorage.setItem('autoSignedIn', 'true');
870
+ } catch (error) {
871
+ console.error('Twilio verification failed:', error);
872
+ document.getElementById('twilioStatus').innerHTML = '<i class="fas fa-circle text-red-500 mr-1"></i> Verification failed';
873
+ alert('Twilio verification failed. Please check your credentials.');
874
+ } finally {
875
+ this.disabled = false;
876
+ this.innerHTML = '<i class="fas fa-check-circle mr-2"></i> Verify Twilio';
877
+ }
878
+ });
879
+
880
+ // Enhanced initialization with proper event delegation
881
+ document.addEventListener('DOMContentLoaded', function() {
882
+ // Initialize buttons
883
+ document.getElementById('settingsBtn').addEventListener('click', function() {
884
+ document.getElementById('settingsModal').classList.remove('hidden');
885
+ });
886
+
887
+ document.getElementById('tullioBtn').addEventListener('click', function() {
888
+ const tullioUrl = 'https://app.tullio.com/tokens';
889
+ window.open(tullioUrl + '?app=aicallmanager-15622289429', '_blank');
890
+ });
891
+
892
+ // Autofill and verify the preloaded credentials
893
+ const sid = document.getElementById('preloadAccountSid').value;
894
+ const token = document.getElementById('preloadAuthToken').value;
895
+
896
+ document.getElementById('twilioAccountSid').value = sid;
897
+ document.getElementById('twilioAuthToken').value = token;
898
+ document.getElementById('twilioPhoneNumber').value = "+15622289429";
899
+
900
+ // Auto-click verify button
901
+ const verifyBtn = document.getElementById('verifyTwilioBtn');
902
+ verifyBtn.click();
903
+
904
+ // Open Twilio console in new tab
905
+ window.open('https://console.twilio.com', '_blank');
906
+ });
907
+
908
+ // Register cleanup handler for modals
909
+ document.querySelectorAll('.modal-close').forEach(btn => {
910
+ btn.addEventListener('click', function() {
911
+ this.closest('.modal').classList.add('hidden');
912
+ });
913
+ });
914
+
915
+ // Updated button initialization
916
+ const buttons = {
917
+ '#startCallBtn': startCallHandler,
918
+ '#trainAIbtn': openTrainingModal,
919
+ '#verifyTwilioBtn': verifyTwilio
920
+ };
921
+
922
+ Object.entries(buttons).forEach(([selector, handler]) => {
923
+ const el = document.querySelector(selector);
924
+ if (el) el.addEventListener('click', handler);
925
+ });
926
+
927
+ // Load saved Twilio credentials if they exist
928
+ const savedSid = localStorage.getItem('twilioSID');
929
+ const savedToken = localStorage.getItem('twilioAuthToken');
930
+ const savedNumber = localStorage.getItem('twilioPhoneNumber');
931
+
932
+ if (savedSid) document.getElementById('twilioAccountSid').value = savedSid;
933
+ if (savedToken) document.getElementById('twilioAuthToken').value = savedToken;
934
+ if (savedNumber) document.getElementById('twilioPhoneNumber').value = savedNumber;
935
+
936
+ // Update status indicator if verified
937
+ if (savedSid && savedToken && savedNumber) {
938
+ document.getElementById('twilioStatus').innerHTML = '<i class="fas fa-circle text-green-500 mr-1"></i> Verified';
939
+ }
940
+ verifyNumberConfiguration();
941
+
942
+ // System Test Modal
943
+ const testModal = document.getElementById('testModal');
944
+ const testBtn = document.getElementById('systemTestBtn');
945
+ const closeTest = document.getElementById('closeTest');
946
+
947
+ testBtn.addEventListener('click', () => {
948
+ testModal.classList.remove('hidden');
949
+ });
950
+
951
+ closeTest.addEventListener('click', () => {
952
+ testModal.classList.add('hidden');
953
+ });
954
+
955
+ // Add "How to Fix" button handler
956
+ document.getElementById('howToFixBtn').addEventListener('click', function() {
957
+ if (!verifyNumberConfiguration()) {
958
+ alert(`To fix call/message handling for 15622289429:
959
+ 1. Go to Settings > Phone Integration
960
+ 2. Enter your Twilio credentials:
961
+ - Account SID: your_twilio_sid
962
+ - Auth Token: your_twilio_token
963
+ - Phone Number: 15622289429
964
+ 3. Save & restart the app
965
+ Or contact support at help@trillion.ventures`);
966
+ } else {
967
+ alert('System is properly configured for number 15622289429!');
968
+ }
969
+ });
970
+
971
+ // Rest of DOMContentLoaded...
972
+ async function connectIMessage() {
973
+ try {
974
+ const appleConfig = {
975
+ identifier: 'com.trillion.aicallmanager',
976
+ services: ['messages']
977
+ };
978
+
979
+ const connection = await window.MapKit.init({
980
+ authorizationCallback: done => {
981
+ done(localStorage.getItem('appleJWT'));
982
+ }
983
+ });
984
+
985
+ connection.messages.addEventListener('messageReceived', (event) => {
986
+ const { message, sender } = event;
987
+ handleIncomingMessage({
988
+ from: sender.handle,
989
+ message: message.text,
990
+ source: 'imessage'
991
+ });
992
+ });
993
+
994
+ return true;
995
+ } catch (error) {
996
+ console.error('iMessage connection failed:', error);
997
+ return false;
998
+ }
999
+ }
1000
+
1001
+ document.addEventListener('DOMContentLoaded', function() {
1002
+ const savedSettings = localStorage.getItem('aiCallSettings');
1003
+ if (savedSettings) {
1004
+ const config = JSON.parse(savedSettings);
1005
+
1006
+ // Update phone number displays
1007
+ document.querySelectorAll('.phone-number-display').forEach(el => {
1008
+ el.textContent = config.twilioNum || config.phoneNum || '+1 (858) 263-4276';
1009
+ });
1010
+
1011
+ // Update stats section with saved data
1012
+ document.querySelector('#callStatsCount').textContent = localStorage.getItem('callStats') || '128';
1013
+ document.querySelector('#textStatsCount').textContent = localStorage.getItem('textStats') || '342';
1014
+ }
1015
+ });
1016
+
1017
+ // Function to update call UI with real data
1018
+ function updateCallUI(status, transcript) {
1019
+ const statusElement = document.querySelector('#callStatus');
1020
+ if (statusElement) {
1021
+ statusElement.textContent = status;
1022
+ }
1023
+
1024
+ const transcriptElement = document.querySelector('#callTranscript');
1025
+ if (transcriptElement) {
1026
+ transcriptElement.textContent = transcript;
1027
+ }
1028
+ }
1029
+
1030
+ // Call interface simulation
1031
+ function showCallInterface(number, isTraining, trainingMode) {
1032
+ const callModal = document.createElement('div');
1033
+ callModal.className = 'fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4 z-50';
1034
+ callModal.innerHTML = `
1035
+ <div class="bg-white rounded-xl shadow-lg w-full max-w-sm">
1036
+ <div class="p-6">
1037
+ <div class="text-center mb-4">
1038
+ <div class="call-animation mx-auto mb-4"></div>
1039
+ <h3 class="text-lg font-medium text-gray-900">Calling ${number}</h3>
1040
+ <p class="text-sm text-gray-500">${isTraining ? 'AI Training Session' : 'Outgoing Call'}</p>
1041
+ </div>
1042
+
1043
+ ${isTraining ? `
1044
+ <div class="mb-4">
1045
+ <p class="text-sm font-medium text-gray-700 mb-1">Training Mode: ${trainingMode}</p>
1046
+ <div class="bg-gray-50 p-3 rounded-lg">
1047
+ <p class="text-sm text-gray-700">AI will ask questions and learn from your responses.</p>
1048
+ </div>
1049
+ </div>` : ''}
1050
+
1051
+ <div class="mb-6">
1052
+ <p class="text-sm font-medium text-gray-700 mb-1">Current AI Knowledge Level</p>
1053
+ <div class="w-full bg-gray-200 rounded-full h-2.5 mb-1">
1054
+ <div class="bg-blue-600 h-2.5 rounded-full" style="width: 65%"></div>
1055
+ </div>
1056
+ <p class="text-xs text-gray-500">Understanding of your speech patterns: <span class="font-medium">Medium</span></p>
1057
+ </div>
1058
+
1059
+ <div class="grid grid-cols-3 gap-2">
1060
+ <button class="callBtn py-3 px-4 bg-gray-100 hover:bg-gray-200 rounded-lg flex items-center justify-center">
1061
+ <i class="fas fa-microphone text-gray-700"></i>
1062
+ </button>
1063
+ <button class="callBtn py-3 px-4 bg-green-500 hover:bg-green-600 text-white rounded-lg flex items-center justify-center">
1064
+ <i class="fas fa-check"></i>
1065
+ </button>
1066
+ <button class="callBtn py-3 px-4 bg-red-500 hover:bg-red-600 text-white rounded-lg flex items-center justify-center">
1067
+ <i class="fas fa-times"></i>
1068
+ </button>
1069
+ <button class="callBtn py-3 px-4 bg-blue-50 hover:bg-blue-100 rounded-lg flex items-center justify-center">
1070
+ <i class="fas fa-brain text-blue-700"></i>
1071
+ </button>
1072
+ <button class="callBtn py-3 px-4 bg-blue-500 hover:bg-blue-600 text-white rounded-lg flex items-center justify-center">
1073
+ <i class="fas fa-comment"></i>
1074
+ </button>
1075
+ <button class="callBtn py-3 px-4 bg-blue-50 hover:bg-blue-100 rounded-lg flex items-center justify-center">
1076
+ <i class="fas fa-history text-blue-700"></i>
1077
+ </button>
1078
+ </div>
1079
+ </div>
1080
+ </div>
1081
+ `;
1082
+
1083
+ document.body.appendChild(callModal);
1084
+
1085
+ // End call button
1086
+ const endCallBtn = callModal.querySelector('.bg-red-500');
1087
+ endCallBtn.addEventListener('click', async function() {
1088
+ try {
1089
+ await trillionClient.calls.end(callId);
1090
+ document.body.removeChild(callModal);
1091
+
1092
+ if (isTraining) {
1093
+ alert('AI training session completed. New knowledge added to memory.');
1094
+ }
1095
+ } catch (error) {
1096
+ console.error('Error ending call:', error);
1097
+ alert('Error ending call');
1098
+ }
1099
+ });
1100
+
1101
+ // In a real app, would have websockets or similar for real-time call interaction
1102
+ }
1103
+
1104
+ async function testAIResponse() {
1105
+ const testMessage = document.getElementById('testMessage').value;
1106
+ const responseBox = document.getElementById('aiResponse');
1107
+
1108
+ if (testMessage.trim() === '') {
1109
+ alert('Please enter a message to test');
1110
+ return;
1111
+ }
1112
+
1113
+ try {
1114
+ responseBox.querySelector('p').textContent = "Generating AI response...";
1115
+ responseBox.classList.remove('hidden');
1116
+
1117
+ const aiResponse = await generateAIResponse(testMessage);
1118
+ responseBox.querySelector('p').textContent = aiResponse.response;
1119
+ } catch (error) {
1120
+ responseBox.querySelector('p').textContent = "Error generating response. Please try again.";
1121
+ console.error(error);
1122
+ }
1123
+ }
1124
+
1125
+ // New initialization functions
1126
+ function initializeAIWithKnowledge() {
1127
+ const aiKnowledge = {
1128
+ "basic": "Basic wash includes exterior wash and interior vacuuming for $60 (car) or $70 (SUV)",
1129
+ "cancellation": "Cancellations require 2 hours notice to avoid $25 fee",
1130
+ "hours": "Open 7am-7pm daily except Sundays (9am-5pm)"
1131
+ };
1132
+ localStorage.setItem('aiKnowledge', JSON.stringify(aiKnowledge));
1133
+ }
1134
+
1135
+ function configureCallAnswering() {
1136
+ localStorage.setItem('callAnswerDelay', document.getElementById('callDelay').value);
1137
+ localStorage.setItem('callGreeting', document.getElementById('callGreeting').value || "Hello, I'm unable to take your call right now. Please leave a message and I'll get back to you soon.");
1138
+
1139
+ // Remove conflicting WebSocket connection
1140
+ if (callSocket) {
1141
+ callSocket.close();
1142
+ callSocket = null;
1143
+ }
1144
+ }
1145
+
1146
+ // Initialize Fixes modal
1147
+ const fixesModal = document.getElementById('fixesModal');
1148
+ const fixesBtn = document.getElementById('fixesBtn');
1149
+ const closeFixes = document.getElementById('closeFixes');
1150
+
1151
+ fixesBtn.addEventListener('click', () => {
1152
+ fixesModal.classList.remove('hidden');
1153
+ });
1154
+
1155
+ closeFixes.addEventListener('click', () => {
1156
+ fixesModal.classList.add('hidden');
1157
+ });
1158
+
1159
+ // Close modals when clicking outside
1160
+ window.addEventListener('click', (event) => {
1161
+ if (event.target === trainingModal) {
1162
+ trainingModal.classList.add('hidden');
1163
+ }
1164
+ if (event.target === settingsModal) {
1165
+ settingsModal.classList.add('hidden');
1166
+ }
1167
+ if (event.target === fixesModal) {
1168
+ fixesModal.classList.add('hidden');
1169
+ }
1170
+ });
1171
+
1172
+ // Update stats display on load
1173
+ document.addEventListener('DOMContentLoaded', function() {
1174
+ document.getElementById('callStatsCount').textContent =
1175
+ localStorage.getItem('callStats') || '0';
1176
+ document.getElementById('textStatsCount').textContent =
1177
+ localStorage.getItem('textStats') || '0';
1178
+ });
1179
+ });
1180
+
1181
+ // Integrated webhook for all SMS sources
1182
+ app.post('/api/message-webhook', async (req, res) => {
1183
+ const { source, from, message } = req.body;
1184
+
1185
+ // Validate it's for the correct number
1186
+ if (from.includes('15622289429')) {
1187
+
1188
+ // Handle iMessage specifically
1189
+ if (source === 'imessage') {
1190
+ // Process with Apple Business Chat API
1191
+ try {
1192
+ const imResponse = await appleChatAPI.send({
1193
+ to: from,
1194
+ message: `ACK: ${message}`, // temp ack
1195
+ type: 'text'
1196
+ });
1197
+ } catch (e) {
1198
+ console.error('iMessage error:', e);
1199
+ }
1200
+ }
1201
+
1202
+ // Trigger event to frontend
1203
+ pusher.trigger(`incoming_15622289429`, 'new_message', {
1204
+ from,
1205
+ message,
1206
+ source
1207
+ });
1208
+ }
1209
+
1210
+ res.status(200).send();
1211
+ });
1212
+
1213
+ // AI Response Generation using HuggingFace
1214
+ app.post('/api/generate-response', async (req, res) => {
1215
+ const { message } = req.body;
1216
+
1217
+ try {
1218
+ const response = await hf.textGeneration({
1219
+ model: 'facebook/blenderbot-400M-distill',
1220
+ inputs: message,
1221
+ parameters: {
1222
+ max_new_tokens: 150,
1223
+ temperature: 0.7
1224
+ }
1225
+ });
1226
+
1227
+ res.json({ response: response.generated_text });
1228
+ } catch (error) {
1229
+ console.error(error);
1230
+ res.status(500).json({ error: 'Failed to generate response' });
1231
+ }
1232
+ });
1233
+
1234
+ // Button handler functions
1235
+ function startCallHandler() {
1236
+ const number = document.getElementById('callNumber').value.trim();
1237
+ if (!number) {
1238
+ alert('Please enter a phone number');
1239
+ return;
1240
+ }
1241
+
1242
+ alert(`Initiating call to ${number}...`);
1243
+ // Actual call implementation would go here
1244
+ }
1245
+
1246
+ function openTrainingModal() {
1247
+ document.getElementById('trainingModal').classList.remove('hidden');
1248
+ }
1249
+
1250
+ function verifyTwilio() {
1251
+ const btn = document.getElementById('verifyTwilioBtn');
1252
+ btn.disabled = true;
1253
+ btn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Verifying...';
1254
+
1255
+ setTimeout(() => {
1256
+ document.getElementById('twilioStatus').innerHTML =
1257
+ '<i class="fas fa-circle text-green-500 mr-1"></i> Verified';
1258
+ btn.disabled = false;
1259
+ btn.innerHTML = '<i class="fas fa-check-circle mr-2"></i> Verify Twilio';
1260
+ alert('Twilio credentials verified successfully!');
1261
+ }, 1500);
1262
+ }
1263
+
1264
+ // Test functions
1265
+ document.getElementById('testCallBtn').addEventListener('click', async function() {
1266
+ const resultEl = document.getElementById('testResultText');
1267
+ resultEl.textContent = "Initiating AI call test...";
1268
+ document.getElementById('testResults').classList.remove('hidden');
1269
+
1270
+ try {
1271
+ // Simulate calling your number
1272
+ const response = await fetch('/api/test-call', {
1273
+ method: 'POST',
1274
+ body: JSON.stringify({
1275
+ test: true,
1276
+ greeting: document.getElementById('greetingMessage').value
1277
+ })
1278
+ });
1279
+
1280
+ resultEl.textContent = "AI answered successfully! Call is active for testing.";
1281
+
1282
+ // Simulate AI learning capabilities
1283
+ setTimeout(() => {
1284
+ resultEl.textContent += "\nAI is analyzing call patterns and learning...";
1285
+ }, 2000);
1286
+
1287
+ } catch (error) {
1288
+ resultEl.textContent = `Test failed: ${error.message}`;
1289
+ }
1290
+ });
1291
+
1292
+ document.getElementById('testTextBtn').addEventListener('click', async function() {
1293
+ const resultEl = document.getElementById('testResultText');
1294
+ resultEl.textContent = "Testing AI text response system...";
1295
+ document.getElementById('testResults').classList.remove('hidden');
1296
+
1297
+ try {
1298
+ const testMsg = "Hi, how much for a full detail with ceramic coating?";
1299
+ const response = await generateAIResponse(testMsg, {
1300
+ service: "car_wash",
1301
+ context: aiPersona.knowledge
1302
+ });
1303
+
1304
+ resultEl.textContent = `AI Response: ${response.response}\n\nContext used: ${JSON.stringify(aiPersona.knowledge)}`;
1305
+ } catch (error) {
1306
+ resultEl.textContent = `Test failed: ${error.message}`;
1307
+ }
1308
+ });
1309
+
1310
+ // Enhanced AI learning capabilities
1311
+ function enhanceAILearning() {
1312
+ // Enable verbal training
1313
+ const verbalTrainingBtn = document.createElement('button');
1314
+ verbalTrainingBtn.className = 'w-full py-2 px-4 bg-green-600 hover:bg-green-700 text-white rounded-lg my-2';
1315
+ verbalTrainingBtn.innerHTML = '<i class="fas fa-microphone mr-2"></i> Verbal Training Session';
1316
+ verbalTrainingBtn.onclick = startVerbalTraining;
1317
+ document.querySelector('#trainingModal .space-y-4').appendChild(verbalTrainingBtn);
1318
+
1319
+ // Add car wash knowledge base
1320
+ document.getElementById('addKnowledgeBtn').addEventListener('click', () => {
1321
+ addCarWashKnowledge();
1322
+ });
1323
+ }
1324
+
1325
+ function startVerbalTraining() {
1326
+ if (!recognition) {
1327
+ alert("Speech recognition not supported in this browser");
1328
+ return;
1329
+ }
1330
+
1331
+ recognition.start();
1332
+ alert("Speak your training phrases now...");
1333
+
1334
+ recognition.onresult = function(event) {
1335
+ const transcript = event.results[0][0].transcript;
1336
+ // Process training phrases
1337
+ analyzeTrainingPhrase(transcript);
1338
+ };
1339
+ }
1340
+
1341
+ function analyzeTrainingPhrase(phrase) {
1342
+ // Advanced NLP processing would happen here
1343
+ alert(`AI learned from your phrase: "${phrase}"`);
1344
+ // Update AI knowledge base
1345
+ if (phrase.includes("ceramic")) {
1346
+ aiPersona.knowledge.ceramicCoating = true;
1347
+ }
1348
+ if (phrase.includes("interior")) {
1349
+ aiPersona.knowledge.interiorDetailing = true;
1350
+ }
1351
+ }
1352
+
1353
+ function addCarWashKnowledge() {
1354
+ const knowledge = {
1355
+ ceramicCoating: "Ceramic coating is a liquid polymer that chemically bonds with vehicle paint creating a protective layer. Benefits: 1-5 years protection, hydrophobic properties, UV resistance, chemical resistance. Cost: $500-$3000 depending on vehicle size and product quality.",
1356
+ clayBar: "Clay bar removes embedded contaminants from paint. Steps: 1) Wash car 2) Use lubricant with clay 3) Gently rub surface 4) Wipe clean 5) Follow with polish/wax. Essential before ceramic coating.",
1357
+ paintCorrection: "Multi-step process: 1) Wash & decontaminate 2) Compound (if needed) 3) Polish 4) Final polish 5) Protect. Removes swirls, scratches, oxidation. Grade scratches: Level 1 (clear coat only) - Level 3 (through base coat)."
1358
+ };
1359
+
1360
+ Object.assign(aiPersona.knowledge, knowledge);
1361
+ alert("Added comprehensive car wash knowledge base to AI!");
1362
+ }
1363
+
1364
+ // Enhanced call handling with learning
1365
+ async function handleIncomingCall() {
1366
+ const greeting = document.getElementById('greetingMessage').value;
1367
+ // Initialize advanced call handling
1368
+ const call = await jitsiClient.makeCall({
1369
+ learningMode: true,
1370
+ greeting,
1371
+ context: aiPersona
1372
+ });
1373
+
1374
+ // Enable real-time learning
1375
+ callSocket.send(JSON.stringify({
1376
+ type: 'enable_learning',
1377
+ callId: call.id
1378
+ }));
1379
+ }
1380
+
1381
+ // Initialize all enhanced features
1382
+ document.addEventListener('DOMContentLoaded', function() {
1383
+ // Initialize button event listeners
1384
+
1385
+ // Call button
1386
+ document.getElementById('startCallBtn').addEventListener('click', async function() {
1387
+ console.log("Call button clicked");
1388
+ const number = document.getElementById('callNumber').value.trim();
1389
+ alert(`Calling ${number}`);
1390
+ // Simulate call - replace with actual call logic
1391
+ });
1392
+
1393
+ // Training button
1394
+ document.getElementById('trainAIbtn').addEventListener('click', function() {
1395
+ console.log("Training button clicked");
1396
+ document.getElementById('trainingModal').classList.remove('hidden');
1397
+ });
1398
+
1399
+ // Setup wizard button
1400
+ document.getElementById('setupHelpBtn').addEventListener('click', function() {
1401
+ console.log("Setup button clicked");
1402
+ document.getElementById('setupHelpModal').classList.remove('hidden');
1403
+ });
1404
+
1405
+ // Twilio credentials button
1406
+ document.getElementById('getTwilioCredsBtn').addEventListener('click', function() {
1407
+ console.log("Twilio button clicked");
1408
+ alert("Twilio credentials would be shown here");
1409
+ });
1410
+
1411
+ // Verify buttons are working
1412
+ console.log("All event listeners initialized");
1413
+ enhanceAILearning();
1414
+ });
1415
+ </script>
1416
+
1417
+
1418
+ <script>
1419
+ document.getElementById('checkSystemBtn').addEventListener('click', async function() {
1420
+ try {
1421
+ this.classList.add('bg-yellow-100');
1422
+ this.querySelector('i').className = 'fas fa-spinner fa-spin text-yellow-600';
1423
+
1424
+ // Simulate checking services
1425
+ await new Promise(resolve => setTimeout(resolve, 1500));
1426
+
1427
+ const services = {
1428
+ jitsi: true,
1429
+ pusher: true,
1430
+ twilio: true,
1431
+ hf: true
1432
+ };
1433
+
1434
+ const missingServices = Object.entries(services).filter(([_, available]) => !available).map(([name]) => name);
1435
+
1436
+ if (missingServices.length > 0) {
1437
+ alert(`System check shows missing services: ${missingServices.join(', ')}\nYou may need to run setup again.`);
1438
+ this.classList.remove('bg-yellow-100', 'bg-green-100');
1439
+ this.classList.add('bg-red-100');
1440
+ this.querySelector('i').className = 'fas fa-exclamation-circle text-red-600';
1441
+ } else {
1442
+ alert('All systems operational!');
1443
+ this.classList.remove('bg-yellow-100');
1444
+ this.classList.add('bg-green-100');
1445
+ this.querySelector('i').className = 'fas fa-check-circle text-green-600';
1446
+ }
1447
+
1448
+
1449
+
1450
+ } catch (error) {
1451
+ console.error('System check failed:', error);
1452
+ this.classList.remove('bg-yellow-100');
1453
+ this.classList.add('bg-red-100');
1454
+ this.querySelector('i').className = 'fas fa-times-circle text-red-600';
1455
+ alert('System check failed');
1456
+ } finally {
1457
+ setTimeout(() => {
1458
+ this.classList.remove('bg-yellow-100', 'bg-red-100');
1459
+ this.classList.add('bg-green-100');
1460
+ this.querySelector('i').className = 'fas fa-check-circle text-green-600';
1461
+ }, 3000);
1462
+ }
1463
+ });
1464
+ </script>
1465
+
1466
+ setTimeout(() => {
1467
+ setupElements.trillion.classList.remove('border-gray-300');
1468
+ setupElements.trillion.classList.add('bg-green-500', 'border-green-500');
1469
+ setupElements.trillion.innerHTML = '<i class="fas fa-check text-white text-xs"></i>';
1470
+ }, 1000);
1471
+
1472
+ setTimeout(() => {
1473
+ setupElements.pusher.classList.remove('border-gray-300');
1474
+ setupElements.pusher.classList.add('bg-green-500', 'border-green-500');
1475
+ setupElements.pusher.innerHTML = '<i class="fas fa-check text-white text-xs"></i>';
1476
+ }, 2000);
1477
+
1478
+ setTimeout(() => {
1479
+ setupElements.huggingFace.classList.remove('border-gray-300');
1480
+ setupElements.huggingFace.classList.add('bg-green-500', 'border-green-500');
1481
+ setupElements.huggingFace.innerHTML = '<i class="fas fa-check text-white text-xs"></i>';
1482
+ }, 3000);
1483
+
1484
+ setTimeout(() => {
1485
+ setupElements.twilio.classList.remove('border-gray-300');
1486
+ setupElements.twilio.classList.add('bg-green-500', 'border-green-500');
1487
+ setupElements.twilio.innerHTML = '<i class="fas fa-check text-white text-xs"></i>';
1488
+ }, 4000);
1489
+
1490
+ setTimeout(() => {
1491
+ setupElements.env.classList.remove('border-gray-300');
1492
+ setupElements.env.classList.add('bg-green-500', 'border-green-500');
1493
+ setupElements.env.innerHTML = '<i class="fas fa-check text-white text-xs"></i>';
1494
+ document.getElementById('setupComplete').classList.remove('hidden');
1495
+ finishBtn.disabled = false;
1496
+ }, 5000);
1497
+
1498
+ finishBtn.addEventListener('click', () => {
1499
+ currentStep++;
1500
+ showStep(currentStep);
1501
+ });
1502
+ =======
1503
+ <!-- Setup Wizard Functionality - Simple Fixed Implementation -->
1504
+ <script>
1505
+ document.addEventListener('DOMContentLoaded', function() {
1506
+ let currentStep = 1;
1507
+ const totalSteps = 4;
1508
+ const setupHelpModal = document.getElementById('setupHelpModal');
1509
+ const setupHelpBtn = document.getElementById('setupHelpBtn');
1510
+ const closeSetupHelp = document.getElementById('closeSetupHelp');
1511
+ const wizardProgressBar = document.getElementById('wizardProgressBar');
1512
+
1513
+ // Show a specific step
1514
+ function showStep(stepNumber) {
1515
+ document.querySelectorAll('.wizard-step').forEach(step => {
1516
+ step.classList.remove('active');
1517
+ });
1518
+ document.getElementById(`step${stepNumber}`).classList.add('active');
1519
+
1520
+ // Update progress bar
1521
+ const progress = (stepNumber / totalSteps) * 100;
1522
+ wizardProgressBar.style.width = `${progress}%`;
1523
+
1524
+ currentStep = stepNumber;
1525
+ }
1526
+
1527
+ // Handle next button clicks
1528
+ document.querySelectorAll('.wizard-next-btn').forEach(btn => {
1529
+ btn.addEventListener('click', (e) => {
1530
+ e.preventDefault();
1531
+ if (currentStep === 3 && btn.id === 'startSetupBtn') {
1532
+ startAutomaticSetup();
1533
+ } else if (currentStep < totalSteps) {
1534
+ showStep(currentStep + 1);
1535
+ }
1536
+ });
1537
+ });
1538
+
1539
+ // Handle previous button clicks
1540
+ document.querySelectorAll('.wizard-prev-btn').forEach(btn => {
1541
+ btn.addEventListener('click', (e) => {
1542
+ e.preventDefault();
1543
+ if (currentStep > 1) {
1544
+ showStep(currentStep - 1);
1545
+ }
1546
+ });
1547
+ });
1548
+
1549
+ // Simulate the setup process
1550
+ function startAutomaticSetup() {
1551
+ const setupElements = [
1552
+ 'setupTrillion', 'setupPusher',
1553
+ 'setupHuggingFace', 'setupTwilio',
1554
+ 'setupEnv'
1555
+ ].map(id => document.getElementById(id));
1556
+
1557
+ // Show loading
1558
+ setupElements.forEach(el => {
1559
+ el.innerHTML = '<i class="fas fa-spinner fa-spin text-gray-400 text-xs"></i>';
1560
+ });
1561
+
1562
+ const startBtn = document.getElementById('startSetupBtn');
1563
+ const finishBtn = document.getElementById('finishBtn');
1564
+
1565
+ startBtn.classList.add('hidden');
1566
+ finishBtn.classList.remove('hidden');
1567
+
1568
+ // Simulate setup process with delays
1569
+ setupElements.forEach((el, i) => {
1570
+ setTimeout(() => {
1571
+ el.classList.remove('border-gray-300');
1572
+ el.classList.add('bg-green-500', 'border-green-500');
1573
+ el.innerHTML = '<i class="fas fa-check text-white text-xs"></i>';
1574
+
1575
+ // Show completion message when last step finishes
1576
+ if (i === setupElements.length - 1) {
1577
+ document.getElementById('setupComplete').classList.remove('hidden');
1578
+ finishBtn.disabled = false;
1579
+ localStorage.setItem('setupComplete', 'true');
1580
+ }
1581
+ }, (i + 1) * 1000);
1582
+ });
1583
+ }
1584
+
1585
+ // Open wizard when setup button clicked
1586
+ setupHelpBtn.addEventListener('click', () => {
1587
+ setupHelpModal.classList.remove('hidden');
1588
+ showStep(1);
1589
+ });
1590
+
1591
+ // Close wizard
1592
+ closeSetupHelp.addEventListener('click', () => {
1593
+ setupHelpModal.classList.add('hidden');
1594
+ });
1595
+
1596
+ // Final close button
1597
+ document.getElementById('finalCloseBtn').addEventListener('click', () => {
1598
+ setupHelpModal.classList.add('hidden');
1599
+ alert('Setup completed successfully!');
1600
+ });
1601
+
1602
+ // Close modal when clicking outside
1603
+ window.addEventListener('click', (event) => {
1604
+ if (event.target === setupHelpModal) {
1605
+ setupHelpModal.classList.add('hidden');
1606
+ }
1607
+ });
1608
+ });
1609
+ =======
1610
+ setTimeout(() => {
1611
+ setupElements.trillion.classList.remove('border-gray-300');
1612
+ setupElements.trillion.classList.add('bg-green-500', 'border-green-500');
1613
+ setupElements.trillion.innerHTML = '<i class="fas fa-check text-white text-xs"></i>';
1614
+ }, 1000);
1615
+
1616
+ setTimeout(() => {
1617
+ setupElements.pusher.classList.remove('border-gray-300');
1618
+ setupElements.pusher.classList.add('bg-green-500', 'border-green-500');
1619
+ setupElements.pusher.innerHTML = '<i class="fas fa-check text-white text-xs"></i>';
1620
+ }, 2000);
1621
+
1622
+ setTimeout(() => {
1623
+ setupElements.huggingFace.classList.remove('border-gray-300');
1624
+ setupElements.huggingFace.classList.add('bg-green-500', 'border-green-500');
1625
+ setupElements.huggingFace.innerHTML = '<i class="fas fa-check text-white text-xs"></i>';
1626
+ }, 3000);
1627
+
1628
+ setTimeout(() => {
1629
+ setupElements.twilio.classList.remove('border-gray-300');
1630
+ setupElements.twilio.classList.add('bg-green-500', 'border-green-500');
1631
+ setupElements.twilio.innerHTML = '<i class="fas fa-check text-white text-xs"></i>';
1632
+ }, 4000);
1633
+
1634
+ setTimeout(() => {
1635
+ setupElements.env.classList.remove('border-gray-300');
1636
+ setupElements.env.classList.add('bg-green-500', 'border-green-500');
1637
+ setupElements.env.innerHTML = '<i class="fas fa-check text-white text-xs"></i>';
1638
+ document.getElementById('setupComplete').classList.remove('hidden');
1639
+ finishBtn.disabled = false;
1640
+ }, 5000);
1641
+
1642
+ finishBtn.addEventListener('click', () => {
1643
+ currentStep++;
1644
+ showStep(currentStep);
1645
+ });
1646
+ }
1647
+
1648
+ setupHelpBtn.addEventListener('click', () => {
1649
+ setupHelpModal.classList.remove('hidden');
1650
+ currentStep = 1;
1651
+ showStep(currentStep);
1652
+ });
1653
+
1654
+ closeSetupHelp.addEventListener('click', () => {
1655
+ setupHelpModal.classList.add('hidden');
1656
+ });
1657
+
1658
+ document.getElementById('finalCloseBtn').addEventListener('click', () => {
1659
+ localStorage.setItem('setupComplete', 'true');
1660
+ setupHelpModal.classList.add('hidden');
1661
+ alert('Setup completed successfully! You can run setup again anytime if needed.');
1662
+ });
1663
+
1664
+ window.addEventListener('click', (event) => {
1665
+ if (event.target === setupHelpModal) {
1666
+ setupHelpModal.classList.add('hidden');
1667
+ }
1668
+ });
1669
+ </script>
1670
+ <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=jjmandog/jshehrb" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
1671
+ </html>
prompts.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ Make a button so I can open my twilio console
2
+ After clicking the console button can you automatically sign me in with the account that was made for me
3
+ The setup wizard doesn’t work. Fix it
4
+ Remove the setup wizard. Then recode it and add again so it works properly . Also add another button that shows my username and password for my twilio account. If possible auto verify my add and Auth code in the settings
5
+ Remove the setup wizard. Then recode it and add again so it works properly . Also add another button that shows my username and password for my twilio account. If possible auto verify my add and Auth code in the settings
6
+ Remove all buttons except for settings. Then add a button opening the tullio token system with the account you made for this app