Skip to content

Commit 6952bdf

Browse files
committed
feat: enhance styling and layout of candidate and pipeline components with improved responsiveness and visual hierarchy
1 parent 4bd4a70 commit 6952bdf

3 files changed

Lines changed: 129 additions & 96 deletions

File tree

app/components/CandidateDetailSidebar.vue

Lines changed: 63 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,12 @@ const transitionClasses: Record<string, string> = {
9494
}
9595
9696
const statusBadgeClasses: Record<string, string> = {
97-
new: 'bg-brand-50 text-brand-700 dark:bg-brand-950 dark:text-brand-400',
98-
screening: 'bg-info-50 text-info-700 dark:bg-info-950 dark:text-info-400',
99-
interview: 'bg-warning-50 text-warning-700 dark:bg-warning-950 dark:text-warning-400',
100-
offer: 'bg-success-50 text-success-700 dark:bg-success-950 dark:text-success-400',
101-
hired: 'bg-success-100 text-success-800 dark:bg-success-900 dark:text-success-300',
102-
rejected: 'bg-surface-100 text-surface-500 dark:bg-surface-800 dark:text-surface-400',
97+
new: 'bg-brand-50 text-brand-700 ring-brand-200 dark:bg-brand-950/50 dark:text-brand-300 dark:ring-brand-800',
98+
screening: 'bg-info-50 text-info-700 ring-info-200 dark:bg-info-950/50 dark:text-info-300 dark:ring-info-800',
99+
interview: 'bg-warning-50 text-warning-700 ring-warning-200 dark:bg-warning-950/50 dark:text-warning-300 dark:ring-warning-800',
100+
offer: 'bg-success-50 text-success-700 ring-success-200 dark:bg-success-950/50 dark:text-success-300 dark:ring-success-800',
101+
hired: 'bg-success-100 text-success-800 ring-success-300 dark:bg-success-900/50 dark:text-success-200 dark:ring-success-700',
102+
rejected: 'bg-surface-100 text-surface-500 ring-surface-200 dark:bg-surface-800/50 dark:text-surface-400 dark:ring-surface-700',
103103
}
104104
105105
const allowedTransitions = computed(() => {
@@ -306,11 +306,11 @@ const responsesCount = computed(() => application.value?.responses?.length ?? 0)
306306
<Transition name="slide">
307307
<aside
308308
v-if="open"
309-
class="fixed right-0 z-40 w-[640px] max-w-[calc(100vw-4rem)] border-l border-surface-200 dark:border-surface-800 bg-white dark:bg-surface-900 shadow-xl flex flex-col"
309+
class="fixed right-0 z-40 w-[640px] max-w-[calc(100vw-4rem)] border-l border-surface-200/80 dark:border-surface-800/60 bg-white dark:bg-surface-900 shadow-xl flex flex-col"
310310
:class="hasSubNav ? 'top-24 h-[calc(100vh-6rem)]' : 'top-14 h-[calc(100vh-3.5rem)]'"
311311
>
312312
<!-- Header -->
313-
<div class="flex items-center justify-between border-b border-surface-200 dark:border-surface-800 px-6 py-4 shrink-0">
313+
<div class="flex items-center justify-between border-b border-surface-200/80 dark:border-surface-800/60 px-6 py-4 shrink-0">
314314
<div v-if="application" class="min-w-0 flex-1">
315315
<div class="flex items-center gap-3">
316316
<div class="flex items-center justify-center size-10 rounded-full bg-brand-50 dark:bg-brand-950 text-brand-700 dark:text-brand-400 font-semibold text-sm shrink-0">
@@ -346,7 +346,7 @@ const responsesCount = computed(() => application.value?.responses?.length ?? 0)
346346
</div>
347347

348348
<!-- Tabs -->
349-
<div v-if="application" class="border-b border-surface-200 dark:border-surface-800 px-6 shrink-0">
349+
<div v-if="application" class="border-b border-surface-200/80 dark:border-surface-800/60 px-6 shrink-0">
350350
<div class="flex gap-1">
351351
<button
352352
class="cursor-pointer px-3 py-2.5 text-sm font-medium transition-colors border-b-2 -mb-px"
@@ -396,8 +396,8 @@ const responsesCount = computed(() => application.value?.responses?.length ?? 0)
396396
<div>
397397
<div class="flex items-center gap-2 mb-3">
398398
<span
399-
class="inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium capitalize"
400-
:class="statusBadgeClasses[application.status] ?? 'bg-surface-100 text-surface-600'"
399+
class="inline-flex items-center rounded-md px-2.5 py-0.5 text-xs font-semibold capitalize ring-1 ring-inset"
400+
:class="statusBadgeClasses[application.status] ?? 'bg-surface-100 text-surface-600 ring-surface-200'"
401401
>
402402
{{ application.status }}
403403
</span>
@@ -422,79 +422,85 @@ const responsesCount = computed(() => application.value?.responses?.length ?? 0)
422422
</div>
423423

424424
<!-- Candidate info -->
425-
<div class="rounded-lg border border-surface-200 dark:border-surface-800 bg-surface-50 dark:bg-surface-950 p-5">
426-
<div class="flex items-center gap-2 mb-3">
427-
<User class="size-4 text-surface-500 dark:text-surface-400" />
428-
<h3 class="text-sm font-semibold text-surface-700 dark:text-surface-200">Candidate</h3>
425+
<div class="rounded-xl border border-surface-200/80 dark:border-surface-800/60 bg-white dark:bg-surface-950 p-5 shadow-sm shadow-surface-900/[0.03] dark:shadow-none">
426+
<div class="flex items-center gap-2.5 mb-4">
427+
<div class="flex size-7 items-center justify-center rounded-lg bg-brand-50 dark:bg-brand-950/40">
428+
<User class="size-3.5 text-brand-600 dark:text-brand-400" />
429+
</div>
430+
<h3 class="text-sm font-semibold text-surface-800 dark:text-surface-200">Candidate</h3>
429431
</div>
430-
<dl class="grid grid-cols-2 gap-3 text-sm">
432+
<dl class="grid grid-cols-2 gap-4 text-sm">
431433
<div>
432-
<dt class="text-surface-400">Name</dt>
433-
<dd class="text-surface-700 dark:text-surface-200 font-medium">
434+
<dt class="text-xs font-medium text-surface-400 dark:text-surface-500 mb-1">Name</dt>
435+
<dd class="text-surface-800 dark:text-surface-200 font-medium">
434436
{{ application.candidate.firstName }} {{ application.candidate.lastName }}
435437
</dd>
436438
</div>
437439
<div>
438-
<dt class="text-surface-400">Email</dt>
439-
<dd class="text-surface-700 dark:text-surface-200 font-medium truncate">
440+
<dt class="text-xs font-medium text-surface-400 dark:text-surface-500 mb-1">Email</dt>
441+
<dd class="text-surface-800 dark:text-surface-200 font-medium truncate">
440442
{{ application.candidate.email }}
441443
</dd>
442444
</div>
443445
<div v-if="application.candidate.phone">
444-
<dt class="text-surface-400">Phone</dt>
445-
<dd class="text-surface-700 dark:text-surface-200 font-medium">
446+
<dt class="text-xs font-medium text-surface-400 dark:text-surface-500 mb-1">Phone</dt>
447+
<dd class="text-surface-800 dark:text-surface-200 font-medium">
446448
{{ application.candidate.phone }}
447449
</dd>
448450
</div>
449451
</dl>
450452
</div>
451453

452454
<!-- Application details -->
453-
<div class="rounded-lg border border-surface-200 dark:border-surface-800 bg-surface-50 dark:bg-surface-950 p-5">
454-
<div class="flex items-center gap-2 mb-3">
455-
<Hash class="size-4 text-surface-500 dark:text-surface-400" />
456-
<h3 class="text-sm font-semibold text-surface-700 dark:text-surface-200">Details</h3>
455+
<div class="rounded-xl border border-surface-200/80 dark:border-surface-800/60 bg-white dark:bg-surface-950 p-5 shadow-sm shadow-surface-900/[0.03] dark:shadow-none">
456+
<div class="flex items-center gap-2.5 mb-4">
457+
<div class="flex size-7 items-center justify-center rounded-lg bg-info-50 dark:bg-info-950/40">
458+
<Hash class="size-3.5 text-info-600 dark:text-info-400" />
459+
</div>
460+
<h3 class="text-sm font-semibold text-surface-800 dark:text-surface-200">Details</h3>
457461
</div>
458-
<dl class="grid grid-cols-2 gap-3 text-sm">
462+
<dl class="grid grid-cols-2 gap-4 text-sm">
459463
<div>
460-
<dt class="text-surface-400">Score</dt>
461-
<dd class="text-surface-700 dark:text-surface-200 font-medium">
464+
<dt class="text-xs font-medium text-surface-400 dark:text-surface-500 mb-1">Score</dt>
465+
<dd class="text-surface-800 dark:text-surface-200 font-medium">
462466
{{ application.score ?? '—' }}
463467
</dd>
464468
</div>
465469
<div>
466-
<dt class="text-surface-400">Status</dt>
467-
<dd class="text-surface-700 dark:text-surface-200 font-medium capitalize">
470+
<dt class="text-xs font-medium text-surface-400 dark:text-surface-500 mb-1">Status</dt>
471+
<dd class="text-surface-800 dark:text-surface-200 font-medium capitalize">
468472
{{ application.status }}
469473
</dd>
470474
</div>
471475
<div>
472-
<dt class="text-surface-400 inline-flex items-center gap-1">
476+
<dt class="text-xs font-medium text-surface-400 dark:text-surface-500 mb-1 inline-flex items-center gap-1">
473477
<Calendar class="size-3.5" />
474478
Applied
475479
</dt>
476-
<dd class="text-surface-700 dark:text-surface-200 font-medium">
480+
<dd class="text-surface-800 dark:text-surface-200 font-medium">
477481
{{ new Date(application.createdAt).toLocaleDateString() }}
478482
</dd>
479483
</div>
480484
<div>
481-
<dt class="text-surface-400 inline-flex items-center gap-1">
485+
<dt class="text-xs font-medium text-surface-400 dark:text-surface-500 mb-1 inline-flex items-center gap-1">
482486
<Clock class="size-3.5" />
483487
Updated
484488
</dt>
485-
<dd class="text-surface-700 dark:text-surface-200 font-medium">
489+
<dd class="text-surface-800 dark:text-surface-200 font-medium">
486490
{{ new Date(application.updatedAt).toLocaleDateString() }}
487491
</dd>
488492
</div>
489493
</dl>
490494
</div>
491495

492496
<!-- Notes -->
493-
<div class="rounded-lg border border-surface-200 dark:border-surface-800 bg-surface-50 dark:bg-surface-950 p-5">
494-
<div class="flex items-center justify-between mb-3">
495-
<div class="flex items-center gap-2">
496-
<MessageSquare class="size-4 text-surface-500 dark:text-surface-400" />
497-
<h3 class="text-sm font-semibold text-surface-700 dark:text-surface-200">Notes</h3>
497+
<div class="rounded-xl border border-surface-200/80 dark:border-surface-800/60 bg-white dark:bg-surface-950 p-5 shadow-sm shadow-surface-900/[0.03] dark:shadow-none">
498+
<div class="flex items-center justify-between mb-4">
499+
<div class="flex items-center gap-2.5">
500+
<div class="flex size-7 items-center justify-center rounded-lg bg-warning-50 dark:bg-warning-950/40">
501+
<MessageSquare class="size-3.5 text-warning-600 dark:text-warning-400" />
502+
</div>
503+
<h3 class="text-sm font-semibold text-surface-800 dark:text-surface-200">Notes</h3>
498504
</div>
499505
<button
500506
v-if="!isEditingNotes"
@@ -531,7 +537,7 @@ const responsesCount = computed(() => application.value?.responses?.length ?? 0)
531537

532538
<p
533539
v-else-if="application.notes"
534-
class="text-sm text-surface-600 dark:text-surface-300 whitespace-pre-wrap"
540+
class="text-sm leading-relaxed text-surface-600 dark:text-surface-300 whitespace-pre-wrap"
535541
>
536542
{{ application.notes }}
537543
</p>
@@ -662,11 +668,13 @@ const responsesCount = computed(() => application.value?.responses?.length ?? 0)
662668
<!-- Empty state -->
663669
<div
664670
v-if="documents.length === 0"
665-
class="rounded-lg border border-surface-200 dark:border-surface-800 bg-surface-50 dark:bg-surface-950 p-8 text-center"
671+
class="rounded-xl border border-surface-200/80 dark:border-surface-800/60 bg-white dark:bg-surface-950 p-8 text-center shadow-sm shadow-surface-900/[0.03] dark:shadow-none"
666672
>
667-
<FileText class="size-8 text-surface-300 dark:text-surface-600 mx-auto mb-2" />
668-
<p class="text-sm text-surface-500 dark:text-surface-400">No documents yet.</p>
669-
<p class="text-xs text-surface-400 mt-1">
673+
<div class="flex size-14 items-center justify-center rounded-2xl bg-surface-100 dark:bg-surface-800/60 mx-auto mb-3">
674+
<FileText class="size-6 text-surface-400 dark:text-surface-500" />
675+
</div>
676+
<p class="text-sm font-medium text-surface-600 dark:text-surface-300">No documents yet.</p>
677+
<p class="text-xs text-surface-400 dark:text-surface-500 mt-1">
670678
Upload a resume, cover letter, or other document (PDF, DOC, DOCX — max 10 MB).
671679
</p>
672680
</div>
@@ -676,7 +684,7 @@ const responsesCount = computed(() => application.value?.responses?.length ?? 0)
676684
<div
677685
v-for="doc in documents"
678686
:key="doc.id"
679-
class="group flex items-center justify-between rounded-lg border border-surface-200 dark:border-surface-800 bg-surface-50 dark:bg-surface-950 px-4 py-3 transition-colors"
687+
class="group flex items-center justify-between rounded-xl border border-surface-200/80 dark:border-surface-800/60 bg-white dark:bg-surface-950 px-4 py-3 shadow-sm shadow-surface-900/[0.03] dark:shadow-none transition-colors"
680688
:class="doc.mimeType === 'application/pdf' ? 'cursor-pointer hover:border-brand-300 dark:hover:border-brand-700 hover:bg-brand-50/50 dark:hover:bg-brand-950/30' : ''"
681689
@click="doc.mimeType === 'application/pdf' ? handlePreview(doc.id, doc.mimeType) : undefined"
682690
>
@@ -727,22 +735,24 @@ const responsesCount = computed(() => application.value?.responses?.length ?? 0)
727735
<div v-if="activeTab === 'responses'" class="space-y-3">
728736
<div
729737
v-if="responsesCount === 0"
730-
class="rounded-lg border border-surface-200 dark:border-surface-800 bg-surface-50 dark:bg-surface-950 p-8 text-center"
738+
class="rounded-xl border border-surface-200/80 dark:border-surface-800/60 bg-white dark:bg-surface-950 p-8 text-center shadow-sm shadow-surface-900/[0.03] dark:shadow-none"
731739
>
732-
<FileText class="size-8 text-surface-300 dark:text-surface-600 mx-auto mb-2" />
733-
<p class="text-sm text-surface-500 dark:text-surface-400">No application responses.</p>
740+
<div class="flex size-14 items-center justify-center rounded-2xl bg-surface-100 dark:bg-surface-800/60 mx-auto mb-3">
741+
<FileText class="size-6 text-surface-400 dark:text-surface-500" />
742+
</div>
743+
<p class="text-sm font-medium text-surface-600 dark:text-surface-300">No application responses.</p>
734744
</div>
735745

736746
<div v-else class="space-y-3">
737747
<div
738748
v-for="response in application.responses"
739749
:key="response.id"
740-
class="rounded-lg border border-surface-200 dark:border-surface-800 bg-surface-50 dark:bg-surface-950 p-4"
750+
class="rounded-xl border border-surface-200/80 dark:border-surface-800/60 bg-white dark:bg-surface-950 p-4 shadow-sm shadow-surface-900/[0.03] dark:shadow-none"
741751
>
742-
<dt class="text-xs font-medium text-surface-500 dark:text-surface-400 mb-1 uppercase tracking-wide">
752+
<dt class="text-xs font-semibold text-surface-400 dark:text-surface-500 mb-1.5 uppercase tracking-wider">
743753
{{ response.question?.label ?? 'Unknown question' }}
744754
</dt>
745-
<dd class="text-sm text-surface-700 dark:text-surface-200">
755+
<dd class="text-sm text-surface-700 dark:text-surface-200 leading-relaxed">
746756
{{ formatResponseValue(response.value) }}
747757
</dd>
748758
</div>
@@ -760,7 +770,7 @@ const responsesCount = computed(() => application.value?.responses?.length ?? 0)
760770
<Teleport to="body">
761771
<div v-if="showDocDeleteConfirm" class="fixed inset-0 z-50 flex items-center justify-center">
762772
<div class="absolute inset-0 bg-black/50" @click="showDocDeleteConfirm = null" />
763-
<div class="relative bg-white dark:bg-surface-900 rounded-xl shadow-xl p-6 max-w-sm w-full mx-4">
773+
<div class="relative bg-white dark:bg-surface-900 rounded-2xl shadow-2xl shadow-surface-900/10 dark:shadow-black/30 ring-1 ring-surface-200/80 dark:ring-surface-700/60 p-6 max-w-sm w-full mx-4">
764774
<h3 class="text-lg font-semibold text-surface-900 dark:text-surface-50 mb-2">Delete Document</h3>
765775
<p class="text-sm text-surface-600 dark:text-surface-400 mb-4">
766776
Are you sure you want to delete this document? This action cannot be undone.

app/components/PipelineCard.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ const transitionClasses: Record<string, string> = {
3636
</script>
3737

3838
<template>
39-
<div class="rounded-lg border border-surface-200 dark:border-surface-800 bg-white dark:bg-surface-900 p-3 shadow-sm">
39+
<div class="rounded-xl border border-surface-200/80 dark:border-surface-800/60 bg-white dark:bg-surface-900 p-3 shadow-sm shadow-surface-900/[0.03] dark:shadow-none">
4040
<NuxtLink
4141
:to="$localePath(`/dashboard/applications/${id}`)"
4242
class="block mb-2 group"
@@ -57,13 +57,13 @@ const transitionClasses: Record<string, string> = {
5757
<Calendar class="size-3" />
5858
{{ new Date(createdAt).toLocaleDateString() }}
5959
</span>
60-
<span v-if="score != null" class="font-medium text-surface-600 dark:text-surface-300">
60+
<span v-if="score != null" class="inline-flex items-center rounded-md px-1.5 py-0.5 text-[10px] font-semibold ring-1 ring-inset bg-surface-50 text-surface-600 ring-surface-200 dark:bg-surface-800/60 dark:text-surface-300 dark:ring-surface-700">
6161
{{ score }}pts
6262
</span>
6363
</div>
6464

6565
<!-- Transition buttons -->
66-
<div v-if="allowedTransitions.length > 0" class="flex flex-wrap gap-1 mt-2 pt-2 border-t border-surface-100 dark:border-surface-800">
66+
<div v-if="allowedTransitions.length > 0" class="flex flex-wrap gap-1 mt-2 pt-2 border-t border-surface-100 dark:border-surface-800/60">
6767
<button
6868
v-for="nextStatus in allowedTransitions"
6969
:key="nextStatus"

0 commit comments

Comments
 (0)