|
33 | 33 | // independently of the filter-driven reload. |
34 | 34 | let structured = $state<ResumeStructured | null>(null); |
35 | 35 | let loadError = $state(false); |
36 | | - let tab = $state<'profile' | 'coverage' | 'readiness'>('profile'); |
| 36 | + let tab = $state<'settings' | 'structured' | 'coverage' | 'readiness'>('settings'); |
37 | 37 | let modalOpen = $state(false); |
38 | 38 | let actionError = $state<string | null>(null); |
39 | 39 |
|
|
235 | 235 | <div class="flex gap-5 border-b border-border"> |
236 | 236 | <button |
237 | 237 | type="button" |
238 | | - onclick={() => (tab = 'profile')} |
239 | | - class="-mb-px border-b-2 px-1 pb-2.5 text-sm font-medium transition-colors {tab === 'profile' |
| 238 | + onclick={() => (tab = 'settings')} |
| 239 | + class="-mb-px border-b-2 px-1 pb-2.5 text-sm font-medium transition-colors {tab === 'settings' |
240 | 240 | ? 'border-brand text-foreground' |
241 | 241 | : 'border-transparent text-muted-foreground hover:text-foreground'}" |
242 | 242 | > |
243 | | - Your CV |
| 243 | + Settings |
| 244 | + </button> |
| 245 | + <button |
| 246 | + type="button" |
| 247 | + onclick={() => (tab = 'structured')} |
| 248 | + class="-mb-px border-b-2 px-1 pb-2.5 text-sm font-medium transition-colors {tab === 'structured' |
| 249 | + ? 'border-brand text-foreground' |
| 250 | + : 'border-transparent text-muted-foreground hover:text-foreground'}" |
| 251 | + > |
| 252 | + Profile |
244 | 253 | </button> |
245 | 254 | <button |
246 | 255 | type="button" |
|
263 | 272 | </div> |
264 | 273 |
|
265 | 274 | <!-- Body --> |
266 | | - {#if tab === 'profile'} |
| 275 | + {#if tab === 'settings'} |
267 | 276 | {#key profile.updated_at} |
268 | 277 | <ProfileForm {profile} {hasCv} onSaved={handleSaved} onCvUploaded={handleCvUploaded} /> |
269 | 278 | {/key} |
270 | | - <!-- Destructive action lives at the foot of the profile-management tab, out of |
| 279 | + <!-- Destructive action lives at the foot of the settings tab, out of |
271 | 280 | the page header (where it crowded the title on narrow viewports). --> |
272 | 281 | <div class="mt-2 flex justify-end border-t border-border pt-4"> |
273 | 282 | <Button |
|
280 | 289 | Delete profile |
281 | 290 | </Button> |
282 | 291 | </div> |
| 292 | + {:else if tab === 'structured'} |
| 293 | + <!-- Profile: the read-only structured résumé parsed from the CV. Loaded |
| 294 | + independently of the filter-driven reload, so no verdict gate. --> |
| 295 | + {#if structured} |
| 296 | + <ResumeStructuredView resume={structured} /> |
| 297 | + {:else} |
| 298 | + <div class="flex flex-col items-start gap-2 rounded-xl border border-dashed border-border p-6"> |
| 299 | + <p class="text-sm font-medium">No parsed profile yet</p> |
| 300 | + <p class="text-sm text-muted-foreground"> |
| 301 | + Upload your CV in the <button type="button" class="font-medium text-foreground underline underline-offset-2" onclick={() => (tab = 'settings')}>Settings</button> tab and we'll parse it into a structured profile. |
| 302 | + </p> |
| 303 | + </div> |
| 304 | + {/if} |
283 | 305 | {:else if loadError} |
284 | 306 | <States state="error" message="Couldn't load the report." /> |
285 | 307 | {:else if verdict === null} |
286 | 308 | <States state="loading" /> |
287 | 309 | {:else if tab === 'coverage'} |
288 | 310 | <VerdictView {verdict} {gapHref} /> |
289 | 311 | {:else} |
290 | | - <!-- CV readiness: the structured résumé we parsed from the CV (read-only, |
291 | | - omitted when none is current) above the ATS-readiness score. --> |
| 312 | + <!-- CV readiness: the ATS-readiness score and the optional AI review. --> |
292 | 313 | <div class="flex flex-col gap-6"> |
293 | | - {#if structured} |
294 | | - <ResumeStructuredView resume={structured} /> |
295 | | - {/if} |
296 | 314 | {#if ats?.has_cv && ats.report} |
297 | 315 | <div class="flex flex-col gap-5"> |
298 | 316 | {#if reviewUnavailable} |
299 | 317 | <p class="text-xs text-muted-foreground">AI review is not available right now.</p> |
300 | 318 | {/if} |
301 | 319 | <ATSReportView report={ats.report} action={reviewAction} /> |
302 | 320 | </div> |
303 | | - {:else if !structured} |
304 | | - <!-- No CV yet: uploaded via the Your CV tab. --> |
| 321 | + {:else} |
| 322 | + <!-- No CV yet: uploaded via the Settings tab. --> |
305 | 323 | <div class="flex flex-col items-start gap-2 rounded-xl border border-dashed border-border p-6"> |
306 | 324 | <p class="text-sm font-medium">Add your CV to score its ATS readiness</p> |
307 | 325 | <p class="text-sm text-muted-foreground"> |
308 | | - Upload your CV in the <button type="button" class="font-medium text-foreground underline underline-offset-2" onclick={() => (tab = 'profile')}>Your CV</button> tab to check ATS readability and this role's keywords. |
| 326 | + Upload your CV in the <button type="button" class="font-medium text-foreground underline underline-offset-2" onclick={() => (tab = 'settings')}>Settings</button> tab to check ATS readability and this role's keywords. |
309 | 327 | </p> |
310 | 328 | </div> |
311 | 329 | {/if} |
|
0 commit comments