User290 commited on
Commit
bf2eb21
Β·
verified Β·
1 Parent(s): 0f4a912

Create index.html

Browse files
Files changed (1) hide show
  1. index.html +702 -0
index.html ADDED
@@ -0,0 +1,702 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>ResumeAI β€” Smart Resume Parser</title>
7
+ <link href="https://fonts.googleapis.com/css2?family=DM+Serif+Display:ital@0;1&family=DM+Mono:wght@400;500&family=Syne:wght@400;600;700;800&display=swap" rel="stylesheet"/>
8
+ <style>
9
+ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
10
+
11
+ :root {
12
+ --bg: #0a0a0f;
13
+ --surface: #12121a;
14
+ --card: #1a1a26;
15
+ --border: #2a2a3a;
16
+ --accent: #7c6aff;
17
+ --accent2: #ff6a8a;
18
+ --text: #e8e8f0;
19
+ --muted: #6b6b80;
20
+ --success: #4ade80;
21
+ --warning: #fbbf24;
22
+ }
23
+
24
+ html { scroll-behavior: smooth; }
25
+
26
+ body {
27
+ font-family: 'Syne', sans-serif;
28
+ background: var(--bg);
29
+ color: var(--text);
30
+ min-height: 100vh;
31
+ overflow-x: hidden;
32
+ }
33
+
34
+ /* BG Grid */
35
+ body::before {
36
+ content: '';
37
+ position: fixed;
38
+ inset: 0;
39
+ background-image:
40
+ linear-gradient(rgba(124,106,255,0.03) 1px, transparent 1px),
41
+ linear-gradient(90deg, rgba(124,106,255,0.03) 1px, transparent 1px);
42
+ background-size: 40px 40px;
43
+ pointer-events: none;
44
+ z-index: 0;
45
+ }
46
+
47
+ /* Glow orbs */
48
+ .orb {
49
+ position: fixed;
50
+ border-radius: 50%;
51
+ filter: blur(120px);
52
+ pointer-events: none;
53
+ z-index: 0;
54
+ opacity: 0.15;
55
+ }
56
+ .orb1 { width: 600px; height: 600px; background: var(--accent); top: -200px; left: -200px; }
57
+ .orb2 { width: 400px; height: 400px; background: var(--accent2); bottom: -100px; right: -100px; }
58
+
59
+ /* NAV */
60
+ nav {
61
+ position: relative;
62
+ z-index: 10;
63
+ display: flex;
64
+ align-items: center;
65
+ justify-content: space-between;
66
+ padding: 24px 48px;
67
+ border-bottom: 1px solid var(--border);
68
+ }
69
+
70
+ .logo {
71
+ font-family: 'DM Serif Display', serif;
72
+ font-size: 1.6rem;
73
+ background: linear-gradient(135deg, var(--accent), var(--accent2));
74
+ -webkit-background-clip: text;
75
+ -webkit-text-fill-color: transparent;
76
+ background-clip: text;
77
+ }
78
+
79
+ .api-badge {
80
+ display: flex;
81
+ align-items: center;
82
+ gap: 10px;
83
+ background: var(--card);
84
+ border: 1px solid var(--border);
85
+ border-radius: 8px;
86
+ padding: 8px 16px;
87
+ font-family: 'DM Mono', monospace;
88
+ font-size: 0.75rem;
89
+ color: var(--muted);
90
+ cursor: pointer;
91
+ transition: all 0.2s;
92
+ text-decoration: none;
93
+ }
94
+ .api-badge:hover { border-color: var(--accent); color: var(--accent); }
95
+ .api-badge .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--success); box-shadow: 0 0 6px var(--success); animation: pulse 2s infinite; }
96
+
97
+ @keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }
98
+
99
+ /* HERO */
100
+ .hero {
101
+ position: relative;
102
+ z-index: 1;
103
+ text-align: center;
104
+ padding: 80px 24px 60px;
105
+ }
106
+
107
+ .hero-tag {
108
+ display: inline-block;
109
+ background: rgba(124,106,255,0.1);
110
+ border: 1px solid rgba(124,106,255,0.3);
111
+ color: var(--accent);
112
+ font-size: 0.75rem;
113
+ font-weight: 700;
114
+ letter-spacing: 0.15em;
115
+ text-transform: uppercase;
116
+ padding: 6px 16px;
117
+ border-radius: 100px;
118
+ margin-bottom: 24px;
119
+ }
120
+
121
+ h1 {
122
+ font-family: 'DM Serif Display', serif;
123
+ font-size: clamp(2.5rem, 6vw, 4.5rem);
124
+ line-height: 1.1;
125
+ margin-bottom: 20px;
126
+ max-width: 700px;
127
+ margin-left: auto;
128
+ margin-right: auto;
129
+ }
130
+
131
+ h1 em {
132
+ font-style: italic;
133
+ background: linear-gradient(135deg, var(--accent), var(--accent2));
134
+ -webkit-background-clip: text;
135
+ -webkit-text-fill-color: transparent;
136
+ background-clip: text;
137
+ }
138
+
139
+ .hero-sub {
140
+ color: var(--muted);
141
+ font-size: 1.05rem;
142
+ max-width: 480px;
143
+ margin: 0 auto 48px;
144
+ line-height: 1.7;
145
+ font-weight: 400;
146
+ }
147
+
148
+ /* MAIN CARD */
149
+ .main-container {
150
+ position: relative;
151
+ z-index: 1;
152
+ max-width: 860px;
153
+ margin: 0 auto;
154
+ padding: 0 24px 80px;
155
+ }
156
+
157
+ /* API CONFIG SECTION */
158
+ .config-section {
159
+ background: var(--card);
160
+ border: 1px solid var(--border);
161
+ border-radius: 16px;
162
+ padding: 28px;
163
+ margin-bottom: 20px;
164
+ }
165
+
166
+ .section-header {
167
+ display: flex;
168
+ align-items: center;
169
+ gap: 10px;
170
+ margin-bottom: 20px;
171
+ }
172
+
173
+ .section-num {
174
+ width: 28px;
175
+ height: 28px;
176
+ border-radius: 50%;
177
+ background: linear-gradient(135deg, var(--accent), var(--accent2));
178
+ display: flex;
179
+ align-items: center;
180
+ justify-content: center;
181
+ font-size: 0.75rem;
182
+ font-weight: 800;
183
+ color: white;
184
+ flex-shrink: 0;
185
+ }
186
+
187
+ .section-title {
188
+ font-size: 0.9rem;
189
+ font-weight: 700;
190
+ letter-spacing: 0.05em;
191
+ text-transform: uppercase;
192
+ color: var(--text);
193
+ }
194
+
195
+ .section-hint {
196
+ font-size: 0.78rem;
197
+ color: var(--muted);
198
+ margin-left: auto;
199
+ }
200
+
201
+ .field-group { display: flex; flex-direction: column; gap: 6px; margin-bottom: 16px; }
202
+ .field-group:last-child { margin-bottom: 0; }
203
+
204
+ label {
205
+ font-size: 0.78rem;
206
+ font-weight: 600;
207
+ color: var(--muted);
208
+ text-transform: uppercase;
209
+ letter-spacing: 0.08em;
210
+ }
211
+
212
+ input[type="text"], input[type="password"] {
213
+ width: 100%;
214
+ background: var(--surface);
215
+ border: 1px solid var(--border);
216
+ border-radius: 10px;
217
+ padding: 12px 16px;
218
+ color: var(--text);
219
+ font-family: 'DM Mono', monospace;
220
+ font-size: 0.82rem;
221
+ outline: none;
222
+ transition: border-color 0.2s;
223
+ }
224
+ input:focus { border-color: var(--accent); }
225
+ input::placeholder { color: var(--muted); opacity: 0.6; }
226
+
227
+ .field-note {
228
+ font-size: 0.72rem;
229
+ color: var(--muted);
230
+ line-height: 1.5;
231
+ }
232
+
233
+ .rapidapi-link {
234
+ color: var(--accent);
235
+ text-decoration: none;
236
+ font-weight: 600;
237
+ }
238
+ .rapidapi-link:hover { text-decoration: underline; }
239
+
240
+ /* UPLOAD SECTION */
241
+ .upload-zone {
242
+ border: 2px dashed var(--border);
243
+ border-radius: 14px;
244
+ padding: 48px 24px;
245
+ text-align: center;
246
+ cursor: pointer;
247
+ transition: all 0.3s;
248
+ background: var(--surface);
249
+ position: relative;
250
+ }
251
+ .upload-zone:hover, .upload-zone.dragover {
252
+ border-color: var(--accent);
253
+ background: rgba(124,106,255,0.05);
254
+ }
255
+ .upload-zone input[type="file"] {
256
+ position: absolute;
257
+ inset: 0;
258
+ opacity: 0;
259
+ cursor: pointer;
260
+ width: 100%;
261
+ height: 100%;
262
+ }
263
+
264
+ .upload-icon {
265
+ font-size: 2.5rem;
266
+ margin-bottom: 12px;
267
+ }
268
+
269
+ .upload-text {
270
+ font-size: 1rem;
271
+ font-weight: 700;
272
+ margin-bottom: 6px;
273
+ }
274
+
275
+ .upload-sub {
276
+ font-size: 0.8rem;
277
+ color: var(--muted);
278
+ }
279
+
280
+ .file-selected {
281
+ display: none;
282
+ align-items: center;
283
+ gap: 12px;
284
+ background: rgba(124,106,255,0.1);
285
+ border: 1px solid rgba(124,106,255,0.3);
286
+ border-radius: 10px;
287
+ padding: 12px 16px;
288
+ margin-top: 16px;
289
+ font-size: 0.85rem;
290
+ }
291
+ .file-selected.show { display: flex; }
292
+ .file-name { font-family: 'DM Mono', monospace; color: var(--accent); }
293
+
294
+ /* PARSE BUTTON */
295
+ .parse-btn {
296
+ width: 100%;
297
+ background: linear-gradient(135deg, var(--accent), #9b59ff);
298
+ border: none;
299
+ border-radius: 12px;
300
+ padding: 16px;
301
+ color: white;
302
+ font-family: 'Syne', sans-serif;
303
+ font-size: 1rem;
304
+ font-weight: 700;
305
+ cursor: pointer;
306
+ letter-spacing: 0.05em;
307
+ transition: all 0.3s;
308
+ margin-top: 20px;
309
+ position: relative;
310
+ overflow: hidden;
311
+ }
312
+ .parse-btn:hover { transform: translateY(-2px); box-shadow: 0 12px 40px rgba(124,106,255,0.4); }
313
+ .parse-btn:active { transform: translateY(0); }
314
+ .parse-btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }
315
+
316
+ .parse-btn .spinner {
317
+ display: none;
318
+ width: 18px;
319
+ height: 18px;
320
+ border: 2px solid rgba(255,255,255,0.3);
321
+ border-top-color: white;
322
+ border-radius: 50%;
323
+ animation: spin 0.7s linear infinite;
324
+ margin: 0 auto;
325
+ }
326
+ @keyframes spin { to { transform: rotate(360deg); } }
327
+ .parse-btn.loading .btn-text { display: none; }
328
+ .parse-btn.loading .spinner { display: block; }
329
+
330
+ /* ERROR */
331
+ .error-box {
332
+ display: none;
333
+ background: rgba(255,106,138,0.1);
334
+ border: 1px solid rgba(255,106,138,0.3);
335
+ border-radius: 10px;
336
+ padding: 14px 18px;
337
+ color: var(--accent2);
338
+ font-size: 0.85rem;
339
+ margin-top: 16px;
340
+ }
341
+ .error-box.show { display: block; }
342
+
343
+ /* RESULTS */
344
+ .results-section {
345
+ display: none;
346
+ background: var(--card);
347
+ border: 1px solid var(--border);
348
+ border-radius: 16px;
349
+ padding: 28px;
350
+ margin-top: 20px;
351
+ animation: fadeUp 0.5s ease;
352
+ }
353
+ .results-section.show { display: block; }
354
+
355
+ @keyframes fadeUp {
356
+ from { opacity: 0; transform: translateY(20px); }
357
+ to { opacity: 1; transform: translateY(0); }
358
+ }
359
+
360
+ .results-grid {
361
+ display: grid;
362
+ grid-template-columns: 1fr 1fr;
363
+ gap: 12px;
364
+ margin-top: 20px;
365
+ }
366
+
367
+ @media (max-width: 600px) { .results-grid { grid-template-columns: 1fr; } }
368
+
369
+ .result-card {
370
+ background: var(--surface);
371
+ border: 1px solid var(--border);
372
+ border-radius: 12px;
373
+ padding: 16px;
374
+ }
375
+
376
+ .result-card.full { grid-column: 1 / -1; }
377
+
378
+ .result-label {
379
+ font-size: 0.7rem;
380
+ font-weight: 700;
381
+ letter-spacing: 0.12em;
382
+ text-transform: uppercase;
383
+ color: var(--muted);
384
+ margin-bottom: 8px;
385
+ }
386
+
387
+ .result-value {
388
+ font-size: 0.92rem;
389
+ font-weight: 600;
390
+ color: var(--text);
391
+ word-break: break-all;
392
+ }
393
+
394
+ .result-value.mono {
395
+ font-family: 'DM Mono', monospace;
396
+ font-size: 0.82rem;
397
+ }
398
+
399
+ .result-empty { color: var(--muted); font-style: italic; font-size: 0.82rem; }
400
+
401
+ .skills-wrap {
402
+ display: flex;
403
+ flex-wrap: wrap;
404
+ gap: 6px;
405
+ margin-top: 4px;
406
+ }
407
+
408
+ .skill-tag {
409
+ background: rgba(124,106,255,0.15);
410
+ border: 1px solid rgba(124,106,255,0.25);
411
+ color: var(--accent);
412
+ font-size: 0.72rem;
413
+ font-weight: 600;
414
+ padding: 4px 10px;
415
+ border-radius: 100px;
416
+ font-family: 'DM Mono', monospace;
417
+ }
418
+
419
+ .links-wrap { display: flex; flex-direction: column; gap: 6px; }
420
+ .link-item {
421
+ display: flex;
422
+ align-items: center;
423
+ gap: 8px;
424
+ font-family: 'DM Mono', monospace;
425
+ font-size: 0.78rem;
426
+ color: var(--accent);
427
+ text-decoration: none;
428
+ }
429
+ .link-item:hover { text-decoration: underline; }
430
+ .link-icon { font-size: 1rem; }
431
+
432
+ /* CSV EXPORT */
433
+ .export-btn {
434
+ display: inline-flex;
435
+ align-items: center;
436
+ gap: 8px;
437
+ background: var(--surface);
438
+ border: 1px solid var(--border);
439
+ border-radius: 8px;
440
+ padding: 8px 16px;
441
+ color: var(--text);
442
+ font-family: 'Syne', sans-serif;
443
+ font-size: 0.8rem;
444
+ font-weight: 600;
445
+ cursor: pointer;
446
+ transition: all 0.2s;
447
+ margin-top: 20px;
448
+ }
449
+ .export-btn:hover { border-color: var(--success); color: var(--success); }
450
+
451
+ /* RAW JSON */
452
+ .json-toggle {
453
+ display: inline-flex;
454
+ align-items: center;
455
+ gap: 8px;
456
+ background: transparent;
457
+ border: 1px solid var(--border);
458
+ border-radius: 8px;
459
+ padding: 8px 16px;
460
+ color: var(--muted);
461
+ font-family: 'Syne', sans-serif;
462
+ font-size: 0.8rem;
463
+ cursor: pointer;
464
+ transition: all 0.2s;
465
+ margin-top: 20px;
466
+ margin-left: 8px;
467
+ }
468
+ .json-toggle:hover { border-color: var(--accent); color: var(--accent); }
469
+
470
+ .raw-json {
471
+ display: none;
472
+ background: var(--surface);
473
+ border: 1px solid var(--border);
474
+ border-radius: 10px;
475
+ padding: 16px;
476
+ margin-top: 16px;
477
+ font-family: 'DM Mono', monospace;
478
+ font-size: 0.75rem;
479
+ color: var(--accent);
480
+ overflow-x: auto;
481
+ white-space: pre;
482
+ max-height: 300px;
483
+ overflow-y: auto;
484
+ }
485
+ .raw-json.show { display: block; }
486
+
487
+ /* FOOTER NOTE */
488
+ .powered-by {
489
+ text-align: center;
490
+ margin-top: 48px;
491
+ font-size: 0.75rem;
492
+ color: var(--muted);
493
+ }
494
+ .powered-by a { color: var(--accent); text-decoration: none; }
495
+ .powered-by a:hover { text-decoration: underline; }
496
+ </style>
497
+ </head>
498
+ <body>
499
+ <div class="orb orb1"></div>
500
+ <div class="orb orb2"></div>
501
+
502
+ <!-- NAV -->
503
+ <nav>
504
+ <div class="logo">ResumeAI</div>
505
+ <a class="api-badge" href="https://rapidapi.com/9873ashutosh/api/resume-parser-api7" target="_blank">
506
+ <span class="dot"></span>
507
+ API Live on RapidAPI
508
+ </a>
509
+ </nav>
510
+
511
+ <!-- HERO -->
512
+ <div class="hero">
513
+ <div class="hero-tag">⚑ Powered by AI</div>
514
+ <h1>Parse Any Resume<br/>in <em>Seconds</em></h1>
515
+ <p class="hero-sub">Upload a PDF resume and instantly extract name, email, phone, skills, experience and education β€” clean structured data, no manual work.</p>
516
+ </div>
517
+
518
+ <!-- MAIN -->
519
+ <div class="main-container">
520
+
521
+ <!-- STEP 1: API CONFIG -->
522
+ <div class="config-section">
523
+ <div class="section-header">
524
+ <div class="section-num">1</div>
525
+ <div class="section-title">Your API Key</div>
526
+ <div class="section-hint">
527
+ <a class="rapidapi-link" href="https://rapidapi.com/9873ashutosh/api/resume-parser-api7" target="_blank">Get key from RapidAPI β†’</a>
528
+ </div>
529
+ </div>
530
+
531
+ <div class="field-group">
532
+ <label>RapidAPI Key</label>
533
+ <input type="password" id="apiKey" placeholder="Paste your x-rapidapi-key here..." />
534
+ <div class="field-note">
535
+ Don't have a key? <a class="rapidapi-link" href="https://rapidapi.com/9873ashutosh/api/resume-parser-api7" target="_blank">Subscribe free on RapidAPI</a> β€” 10 free parses/month included.
536
+ </div>
537
+ </div>
538
+ </div>
539
+
540
+ <!-- STEP 2: UPLOAD -->
541
+ <div class="config-section">
542
+ <div class="section-header">
543
+ <div class="section-num">2</div>
544
+ <div class="section-title">Upload Resume</div>
545
+ <div class="section-hint">PDF only Β· Max 5MB</div>
546
+ </div>
547
+
548
+ <div class="upload-zone" id="uploadZone">
549
+ <input type="file" id="fileInput" accept=".pdf" />
550
+ <div class="upload-icon">πŸ“„</div>
551
+ <div class="upload-text">Drop your PDF resume here</div>
552
+ <div class="upload-sub">or click to browse files</div>
553
+ </div>
554
+
555
+ <div class="file-selected" id="fileSelected">
556
+ <span>πŸ“Ž</span>
557
+ <span class="file-name" id="fileName"></span>
558
+ <span style="color:var(--muted);font-size:0.78rem;" id="fileSize"></span>
559
+ </div>
560
+
561
+ <button class="parse-btn" id="parseBtn" onclick="parseResume()">
562
+ <span class="btn-text">✨ Parse Resume</span>
563
+ <div class="spinner"></div>
564
+ </button>
565
+
566
+ <div class="error-box" id="errorBox"></div>
567
+ </div>
568
+
569
+ <!-- RESULTS -->
570
+ <div class="results-section" id="resultsSection">
571
+ <div class="section-header">
572
+ <div class="section-num">βœ“</div>
573
+ <div class="section-title">Extracted Data</div>
574
+ </div>
575
+
576
+ <div class="results-grid" id="resultsGrid"></div>
577
+
578
+ <div>
579
+ <button class="export-btn" onclick="exportCSV()">⬇ Export CSV</button>
580
+ <button class="json-toggle" onclick="toggleJSON()">{ } Raw JSON</button>
581
+ </div>
582
+ <div class="raw-json" id="rawJson"></div>
583
+ </div>
584
+
585
+ <div class="powered-by">
586
+ Powered by <a href="https://rapidapi.com/9873ashutosh/api/resume-parser-api7" target="_blank">Resume Parser API on RapidAPI</a>
587
+ </div>
588
+ </div>
589
+
590
+ <script>
591
+ let parsedData = null;
592
+
593
+ // File input handling
594
+ const fileInput = document.getElementById('fileInput');
595
+ const uploadZone = document.getElementById('uploadZone');
596
+ const fileSelected = document.getElementById('fileSelected');
597
+
598
+ fileInput.addEventListener('change', () => {
599
+ const file = fileInput.files[0];
600
+ if (file) {
601
+ document.getElementById('fileName').textContent = file.name;
602
+ document.getElementById('fileSize').textContent = (file.size / 1024).toFixed(1) + ' KB';
603
+ fileSelected.classList.add('show');
604
+ }
605
+ });
606
+
607
+ uploadZone.addEventListener('dragover', (e) => { e.preventDefault(); uploadZone.classList.add('dragover'); });
608
+ uploadZone.addEventListener('dragleave', () => uploadZone.classList.remove('dragover'));
609
+ uploadZone.addEventListener('drop', (e) => {
610
+ e.preventDefault();
611
+ uploadZone.classList.remove('dragover');
612
+ const file = e.dataTransfer.files[0];
613
+ if (file && file.type === 'application/pdf') {
614
+ fileInput.files = e.dataTransfer.files;
615
+ document.getElementById('fileName').textContent = file.name;
616
+ document.getElementById('fileSize').textContent = (file.size / 1024).toFixed(1) + ' KB';
617
+ fileSelected.classList.add('show');
618
+ }
619
+ });
620
+
621
+ function showError(msg) {
622
+ const box = document.getElementById('errorBox');
623
+ box.textContent = '⚠ ' + msg;
624
+ box.classList.add('show');
625
+ }
626
+
627
+ function hideError() {
628
+ document.getElementById('errorBox').classList.remove('show');
629
+ }
630
+
631
+ async function parseResume() {
632
+ hideError();
633
+ const apiKey = document.getElementById('apiKey').value.trim();
634
+ const file = fileInput.files[0];
635
+ const btn = document.getElementById('parseBtn');
636
+
637
+ if (!apiKey) { showError('Please enter your RapidAPI key first.'); return; }
638
+ if (!file) { showError('Please upload a PDF resume first.'); return; }
639
+ if (file.size > 5 * 1024 * 1024) { showError('File too large. Max 5MB.'); return; }
640
+
641
+ btn.classList.add('loading');
642
+ btn.disabled = true;
643
+ document.getElementById('resultsSection').classList.remove('show');
644
+
645
+ try {
646
+ const formData = new FormData();
647
+ formData.append('file', file);
648
+
649
+ const response = await fetch('https://resume-parser-api7.p.rapidapi.com/parse/pdf', {
650
+ method: 'POST',
651
+ headers: {
652
+ 'x-rapidapi-key': apiKey,
653
+ 'x-rapidapi-host': 'resume-parser-api7.p.rapidapi.com'
654
+ },
655
+ body: formData
656
+ });
657
+
658
+ const result = await response.json();
659
+
660
+ if (!response.ok) {
661
+ showError(result.detail || 'API error: ' + response.status);
662
+ return;
663
+ }
664
+
665
+ parsedData = result.data;
666
+ renderResults(parsedData, result);
667
+
668
+ } catch (err) {
669
+ showError('Network error. Check your API key and try again.');
670
+ } finally {
671
+ btn.classList.remove('loading');
672
+ btn.disabled = false;
673
+ }
674
+ }
675
+
676
+ function val(v) {
677
+ if (!v || (Array.isArray(v) && v.length === 0) || (typeof v === 'object' && Object.keys(v).length === 0)) return null;
678
+ return v;
679
+ }
680
+
681
+ function renderResults(data, fullResult) {
682
+ const grid = document.getElementById('resultsGrid');
683
+
684
+ const name = val(data.name);
685
+ const email = val(data.email);
686
+ const phone = val(data.phone);
687
+ const skills = val(data.skills);
688
+ const exp = val(data.experience_years);
689
+ const edu = val(data.education);
690
+ const links = val(data.links);
691
+
692
+ let html = '';
693
+
694
+ html += card('Name', name ? `<span class="result-value">${name}</span>` : empty());
695
+ html += card('Email', email ? `<span class="result-value mono">${email}</span>` : empty());
696
+ html += card('Phone', phone ? `<span class="result-value mono">${phone}</span>` : empty());
697
+ html += card('Experience', exp ? `<span class="result-value">${exp}</span>` : empty());
698
+
699
+ // Skills
700
+ if (skills && skills.length > 0) {
701
+ const tags = skills.map(s => `<span class="skill-tag">${s}</span>`).join('');
702
+ html += `<div class="res