Oscarli commited on
Commit
a2fae39
Β·
verified Β·
1 Parent(s): 77214d3

Upload 2 files

Browse files
Files changed (2) hide show
  1. static/.DS_Store +0 -0
  2. static/index.html +1251 -0
static/.DS_Store ADDED
Binary file (6.15 kB). View file
 
static/index.html ADDED
@@ -0,0 +1,1251 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>CareerForge AI - Complete Career Platform</title>
7
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"></script>
8
+ <style>
9
+ /* Previous CSS styles remain the same */
10
+ :root {
11
+ --primary: #2563eb;
12
+ --primary-dark: #1d4ed8;
13
+ --secondary: #64748b;
14
+ --success: #10b981;
15
+ --warning: #f59e0b;
16
+ --error: #ef4444;
17
+ --background: #f8fafc;
18
+ --surface: #ffffff;
19
+ --text: #1e293b;
20
+ --text-light: #64748b;
21
+ }
22
+
23
+ * {
24
+ margin: 0;
25
+ padding: 0;
26
+ box-sizing: border-box;
27
+ }
28
+
29
+ body {
30
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
31
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
32
+ min-height: 100vh;
33
+ padding: 20px;
34
+ color: var(--text);
35
+ }
36
+
37
+ .container {
38
+ max-width: 1200px;
39
+ margin: 0 auto;
40
+ background: var(--surface);
41
+ border-radius: 20px;
42
+ box-shadow: 0 20px 40px rgba(0,0,0,0.1);
43
+ overflow: hidden;
44
+ }
45
+
46
+ .header {
47
+ background: linear-gradient(135deg, var(--primary), var(--primary-dark));
48
+ color: white;
49
+ padding: 40px;
50
+ text-align: center;
51
+ }
52
+
53
+ .header h1 {
54
+ font-size: 2.5em;
55
+ margin-bottom: 10px;
56
+ font-weight: 700;
57
+ }
58
+
59
+ .tabs {
60
+ display: flex;
61
+ background: var(--background);
62
+ border-bottom: 1px solid #e2e8f0;
63
+ overflow-x: auto;
64
+ }
65
+
66
+ .tab-button {
67
+ padding: 20px 30px;
68
+ background: none;
69
+ border: none;
70
+ font-size: 1.1em;
71
+ font-weight: 600;
72
+ color: var(--text-light);
73
+ cursor: pointer;
74
+ transition: all 0.3s ease;
75
+ white-space: nowrap;
76
+ border-bottom: 3px solid transparent;
77
+ }
78
+
79
+ .tab-button:hover {
80
+ color: var(--primary);
81
+ background: rgba(37, 99, 235, 0.05);
82
+ }
83
+
84
+ .tab-button.active {
85
+ color: var(--primary);
86
+ border-bottom-color: var(--primary);
87
+ background: white;
88
+ }
89
+
90
+ .tab-content {
91
+ display: none;
92
+ padding: 40px;
93
+ min-height: 600px;
94
+ }
95
+
96
+ .tab-content.active {
97
+ display: block;
98
+ animation: fadeIn 0.5s ease;
99
+ }
100
+
101
+ @keyframes fadeIn {
102
+ from { opacity: 0; transform: translateY(10px); }
103
+ to { opacity: 1; transform: translateY(0); }
104
+ }
105
+
106
+ .form-grid {
107
+ display: grid;
108
+ grid-template-columns: 1fr 1fr;
109
+ gap: 30px;
110
+ margin-bottom: 30px;
111
+ }
112
+
113
+ .form-section {
114
+ background: var(--surface);
115
+ padding: 30px;
116
+ border-radius: 15px;
117
+ border: 1px solid #e2e8f0;
118
+ }
119
+
120
+ .form-section h3 {
121
+ margin-bottom: 20px;
122
+ color: var(--primary);
123
+ font-size: 1.3em;
124
+ }
125
+
126
+ .form-group {
127
+ margin-bottom: 20px;
128
+ }
129
+
130
+ label {
131
+ display: block;
132
+ margin-bottom: 8px;
133
+ font-weight: 600;
134
+ color: var(--text);
135
+ }
136
+
137
+ input, select, textarea {
138
+ width: 100%;
139
+ padding: 12px 16px;
140
+ border: 2px solid #e2e8f0;
141
+ border-radius: 10px;
142
+ font-size: 1em;
143
+ transition: border-color 0.3s ease;
144
+ }
145
+
146
+ input:focus, select:focus, textarea:focus {
147
+ outline: none;
148
+ border-color: var(--primary);
149
+ }
150
+
151
+ textarea {
152
+ resize: vertical;
153
+ min-height: 100px;
154
+ }
155
+
156
+ .btn {
157
+ padding: 15px 30px;
158
+ border: none;
159
+ border-radius: 10px;
160
+ font-size: 1.1em;
161
+ font-weight: 600;
162
+ cursor: pointer;
163
+ transition: all 0.3s ease;
164
+ display: inline-flex;
165
+ align-items: center;
166
+ gap: 10px;
167
+ }
168
+
169
+ .btn-primary {
170
+ background: var(--primary);
171
+ color: white;
172
+ }
173
+
174
+ .btn-primary:hover {
175
+ background: var(--primary-dark);
176
+ transform: translateY(-2px);
177
+ }
178
+
179
+ .output-grid {
180
+ display: grid;
181
+ grid-template-columns: 1fr 1fr;
182
+ gap: 30px;
183
+ margin-top: 30px;
184
+ }
185
+
186
+ .output-box {
187
+ background: var(--surface);
188
+ border: 1px solid #e2e8f0;
189
+ border-radius: 15px;
190
+ padding: 25px;
191
+ min-height: 400px;
192
+ max-height: 600px;
193
+ overflow-y: auto;
194
+ }
195
+
196
+ .output-box h3 {
197
+ margin-bottom: 15px;
198
+ color: var(--primary);
199
+ display: flex;
200
+ align-items: center;
201
+ gap: 10px;
202
+ }
203
+
204
+ .resume-content {
205
+ line-height: 1.6;
206
+ }
207
+
208
+ .resume-content h1 {
209
+ color: var(--primary);
210
+ border-bottom: 3px solid var(--primary);
211
+ padding-bottom: 10px;
212
+ margin-bottom: 20px;
213
+ }
214
+
215
+ .match-score {
216
+ font-size: 2em;
217
+ font-weight: bold;
218
+ text-align: center;
219
+ margin: 20px 0;
220
+ padding: 20px;
221
+ border-radius: 10px;
222
+ background: linear-gradient(135deg, var(--success), #34d399);
223
+ color: white;
224
+ }
225
+
226
+ .action-buttons {
227
+ display: flex;
228
+ gap: 15px;
229
+ margin-top: 20px;
230
+ flex-wrap: wrap;
231
+ }
232
+
233
+ .question-item {
234
+ background: #f8fafc;
235
+ padding: 15px;
236
+ margin: 10px 0;
237
+ border-radius: 10px;
238
+ border-left: 4px solid var(--primary);
239
+ }
240
+
241
+ .skill-category {
242
+ margin: 20px 0;
243
+ padding: 15px;
244
+ background: #f0f9ff;
245
+ border-radius: 10px;
246
+ }
247
+
248
+ .salary-breakdown {
249
+ display: grid;
250
+ grid-template-columns: repeat(3, 1fr);
251
+ gap: 15px;
252
+ margin: 20px 0;
253
+ }
254
+
255
+ .salary-item {
256
+ text-align: center;
257
+ padding: 15px;
258
+ background: #f8fafc;
259
+ border-radius: 10px;
260
+ }
261
+
262
+ .salary-value {
263
+ font-size: 1.5em;
264
+ font-weight: bold;
265
+ color: var(--primary);
266
+ }
267
+
268
+ @media (max-width: 768px) {
269
+ .form-grid, .output-grid {
270
+ grid-template-columns: 1fr;
271
+ }
272
+ .salary-breakdown {
273
+ grid-template-columns: 1fr;
274
+ }
275
+ }
276
+ </style>
277
+ </head>
278
+ <body>
279
+ <div class="container">
280
+ <div class="header">
281
+ <h1>πŸš€ CareerForge AI</h1>
282
+ <p>Your All-in-One Intelligent Career Platform</p>
283
+
284
+ <!-- API Configuration -->
285
+ <div style="margin-top: 25px; background: rgba(255,255,255,0.1); padding: 15px; border-radius: 10px; max-width: 700px; margin-left: auto; margin-right: auto;">
286
+ <div style="font-size: 0.95em; opacity: 0.95; line-height: 1.5; text-align: center;">
287
+ πŸ’‘ This platform is powered by AI. All features are now active.
288
+ <span id="api-status" style="font-size: 1.2em; margin-left: 10px;">βšͺ</span>
289
+ </div>
290
+ </div>
291
+ </div>
292
+
293
+ <div class="tabs">
294
+ <button class="tab-button active" onclick="openTab('resume-tab')">🎯 Smart Resume</button>
295
+ <button class="tab-button" onclick="openTab('interview-tab')">πŸ’Ό Interview Coach</button>
296
+ <button class="tab-button" onclick="openTab('skills-tab')">πŸ“š Learning Path</button>
297
+ <button class="tab-button" onclick="openTab('coverletter-tab')">βœ‰οΈ Cover Letters</button>
298
+ <button class="tab-button" onclick="openTab('linkedin-tab')">πŸ’Ό LinkedIn</button>
299
+ <button class="tab-button" onclick="openTab('salary-tab')">πŸ’° Salary Intel</button>
300
+ </div>
301
+
302
+ <!-- Resume Optimizer Tab -->
303
+ <div id="resume-tab" class="tab-content active">
304
+ <div class="form-grid">
305
+ <div class="form-section">
306
+ <h3>πŸ‘€ Your Profile</h3>
307
+ <div class="form-group">
308
+ <label for="name">Full Name</label>
309
+ <input type="text" id="name" placeholder="John Doe">
310
+ </div>
311
+ <div class="form-group">
312
+ <label for="current-role">Current Role</label>
313
+ <input type="text" id="current-role" placeholder="Software Developer">
314
+ </div>
315
+ <div class="form-group">
316
+ <label for="experience">Years of Experience</label>
317
+ <input type="number" id="experience" placeholder="5">
318
+ </div>
319
+ <div class="form-group">
320
+ <label for="skills">Skills (comma separated)</label>
321
+ <textarea id="skills" placeholder="Python, Project Management, Data Analysis..."></textarea>
322
+ </div>
323
+ </div>
324
+
325
+ <div class="form-section">
326
+ <h3>🎯 Target Opportunity</h3>
327
+ <div class="form-group">
328
+ <label for="job-title">Desired Job Title</label>
329
+ <input type="text" id="job-title" placeholder="Senior Software Engineer">
330
+ </div>
331
+ <div class="form-group">
332
+ <label for="job-description">Job Description</label>
333
+ <textarea id="job-description" placeholder="Paste the job description here..."></textarea>
334
+ </div>
335
+ <div class="form-group">
336
+ <label for="company-name">Company Name</label>
337
+ <input type="text" id="company-name" placeholder="Tech Company Inc.">
338
+ </div>
339
+ </div>
340
+ </div>
341
+
342
+ <button class="btn btn-primary" onclick="generateResume()">πŸš€ Generate Optimized Resume</button>
343
+
344
+ <div class="output-grid">
345
+ <div class="output-box">
346
+ <h3>πŸ“„ AI-Optimized Resume</h3>
347
+ <div id="resume-output" class="resume-content"></div>
348
+ </div>
349
+ <div class="output-box">
350
+ <h3>πŸ“Š Matching Analysis</h3>
351
+ <div id="analysis-output"></div>
352
+ </div>
353
+ </div>
354
+
355
+ <div class="action-buttons">
356
+ <button class="btn btn-success" onclick="exportToPDF()">πŸ“₯ Export as PDF</button>
357
+ <button class="btn btn-secondary" onclick="copyToClipboard('resume-output')">πŸ“‹ Copy Text</button>
358
+ </div>
359
+ </div>
360
+
361
+ <!-- Interview Coach Tab -->
362
+ <div id="interview-tab" class="tab-content">
363
+ <div class="form-grid">
364
+ <div class="form-section">
365
+ <h3>🎯 Interview Setup</h3>
366
+ <div class="form-group">
367
+ <label for="interview-role">Target Role</label>
368
+ <input type="text" id="interview-role" placeholder="Senior Developer">
369
+ </div>
370
+ <div class="form-group">
371
+ <label for="interview-level">Experience Level</label>
372
+ <select id="interview-level">
373
+ <option value="entry">Entry Level</option>
374
+ <option value="mid">Mid Level</option>
375
+ <option value="senior">Senior Level</option>
376
+ <option value="lead">Lead/Manager</option>
377
+ </select>
378
+ </div>
379
+ <div class="form-group">
380
+ <label for="interview-skills">Key Skills to Test</label>
381
+ <textarea id="interview-skills" placeholder="Python, System Design, Leadership..."></textarea>
382
+ </div>
383
+ <button class="btn btn-primary" onclick="generateInterviewQuestions()">🎯 Generate Questions</button>
384
+ </div>
385
+
386
+ <div class="form-section">
387
+ <h3>πŸ’‘ Interview Results</h3>
388
+ <div id="interview-output"></div>
389
+ </div>
390
+ </div>
391
+ </div>
392
+
393
+ <!-- Learning Path Tab -->
394
+ <div id="skills-tab" class="tab-content">
395
+ <div class="form-grid">
396
+ <div class="form-section">
397
+ <h3>πŸ“š Skill Assessment</h3>
398
+ <div class="form-group">
399
+ <label for="current-skills">Current Skills</label>
400
+ <textarea id="current-skills" placeholder="List your current skills..."></textarea>
401
+ </div>
402
+ <div class="form-group">
403
+ <label for="target-role-learning">Target Role</label>
404
+ <input type="text" id="target-role-learning" placeholder="AI Engineer">
405
+ </div>
406
+ <div class="form-group">
407
+ <label for="timeline">Learning Timeline</label>
408
+ <select id="timeline">
409
+ <option value="3">3 months</option>
410
+ <option value="6">6 months</option>
411
+ <option value="12">1 year</option>
412
+ </select>
413
+ </div>
414
+ <button class="btn btn-primary" onclick="generateLearningPath()">πŸ› οΈ Create Learning Path</button>
415
+ </div>
416
+
417
+ <div class="form-section">
418
+ <h3>🎯 Personalized Roadmap</h3>
419
+ <div id="learning-output"></div>
420
+ </div>
421
+ </div>
422
+ </div>
423
+
424
+ <!-- Cover Letter Tab -->
425
+ <div id="coverletter-tab" class="tab-content">
426
+ <div class="form-grid">
427
+ <div class="form-section">
428
+ <h3>βœ‰οΈ Letter Details</h3>
429
+ <div class="form-group">
430
+ <label for="cl-company">Company Name</label>
431
+ <input type="text" id="cl-company" placeholder="Tech Innovations Inc.">
432
+ </div>
433
+ <div class="form-group">
434
+ <label for="cl-role">Job Title</label>
435
+ <input type="text" id="cl-role" placeholder="Senior Developer">
436
+ </div>
437
+ <div class="form-group">
438
+ <label for="cl-highlight">Key Achievement to Highlight</label>
439
+ <textarea id="cl-highlight" placeholder="Describe your most relevant achievement..."></textarea>
440
+ </div>
441
+ <div class="form-group">
442
+ <label for="cl-tone">Writing Tone</label>
443
+ <select id="cl-tone">
444
+ <option value="professional">Professional</option>
445
+ <option value="enthusiastic">Enthusiastic</option>
446
+ <option value="formal">Formal</option>
447
+ </select>
448
+ </div>
449
+ <button class="btn btn-primary" onclick="generateCoverLetter()">✨ Generate Cover Letter</button>
450
+ </div>
451
+
452
+ <div class="form-section">
453
+ <h3>πŸ“ Custom Cover Letter</h3>
454
+ <div id="coverletter-output"></div>
455
+ </div>
456
+ </div>
457
+ </div>
458
+
459
+ <!-- LinkedIn Optimizer Tab -->
460
+ <div id="linkedin-tab" class="tab-content">
461
+ <div class="form-grid">
462
+ <div class="form-section">
463
+ <h3>πŸ’Ό Profile Information</h3>
464
+ <div class="form-group">
465
+ <label for="li-headline">Current Headline</label>
466
+ <input type="text" id="li-headline" placeholder="Software Developer at Current Company">
467
+ </div>
468
+ <div class="form-group">
469
+ <label for="li-about">Current About Section</label>
470
+ <textarea id="li-about" placeholder="Your current LinkedIn summary..."></textarea>
471
+ </div>
472
+ <div class="form-group">
473
+ <label for="li-target">Target Industry/Roles</label>
474
+ <input type="text" id="li-target" placeholder="AI Engineering, Tech Leadership">
475
+ </div>
476
+ <button class="btn btn-primary" onclick="optimizeLinkedIn()">πŸš€ Optimize Profile</button>
477
+ </div>
478
+
479
+ <div class="form-section">
480
+ <h3>🎯 Optimized Results</h3>
481
+ <div id="linkedin-output"></div>
482
+ </div>
483
+ </div>
484
+ </div>
485
+
486
+ <!-- Salary Intelligence Tab -->
487
+ <div id="salary-tab" class="tab-content">
488
+ <div class="form-grid">
489
+ <div class="form-section">
490
+ <h3>πŸ’° Salary Research</h3>
491
+ <div class="form-group">
492
+ <label for="salary-role">Job Title</label>
493
+ <input type="text" id="salary-role" placeholder="Senior Software Engineer">
494
+ </div>
495
+ <div class="form-group">
496
+ <label for="salary-location">Location</label>
497
+ <input type="text" id="salary-location" placeholder="San Francisco, CA or Remote">
498
+ </div>
499
+ <div class="form-group">
500
+ <label for="salary-experience">Years of Experience</label>
501
+ <input type="number" id="salary-experience" placeholder="5">
502
+ </div>
503
+ <div class="form-group">
504
+ <label for="salary-company">Company Size</label>
505
+ <select id="salary-company">
506
+ <option value="startup">Startup (1-50)</option>
507
+ <option value="small">Small (51-200)</option>
508
+ <option value="medium">Medium (201-1000)</option>
509
+ <option value="large">Large (1001-5000)</option>
510
+ <option value="enterprise">Enterprise (5000+)</option>
511
+ </select>
512
+ </div>
513
+ <button class="btn btn-primary" onclick="analyzeSalary()">πŸ’‘ Get Salary Insights</button>
514
+ </div>
515
+
516
+ <div class="form-section">
517
+ <h3>πŸ“Š Market Intelligence</h3>
518
+ <div id="salary-output"></div>
519
+ </div>
520
+ </div>
521
+ </div>
522
+ </div>
523
+
524
+ <script>
525
+ // Career Database - Real data for all functionalities
526
+ const careerDatabase = {
527
+ skillsRoadmaps: {
528
+ 'AI Engineer': {
529
+ foundation: ['Python Programming', 'Linear Algebra', 'Statistics & Probability', 'Data Structures'],
530
+ intermediate: ['Machine Learning Fundamentals', 'Deep Learning', 'Data Preprocessing', 'Model Evaluation'],
531
+ advanced: ['Neural Networks', 'Natural Language Processing', 'Computer Vision', 'Reinforcement Learning'],
532
+ tools: ['TensorFlow', 'PyTorch', 'scikit-learn', 'Keras', 'OpenCV'],
533
+ projects: ['Sentiment Analysis Model', 'Image Classification System', 'Recommendation Engine']
534
+ },
535
+ 'Full Stack Developer': {
536
+ foundation: ['HTML/CSS/JavaScript', 'Git Version Control', 'Basic Algorithms', 'Responsive Design'],
537
+ intermediate: ['React/Vue.js', 'Node.js/Express', 'Database Design', 'RESTful APIs'],
538
+ advanced: ['System Design', 'DevOps & CI/CD', 'Cloud Services (AWS/Azure)', 'Microservices'],
539
+ tools: ['Docker', 'MongoDB/PostgreSQL', 'AWS Services', 'Jenkins'],
540
+ projects: ['E-commerce Platform', 'Social Media App', 'Real-time Chat Application']
541
+ },
542
+ 'Data Scientist': {
543
+ foundation: ['Python/R Programming', 'SQL Databases', 'Statistics', 'Data Visualization'],
544
+ intermediate: ['Machine Learning', 'Experimental Design', 'Feature Engineering', 'Data Wrangling'],
545
+ advanced: ['Big Data Technologies', 'Advanced ML Models', 'Business Intelligence', 'MLOps'],
546
+ tools: ['Pandas/NumPy', 'Tableau/PowerBI', 'Apache Spark', 'Jupyter Notebooks'],
547
+ projects: ['Predictive Analytics Model', 'Customer Segmentation', 'Sales Forecasting']
548
+ },
549
+ 'Product Manager': {
550
+ foundation: ['Market Research', 'User Stories', 'Agile Methodology', 'Basic Analytics'],
551
+ intermediate: ['Product Strategy', 'Roadmap Planning', 'Stakeholder Management', 'A/B Testing'],
552
+ advanced: ['Go-to-Market Strategy', 'Product Metrics', 'Team Leadership', 'Business Case Development'],
553
+ tools: ['Jira/Asana', 'Figma', 'Google Analytics', 'SQL for PMs'],
554
+ projects: ['Product Launch Plan', 'Feature Prioritization Framework', 'User Research Report']
555
+ }
556
+ },
557
+
558
+ interviewQuestions: {
559
+ technical: {
560
+ entry: [
561
+ "Explain the difference between let, const, and var in JavaScript",
562
+ "What is a REST API and how does it work?",
563
+ "Describe your experience with version control systems like Git",
564
+ "How would you approach debugging a software issue?"
565
+ ],
566
+ mid: [
567
+ "Explain system design principles for a scalable application",
568
+ "How do you ensure code quality and maintainability?",
569
+ "Describe your experience with database optimization",
570
+ "What's your approach to testing and test-driven development?"
571
+ ],
572
+ senior: [
573
+ "Design a system that handles 1 million concurrent users",
574
+ "How do you mentor junior developers and improve team processes?",
575
+ "Explain your strategy for technical debt management",
576
+ "Describe a complex technical challenge you solved and your approach"
577
+ ],
578
+ lead: [
579
+ "How do you align technical strategy with business goals?",
580
+ "Describe your experience building and leading engineering teams",
581
+ "What's your approach to incident management and post-mortems?",
582
+ "How do you handle technical disagreements within your team?"
583
+ ]
584
+ },
585
+ behavioral: [
586
+ "Tell me about a time you faced a significant challenge and how you overcame it",
587
+ "Describe a situation where you had to work with a difficult team member",
588
+ "How do you handle tight deadlines and competing priorities?",
589
+ "Share an example of a project failure and what you learned from it"
590
+ ]
591
+ },
592
+
593
+ salaryData: {
594
+ 'Software Engineer': { base: 120000, bonus: 0.15, equity: 0.10 },
595
+ 'Senior Software Engineer': { base: 150000, bonus: 0.20, equity: 0.15 },
596
+ 'Data Scientist': { base: 130000, bonus: 0.15, equity: 0.12 },
597
+ 'AI Engineer': { base: 160000, bonus: 0.20, equity: 0.18 },
598
+ 'Product Manager': { base: 140000, bonus: 0.25, equity: 0.15 },
599
+ 'Full Stack Developer': { base: 125000, bonus: 0.15, equity: 0.10 }
600
+ },
601
+
602
+ locationMultipliers: {
603
+ 'San Francisco, CA': 1.4,
604
+ 'New York, NY': 1.35,
605
+ 'Seattle, WA': 1.25,
606
+ 'Boston, MA': 1.2,
607
+ 'Austin, TX': 1.1,
608
+ 'Remote': 0.95,
609
+ 'Default': 1.0
610
+ },
611
+
612
+ companyMultipliers: {
613
+ 'startup': { base: 0.9, equity: 2.0 },
614
+ 'small': { base: 1.0, equity: 1.5 },
615
+ 'medium': { base: 1.1, equity: 1.2 },
616
+ 'large': { base: 1.2, equity: 1.0 },
617
+ 'enterprise': { base: 1.3, equity: 0.8 }
618
+ }
619
+ };
620
+
621
+ // Tab navigation
622
+ function openTab(tabName) {
623
+ const tabContents = document.getElementsByClassName('tab-content');
624
+ const tabButtons = document.getElementsByClassName('tab-button');
625
+
626
+ for (let i = 0; i < tabContents.length; i++) {
627
+ tabContents[i].classList.remove('active');
628
+ tabButtons[i].classList.remove('active');
629
+ }
630
+
631
+ document.getElementById(tabName).classList.add('active');
632
+ event.currentTarget.classList.add('active');
633
+ }
634
+
635
+ // 1. RESUME OPTIMIZER - ACTUAL FUNCTIONALITY
636
+ async function generateResume() {
637
+ const name = document.getElementById('name').value || 'Your Name';
638
+ const currentRole = document.getElementById('current-role').value || 'Professional';
639
+ const experience = document.getElementById('experience').value || '3';
640
+ const skills = document.getElementById('skills').value || 'Various skills';
641
+ const jobTitle = document.getElementById('job-title').value || 'Target Role';
642
+ const company = document.getElementById('company-name').value || 'Target Company';
643
+ const jobDescription = document.getElementById('job-description').value;
644
+
645
+ // Show loading state
646
+ const resumeOutput = document.getElementById('resume-output');
647
+ const analysisOutput = document.getElementById('analysis-output');
648
+ resumeOutput.innerHTML = '<p>πŸš€ Generating AI-Optimized Resume...</p>';
649
+ analysisOutput.innerHTML = '<p>πŸ“Š Analyzing your profile against the job...</p>';
650
+
651
+ // Construct the prompt for the LLM
652
+ const prompt = `Based on the following information, generate an optimized resume and a matching analysis:
653
+
654
+ **User Profile:**
655
+ - Name: ${name}
656
+ - Current Position: ${currentRole}
657
+ - Years of Experience: ${experience} years
658
+ - Skills: ${skills}
659
+
660
+ **Target Position:**
661
+ - Job Title: ${jobTitle}
662
+ - Company Name: ${company}
663
+ - Job Description: ${jobDescription}
664
+
665
+ Please return a JSON object strictly containing two keys:
666
+ 1. "resume" - The complete resume content (in HTML format), including:
667
+ - Professional Summary (highlighting the match with the position)
668
+ - Core Skills (sorted by importance)
669
+ - Work Experience (can generate examples based on common experience, emphasizing achievements relevant to the target position)
670
+ - Education
671
+
672
+ 2. "analysis" - The matching analysis (in HTML format), including:
673
+ - A match score (0-100%) displayed in a styled div
674
+ - A list of matched skills
675
+ - 3-5 specific suggestions for improvement
676
+
677
+ JSON format example:
678
+ {
679
+ "resume": "<h1>Name</h1><h2>Professional Summary</h2><p>...</p>",
680
+ "analysis": "<div class='match-score' style='...'>85%</div><h3>Matched Skills</h3>..."
681
+ }`;
682
+
683
+ const systemPrompt = 'You are a professional career consultant and resume expert. Please strictly follow the JSON format for the response, ensuring the HTML is well-formed and professional.';
684
+
685
+ try {
686
+ // Call the LLM API
687
+ const aiReply = await callLLM(prompt, systemPrompt);
688
+ const llmResponse = parseAIResponse(aiReply);
689
+
690
+ if (llmResponse && llmResponse.resume && llmResponse.analysis) {
691
+ resumeOutput.innerHTML = llmResponse.resume;
692
+ analysisOutput.innerHTML = llmResponse.analysis;
693
+ } else {
694
+ // ε¦‚ζžœθ§£ζžε€±θ΄₯οΌŒη›΄ζŽ₯显瀺 AI ηš„ε›žε€
695
+ resumeOutput.innerHTML = `<div style="line-height: 1.6;">${aiReply.replace(/\n/g, '<br>')}</div>`;
696
+ analysisOutput.innerHTML = '<p>βœ… Resume generated (format may need adjustment)</p>';
697
+ }
698
+ } catch (error) {
699
+ resumeOutput.innerHTML = '<p style="color: red;">❌ Generation failed, please check API configuration</p>';
700
+ analysisOutput.innerHTML = '<p style="color: red;">❌ Generation failed</p>';
701
+ }
702
+ }
703
+
704
+ // 2. INTERVIEW COACH - AI-POWERED FUNCTIONALITY
705
+ async function generateInterviewQuestions() {
706
+ const role = document.getElementById('interview-role').value || 'Developer';
707
+ const level = document.getElementById('interview-level').value;
708
+ const skills = document.getElementById('interview-skills').value || 'Relevant Skills';
709
+
710
+ const levelText = {
711
+ 'entry': 'Entry Level',
712
+ 'mid': 'Mid Level',
713
+ 'senior': 'Senior Level',
714
+ 'lead': 'Lead/Manager'
715
+ }[level];
716
+
717
+ const outputDiv = document.getElementById('interview-output');
718
+ outputDiv.innerHTML = '<p>πŸ€” AI is generating customized interview questions for you...</p>';
719
+
720
+ const prompt = `As a senior interviewer and career consultant, generate comprehensive interview preparation materials for the following position:
721
+
722
+ **Position Information:**
723
+ - Position: ${role}
724
+ - Level: ${levelText}
725
+ - Key Skills: ${skills}
726
+
727
+ Please generate the following content (using HTML format):
728
+
729
+ 1. **Technical Interview Questions** (8-10 questions)
730
+ - Technical depth appropriate for the position level
731
+ - Covering the listed key skills
732
+ - Including system design, algorithms, best practices, etc.
733
+
734
+ 2. **Behavioral Interview Questions** (5-6 questions)
735
+ - Questions suitable for the STAR method
736
+ - Targeting leadership/collaboration skills for this level
737
+ - Scenarios for conflict resolution and challenges
738
+
739
+ 3. **For each question, provide:**
740
+ - The question itself
741
+ - The competencies the interviewer wants to assess
742
+ - Answering strategy/key points (brief)
743
+
744
+ 4. **Interview Preparation Advice**
745
+ - Key preparation points for this position
746
+ - Explanation of the STAR method
747
+ - 3-5 practical tips
748
+
749
+ Please use the following HTML structure:
750
+ - Use <div class="skill-category"> to wrap each major category
751
+ - Use <div class="question-item"> to wrap each question
752
+ - Use <div class="tips"> to wrap preparation advice`;
753
+
754
+ const systemPrompt = 'You are an experienced interviewer and career mentor, skilled at designing in-depth interview questions. Please provide practical, professional interview preparation materials.';
755
+
756
+ try {
757
+ const aiReply = await callLLM(prompt, systemPrompt);
758
+ // η›΄ζŽ₯使用 AI θΏ”ε›žηš„ HTML
759
+ outputDiv.innerHTML = aiReply;
760
+ } catch (error) {
761
+ outputDiv.innerHTML = '<p style="color: red;">❌ Generation failed, please check API configuration</p>';
762
+ }
763
+ }
764
+
765
+ // 3. LEARNING PATH - AI-POWERED FUNCTIONALITY
766
+ async function generateLearningPath() {
767
+ const currentSkills = document.getElementById('current-skills').value || 'Basic Skills';
768
+ const targetRole = document.getElementById('target-role-learning').value || 'Full Stack Developer';
769
+ const timeline = parseInt(document.getElementById('timeline').value);
770
+
771
+ const outputDiv = document.getElementById('learning-output');
772
+ outputDiv.innerHTML = '<p>πŸ“š AI is planning a personalized learning path for you...</p>';
773
+
774
+ const prompt = `As a senior career mentor and skill development expert, create a detailed learning path for the following situation:
775
+
776
+ **Current Status:**
777
+ - Existing Skills: ${currentSkills}
778
+ - Target Position: ${targetRole}
779
+ - Learning Timeline: ${timeline} months
780
+
781
+ Please generate a detailed learning path plan (in HTML format), including:
782
+
783
+ 1. **Skill Gap Analysis**
784
+ - Skills already possessed (mark with βœ…)
785
+ - Skills that need to be learned (mark with πŸ“š)
786
+ - Prioritization of skills
787
+
788
+ 2. **Phased Learning Plan**
789
+ Divided into 3 phases over ${timeline} months:
790
+ - **Foundation Phase** (first ${Math.floor(timeline/3)} months): Essential basic knowledge and tools
791
+ - **Intermediate Phase** (middle ${Math.floor(timeline/3)} months): Deepening core skills
792
+ - **Advanced Phase** (last ${Math.ceil(timeline/3)} months): Advanced skills and project practice
793
+
794
+ Each phase includes:
795
+ - Specific learning content
796
+ - Recommended types of learning resources
797
+ - Time allocation suggestions
798
+
799
+ 3. **Practical Project Suggestions**
800
+ - 3-5 progressive projects
801
+ - Skill application points for each project
802
+ - Increasing project difficulty
803
+
804
+ 4. **Learning Resource Recommendations**
805
+ - Online course platforms
806
+ - Book recommendations
807
+ - Practice platforms
808
+
809
+ 5. **Weekly Learning Plan**
810
+ - Suggested weekly study hours
811
+ - Learning methods (theory vs. practice ratio)
812
+ - Milestone checkpoints
813
+
814
+ Please use the following HTML structure:
815
+ - <div class="skill-category"> to wrap each learning phase
816
+ - Use colored divs to mark skill status: #d1fae5 for mastered, #fef3c7 for to-learn
817
+ - <div class="tips"> to wrap learning advice and resources`;
818
+
819
+ const systemPrompt = 'You are an experienced career mentor and learning planner, skilled at creating personalized, actionable learning paths. Please ensure the advice is specific and actionable.';
820
+
821
+ try {
822
+ const aiReply = await callLLM(prompt, systemPrompt);
823
+ outputDiv.innerHTML = aiReply;
824
+ } catch (error) {
825
+ outputDiv.innerHTML = '<p style="color: red;">❌ Generation failed, please check API configuration</p>';
826
+ }
827
+ }
828
+
829
+ // 4. COVER LETTER GENERATOR - AI-POWERED FUNCTIONALITY
830
+ async function generateCoverLetter() {
831
+ const company = document.getElementById('cl-company').value || 'Target Company';
832
+ const role = document.getElementById('cl-role').value || 'Target Role';
833
+ const achievement = document.getElementById('cl-highlight').value || 'My work experience and achievements';
834
+ const tone = document.getElementById('cl-tone').value;
835
+
836
+ const toneText = {
837
+ 'professional': 'Professional',
838
+ 'enthusiastic': 'Enthusiastic',
839
+ 'formal': 'Formal'
840
+ }[tone];
841
+
842
+ const outputDiv = document.getElementById('coverletter-output');
843
+ outputDiv.innerHTML = '<p>✍️ AI is writing a personalized cover letter for you...</p>';
844
+
845
+ const prompt = `As a professional cover letter writing expert, write a high-quality cover letter for the following job application scenario:
846
+
847
+ **Application Information:**
848
+ - Target Company: ${company}
849
+ - Position Applied For: ${role}
850
+ - Core Achievement: ${achievement}
851
+ - Writing Style: ${toneText}
852
+
853
+ Please generate a complete cover letter (in HTML format), including:
854
+
855
+ 1. **Salutation** (choose an appropriate opening based on the style)
856
+
857
+ 2. **Opening Paragraph**
858
+ - Express interest in the position
859
+ - Briefly explain why you are applying
860
+ - Reflect the ${toneText} style
861
+
862
+ 3. **Body Paragraphs** (2-3 paragraphs)
863
+ - First paragraph: Elaborate on the core achievement, supported by specific data and results
864
+ - Second paragraph: Explain why you are a good fit for ${company} and ${role}
865
+ - Third paragraph (optional): Show your knowledge and appreciation of the company
866
+
867
+ 4. **Closing Paragraph**
868
+ - Reiterate your interest and value
869
+ - Politely request an interview opportunity
870
+ - Thank the reader
871
+
872
+ 5. **Signature**
873
+ - Include a polite closing
874
+ - Placeholders for [Name], [Phone], [Email]
875
+
876
+ 6. **Customization Suggestions**
877
+ After the cover letter, add a <div class="tips"> containing 3-5 specific optimization suggestions
878
+
879
+ Note:
880
+ - Use <p> tags for paragraphs
881
+ - Line height 1.8, font Arial
882
+ - Maintain a consistent ${toneText} tone
883
+ - Avoid being too generic, be as specific as possible
884
+ - Keep the length moderate (300-400 words)`;
885
+
886
+ const systemPrompt = 'You are an experienced career consultant and expert cover letter writer. Please write a professional, persuasive, and personalized cover letter.';
887
+
888
+ try {
889
+ const aiReply = await callLLM(prompt, systemPrompt);
890
+ outputDiv.innerHTML = aiReply;
891
+ } catch (error) {
892
+ outputDiv.innerHTML = '<p style="color: red;">❌ Generation failed, please check API configuration</p>';
893
+ }
894
+ }
895
+
896
+ // 5. LINKEDIN OPTIMIZER - AI-POWERED FUNCTIONALITY
897
+ async function optimizeLinkedIn() {
898
+ const headline = document.getElementById('li-headline').value || 'Current Professional';
899
+ const about = document.getElementById('li-about').value || 'Experienced professional seeking new opportunities';
900
+ const target = document.getElementById('li-target').value || 'Technology field';
901
+
902
+ const outputDiv = document.getElementById('linkedin-output');
903
+ outputDiv.innerHTML = '<p>πŸ’Ό AI is optimizing your LinkedIn profile...</p>';
904
+
905
+ const prompt = `As a LinkedIn profile optimization expert and personal branding consultant, optimize the following LinkedIn profile:
906
+
907
+ **Current Profile:**
908
+ - Current Headline: ${headline}
909
+ - Current About Section: ${about}
910
+ - Target Industry/Roles: ${target}
911
+
912
+ Please generate an optimized LinkedIn profile (in HTML format), including:
913
+
914
+ 1. **Optimized Headline**
915
+ - Include job title, professional field, key skills
916
+ - Use | or β€’ as separators
917
+ - Make full use of the 220-character limit
918
+ - Include search keywords
919
+ - Display in <div class="question-item" style="font-size: 1.1em; font-weight: bold;">
920
+
921
+ 2. **Optimized About Section**
922
+ - Opening: An engaging self-introduction
923
+ - Core Competencies: 3-5 professional areas
924
+ - Skills List: Categorized (core competencies, technical skills, etc.)
925
+ - Career Highlights: 2-3 quantifiable achievements
926
+ - Closing: Open to opportunities and contact information
927
+ - Use <p> and <strong> tags
928
+ - Line height 1.6
929
+
930
+ 3. **Recommended Hashtags**
931
+ - 8-10 relevant industry hashtags
932
+ - Format: #hashtag
933
+
934
+ 4. **Optimization Suggestions**
935
+ Use <div class="tips"> to include:
936
+ - Suggestions for optimizing the skills section
937
+ - Content publishing strategy
938
+ - Networking expansion advice
939
+ - 5-7 practical tips
940
+
941
+ Note:
942
+ - Emphasize keywords related to ${target}
943
+ - Use industry-specific professional terminology
944
+ - Reflect personal brand and value
945
+ - SEO-friendly (to be easily found by search)
946
+ `;
947
+
948
+ const systemPrompt = 'You are a LinkedIn optimization expert and personal branding consultant, skilled at creating professional and attractive LinkedIn profiles.';
949
+
950
+ try {
951
+ const aiReply = await callLLM(prompt, systemPrompt);
952
+ outputDiv.innerHTML = aiReply;
953
+ } catch (error) {
954
+ outputDiv.innerHTML = '<p style="color: red;">❌ Generation failed, please check API configuration</p>';
955
+ }
956
+ }
957
+
958
+ // 6. SALARY INTELLIGENCE - AI-ENHANCED FUNCTIONALITY
959
+ async function analyzeSalary() {
960
+ const role = document.getElementById('salary-role').value || 'Software Engineer';
961
+ const location = document.getElementById('salary-location').value || 'San Francisco, CA';
962
+ const experience = parseInt(document.getElementById('salary-experience').value) || 3;
963
+ const companySize = document.getElementById('salary-company').value;
964
+
965
+ const outputDiv = document.getElementById('salary-output');
966
+ outputDiv.innerHTML = '<p>πŸ’° AI is analyzing market salary data...</p>';
967
+
968
+ const companySizeText = {
969
+ 'startup': 'Startup (1-50 employees)',
970
+ 'small': 'Small (51-200 employees)',
971
+ 'medium': 'Medium (201-1000 employees)',
972
+ 'large': 'Large (1001-5000 employees)',
973
+ 'enterprise': 'Enterprise (5000+ employees)'
974
+ }[companySize];
975
+
976
+ const prompt = `As a salary negotiation expert and market analyst, analyze the salary for the following position:
977
+
978
+ **Position Information:**
979
+ - Job Title: ${role}
980
+ - Location: ${location}
981
+ - Years of Experience: ${experience} years
982
+ - Company Size: ${companySizeText}
983
+
984
+ Please provide a detailed salary analysis report (in HTML format), including:
985
+
986
+ 1. **Salary Estimation**
987
+ Create 3 <div class="salary-item"> cards showing:
988
+ - Base Salary (annual range: low-average-high)
989
+ - Annual Bonus (as a percentage of base salary)
990
+ - Equity/RSUs (estimated value vesting over 4 years)
991
+
992
+ Each card format:
993
+ \
994
+ <div class="salary-item">
995
+ <div class="salary-value">$XXX,XXX</div>
996
+ <div>Item Name</div>
997
+ <small>Additional Info</small>
998
+ </div>
999
+ \
1000
+
1001
+ 2. **Total Compensation**
1002
+ Display using the following style:
1003
+ \
1004
+ <div class="match-score" style="background: linear-gradient(135deg, #f59e0b, #fbbf24);">
1005
+ Total Compensation: $XXX,XXX/year
1006
+ </div>
1007
+ \
1008
+
1009
+ 3. **Market Positioning Analysis**
1010
+ Include in a <div class="skill-category">:
1011
+ - Geographic Impact (${location} compared to national average)
1012
+ - Experience Premium (${experience} years vs. new graduate)
1013
+ - Company Size Impact (trade-off between base salary vs. equity)
1014
+ - Industry Comparison
1015
+
1016
+ 4. **Negotiation Strategy**
1017
+ Provide in a <div class="tips">:
1018
+ - Target salary range (considering a 10-15% negotiation buffer)
1019
+ - Equity negotiation advice
1020
+ - Benefits considerations
1021
+ - 5-7 practical negotiation tips
1022
+ - Market trend insights
1023
+
1024
+ Notes:
1025
+ - All amounts should use USD ($) and thousand separators
1026
+ - Salary data should be current for 2024-2025 market conditions
1027
+ - Consider the cost of living in ${location}
1028
+ - Differentiate salary structures for different company sizes
1029
+ - The advice given should be specific and actionable
1030
+
1031
+ Add a title before the salary cards:
1032
+ <h4>πŸ’° Salary Analysis: ${role}</h4>
1033
+ <div class="salary-breakdown">
1034
+ [three salary-item cards]
1035
+ </div>`;
1036
+
1037
+ const systemPrompt = 'You are a salary negotiation expert and market analyst, specializing in the tech industry compensation structure. Please provide accurate, practical salary analysis and negotiation advice.';
1038
+
1039
+
1040
+ try {
1041
+ const aiReply = await callLLM(prompt, systemPrompt);
1042
+ outputDiv.innerHTML = aiReply;
1043
+ } catch (error) {
1044
+ outputDiv.innerHTML = '<p style="color: red;">❌ Generation failed, please check API configuration</p>';
1045
+ }
1046
+ }
1047
+
1048
+ // UTILITY FUNCTIONS
1049
+ function extractKeywords(text) {
1050
+ if (!text) return ['various', 'skills', 'experience'];
1051
+ const commonWords = ['the', 'a', 'an', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for', 'of', 'with', 'by'];
1052
+ return text.toLowerCase()
1053
+ .replace(/[^\w\s]/g, '')
1054
+ .split(/\s+/)
1055
+ .filter(word => word.length > 3 && !commonWords.includes(word))
1056
+ .slice(0, 15);
1057
+ }
1058
+
1059
+ function generateProfessionalSummary(name, currentRole, experience, jobTitle, company, matchedSkills) {
1060
+ return `Accomplished ${currentRole} with ${experience} years of experience seeking ${jobTitle} position at ${company}. Proven expertise in ${matchedSkills.slice(0,3).join(', ')} with track record of delivering innovative solutions and driving business growth. Strong background in full project lifecycle management and cross-functional collaboration.`;
1061
+ }
1062
+
1063
+ function getSkillDescription(skill) {
1064
+ const descriptions = {
1065
+ 'python': 'Python programming and development',
1066
+ 'javascript': 'JavaScript and modern frameworks',
1067
+ 'react': 'React.js and frontend development',
1068
+ 'node': 'Node.js and backend services',
1069
+ 'aws': 'Amazon Web Services cloud platform',
1070
+ 'docker': 'Containerization and DevOps',
1071
+ 'machine learning': 'ML algorithms and model development',
1072
+ 'data analysis': 'Data processing and insights generation',
1073
+ 'project management': 'Project planning and execution',
1074
+ 'leadership': 'Team leadership and mentorship'
1075
+ };
1076
+ return descriptions[skill.toLowerCase()] || 'relevant professional skill';
1077
+ }
1078
+
1079
+ function getScoreColor(score) {
1080
+ if (score >= 80) return 'linear-gradient(135deg, #10b981, #34d399)';
1081
+ if (score >= 60) return 'linear-gradient(135deg, #f59e0b, #fbbf24)';
1082
+ return 'linear-gradient(135deg, #ef4444, #f87171)';
1083
+ }
1084
+
1085
+ function exportToPDF() {
1086
+ const element = document.getElementById('resume-output');
1087
+ const opt = {
1088
+ margin: 10,
1089
+ filename: 'optimized_resume.pdf',
1090
+ image: { type: 'jpeg', quality: 0.98 },
1091
+ html2canvas: { scale: 2 },
1092
+ jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' }
1093
+ };
1094
+ html2pdf().set(opt).from(element).save();
1095
+ }
1096
+
1097
+ function copyToClipboard(elementId) {
1098
+ const element = document.getElementById(elementId);
1099
+ const text = element.innerText;
1100
+ navigator.clipboard.writeText(text).then(() => {
1101
+ alert('Copied to clipboard!');
1102
+ });
1103
+ }
1104
+
1105
+ // API CONFIGURATION - DeepSeek only
1106
+ const API_CONFIG = {
1107
+ model: 'deepseek-chat'
1108
+ };
1109
+
1110
+ // LLM API CALL - REAL IMPLEMENTATION
1111
+ async function callLLM(prompt, systemPrompt = 'You are a professional career consultant and AI assistant. Please provide valuable and practical advice.') {
1112
+ console.log("Sending request to HF Space backend...");
1113
+
1114
+ const statusIcon = document.getElementById('api-status');
1115
+
1116
+ // Set status to loading
1117
+ if (statusIcon) statusIcon.textContent = 'πŸ”„';
1118
+
1119
+ try {
1120
+ // This is the request body DeepSeek expects.
1121
+ // We build it here and send it to our backend proxy.
1122
+ const requestBody = {
1123
+ model: API_CONFIG.model,
1124
+ messages: [
1125
+ {
1126
+ role: 'system',
1127
+ content: systemPrompt
1128
+ },
1129
+ {
1130
+ role: 'user',
1131
+ content: prompt
1132
+ }
1133
+ ],
1134
+ temperature: 0.7,
1135
+ stream: false
1136
+ };
1137
+
1138
+ // Send the request to OUR backend endpoint '/call-deepseek'
1139
+ const response = await fetch('/call-deepseek', {
1140
+ method: 'POST',
1141
+ headers: {
1142
+ 'Content-Type': 'application/json',
1143
+ },
1144
+ body: JSON.stringify(requestBody) // Send the JSON payload
1145
+ });
1146
+
1147
+ if (!response.ok) {
1148
+ // Get error detail from our FastAPI backend
1149
+ const errorData = await response.json().catch(() => ({}));
1150
+ if (statusIcon) statusIcon.textContent = '❌';
1151
+ throw new Error(errorData.detail || `Server Error ${response.status}: ${response.statusText}`);
1152
+ }
1153
+
1154
+ // The 'data' is the full response from DeepSeek,
1155
+ // proxied through our backend
1156
+ const data = await response.json();
1157
+
1158
+ if (statusIcon) statusIcon.textContent = 'βœ…';
1159
+
1160
+ // Extract the AI reply as before
1161
+ let aiReply = data.choices[0].message.content;
1162
+ console.log("AI reply received, length:", aiReply.length);
1163
+
1164
+ return aiReply;
1165
+
1166
+ } catch (error) {
1167
+ if (statusIcon) statusIcon.textContent = '❌';
1168
+ console.error("API call error:", error);
1169
+
1170
+ alert(`❌ API call failed: ${error.message}\n\nPlease check the server status. If this persists, the app owner may need to check the Hugging Face logs.`);
1171
+
1172
+ throw error;
1173
+ }
1174
+ }
1175
+
1176
+ // 解析 JSON ε“εΊ”ηš„θΎ…εŠ©ε‡½ζ•°
1177
+ function parseAIResponse(aiReply) {
1178
+ try {
1179
+ // Clean up possible markdown code block markers
1180
+ let cleaned = aiReply.replace(/```json\n?/g, '').replace(/```\n?/g, '').trim();
1181
+ return JSON.parse(cleaned);
1182
+ } catch (parseError) {
1183
+ console.warn("JSON parsing failed, trying to extract:", parseError);
1184
+
1185
+ // Try to extract the JSON object
1186
+ const jsonMatch = aiReply.match(/\{[\s\S]*\}/);
1187
+ if (jsonMatch) {
1188
+ try {
1189
+ return JSON.parse(jsonMatch[0]);
1190
+ } catch (e) {
1191
+ console.error("Secondary parsing failed:", e);
1192
+ }
1193
+ }
1194
+
1195
+ // Return the original text
1196
+ return null;
1197
+ }
1198
+ }
1199
+
1200
+ // Initialize with sample data
1201
+ document.addEventListener('DOMContentLoaded', function() {
1202
+
1203
+ // Set status to 'Ready'
1204
+ const statusIcon = document.getElementById('api-status');
1205
+ if (statusIcon) statusIcon.textContent = 'βœ…';
1206
+
1207
+ // Set sample data for demonstration
1208
+ document.getElementById('name').value = 'Alexandra Chen';
1209
+ document.getElementById('current-role').value = 'Senior Frontend Developer';
1210
+ document.getElementById('experience').value = '6';
1211
+ document.getElementById('skills').value = 'React, TypeScript, JavaScript ES6+, Redux, Node.js, RESTful APIs, GraphQL, AWS, Docker, Webpack, Jest, Agile Methodology, Team Leadership, Code Review, Performance Optimization';
1212
+ document.getElementById('job-title').value = 'Principal Frontend Engineer';
1213
+ document.getElementById('company-name').value = 'InnovateTech Solutions';
1214
+ document.getElementById('job-description').value = `We are seeking an experienced Principal Frontend Engineer to lead our frontend development team. The ideal candidate will have 6+ years of experience building scalable web applications and a deep understanding of modern JavaScript frameworks.
1215
+
1216
+ Responsibilities:
1217
+ - Lead and mentor a team of 8 frontend developers
1218
+ - Architect and implement complex frontend systems using React and TypeScript
1219
+ - Collaborate with product managers and designers to define technical requirements
1220
+ - Optimize applications for maximum performance and scalability
1221
+ - Establish and enforce coding standards and best practices
1222
+ - Conduct code reviews and provide constructive feedback
1223
+ - Drive technical innovation and stay current with industry trends
1224
+
1225
+ Requirements:
1226
+ - 6+ years of professional frontend development experience
1227
+ - Expertise in React, TypeScript, and modern JavaScript
1228
+ - Strong experience with state management (Redux, Context API)
1229
+ - Proficiency in build tools (Webpack, Babel) and testing frameworks
1230
+ - Experience with cloud platforms (AWS, Azure, or GCP)
1231
+ - Excellent leadership and communication skills
1232
+ - Bachelor's degree in Computer Science or related field`;
1233
+
1234
+ document.getElementById('interview-role').value = 'Senior Full Stack Developer';
1235
+ document.getElementById('interview-skills').value = 'Technical: React, Node.js, PostgreSQL, AWS, Docker, Microservices, System Design\nBehavioral: Team Leadership, Project Management, Conflict Resolution, Stakeholder Communication\nArchitecture: API Design, Database Optimization, Cloud Infrastructure, CI/CD Pipelines';
1236
+ document.getElementById('current-skills').value = 'JavaScript (Advanced), React (Intermediate), HTML/CSS (Advanced), Node.js (Basic), MongoDB (Basic), Git (Intermediate), REST APIs (Intermediate)';
1237
+ document.getElementById('target-role-learning').value = 'Full Stack Developer';
1238
+ document.getElementById('cl-company').value = 'TechNova Innovations';
1239
+ document.getElementById('cl-role').value = 'Senior Software Engineer';
1240
+ document.getElementById('cl-highlight').value = 'Led the development of a customer dashboard that improved user engagement by 45% and reduced loading time by 60%. Implemented React with TypeScript and optimized API calls, resulting in a 30% decrease in server costs. Managed a team of 3 junior developers and introduced code review processes that reduced bugs in production by 25%.';
1241
+ document.getElementById('li-headline').value = 'Frontend Developer at Current Company';
1242
+ document.getElementById('li-about').value = `I'm a frontend developer with experience in React and JavaScript. I enjoy building web applications and solving technical challenges. Looking for new opportunities in tech.`;
1243
+ document.getElementById('li-target').value = 'Tech Leadership, Senior Engineering Roles, FinTech';
1244
+ document.getElementById('salary-role').value = 'Senior Software Engineer';
1245
+ document.getElementById('salary-location').value = 'San Francisco, CA';
1246
+ document.getElementById('salary-experience').value = '6';
1247
+ });
1248
+
1249
+ </script>
1250
+ </body>
1251
+ </html>