Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,26 @@ All notable changes to CV Manager will be documented in this file.

Format follows [Keep a Changelog](https://keepachangelog.com/), versioning follows [Semantic Versioning](https://semver.org/).

## [1.33.3] - 2026-04-17

### Changed
- Section reorder overlay: when a drag is started from a section-heading handle, the floating pill now snaps under the cursor (centered on the pointer) instead of preserving the pointer→pill offset. The handle can be far from the overlay's center, which previously required dragging the cursor a long way before the pill caught up — painful on small trackpads.

## [1.33.2] - 2026-04-17

### Fixed
- Section reorder overlay: the new order is now also synced into the active dataset snapshot, matching how the Settings → Sections Save button behaves. Without this, the live `section_visibility` table was updated but the active dataset kept the old order, and a page reload restored it — making the reorder appear not to persist.

## [1.33.1] - 2026-04-17

### Fixed
- Section reorder overlay: the drop-position indicator now tracks the floating pill's midpoint instead of the cursor, so grabbing a pill near its top or bottom edge no longer puts the placeholder one slot off from where the pill is actually shown.

## [1.33.0] - 2026-04-17

### Added
- In-place section reorder overlay. A drag handle now appears next to every section heading; activating it opens a floating overlay with each section's title over a dimmed, blurred CV. Drag pills to reorder with animated transitions, then click OK to save or Cancel to revert. Hidden sections appear dimmed so their position can still be adjusted. The Settings → Sections & Headlines panel is unchanged and remains available.

## [1.32.0] - 2026-04-17

### Added
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cv-manager",
"version": "1.32.0",
"version": "1.33.3",
"description": "Professional CV Management System",
"main": "src/server.js",
"scripts": {
Expand Down
33 changes: 33 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,9 @@ <h1 class="profile-name" id="profileName" itemprop="name">Loading...</h1>

<!-- About Section -->
<section class="section" id="section-about">
<button class="section-reorder-handle no-print" data-section-key="about" data-i18n-title="action.reorder_sections" title="Reorder sections" aria-label="Reorder sections">
<span class="material-symbols-outlined">drag_indicator</span>
</button>
<div class="section-header">
<h2 class="section-title" data-i18n="section.about">Professional Summary</h2>
<div class="section-actions no-print">
Expand All @@ -184,6 +187,9 @@ <h2 class="section-title" data-i18n="section.about">Professional Summary</h2>

<!-- Timeline Section -->
<section class="section" id="section-timeline">
<button class="section-reorder-handle no-print" data-section-key="timeline" data-i18n-title="action.reorder_sections" title="Reorder sections" aria-label="Reorder sections">
<span class="material-symbols-outlined">drag_indicator</span>
</button>
<div class="section-header">
<h2 class="section-title" data-i18n="section.timeline">Career Timeline</h2>
<div class="section-actions no-print">
Expand All @@ -200,6 +206,9 @@ <h2 class="section-title" data-i18n="section.timeline">Career Timeline</h2>

<!-- Experience Section -->
<section class="section" id="section-experience">
<button class="section-reorder-handle no-print" data-section-key="experience" data-i18n-title="action.reorder_sections" title="Reorder sections" aria-label="Reorder sections">
<span class="material-symbols-outlined">drag_indicator</span>
</button>
<div class="section-header">
<h2 class="section-title" data-i18n="section.experience">Work Experience</h2>
<div class="section-actions no-print">
Expand All @@ -217,6 +226,9 @@ <h2 class="section-title" data-i18n="section.experience">Work Experience</h2>

<!-- Certifications Section -->
<section class="section" id="section-certifications">
<button class="section-reorder-handle no-print" data-section-key="certifications" data-i18n-title="action.reorder_sections" title="Reorder sections" aria-label="Reorder sections">
<span class="material-symbols-outlined">drag_indicator</span>
</button>
<div class="section-header">
<h2 class="section-title" data-i18n="section.certifications">Certifications</h2>
<div class="section-actions no-print">
Expand All @@ -234,6 +246,9 @@ <h2 class="section-title" data-i18n="section.certifications">Certifications</h2>

<!-- Education Section -->
<section class="section" id="section-education">
<button class="section-reorder-handle no-print" data-section-key="education" data-i18n-title="action.reorder_sections" title="Reorder sections" aria-label="Reorder sections">
<span class="material-symbols-outlined">drag_indicator</span>
</button>
<div class="section-header">
<h2 class="section-title" data-i18n="section.education">Education</h2>
<div class="section-actions no-print">
Expand All @@ -251,6 +266,9 @@ <h2 class="section-title" data-i18n="section.education">Education</h2>

<!-- Skills Section -->
<section class="section" id="section-skills">
<button class="section-reorder-handle no-print" data-section-key="skills" data-i18n-title="action.reorder_sections" title="Reorder sections" aria-label="Reorder sections">
<span class="material-symbols-outlined">drag_indicator</span>
</button>
<div class="section-header">
<h2 class="section-title" data-i18n="section.skills">Skills & Expertise</h2>
<div class="section-actions no-print">
Expand All @@ -268,6 +286,9 @@ <h2 class="section-title" data-i18n="section.skills">Skills & Expertise</h2>

<!-- Projects Section -->
<section class="section" id="section-projects">
<button class="section-reorder-handle no-print" data-section-key="projects" data-i18n-title="action.reorder_sections" title="Reorder sections" aria-label="Reorder sections">
<span class="material-symbols-outlined">drag_indicator</span>
</button>
<div class="section-header">
<h2 class="section-title" data-i18n="section.projects">Featured Projects</h2>
<div class="section-actions no-print">
Expand Down Expand Up @@ -726,6 +747,18 @@ <h2 data-i18n="ats.title">ATS-Friendly Document</h2>
</div>
</div>

<!-- Section Reorder Overlay -->
<div class="reorder-overlay" id="reorderOverlay" aria-hidden="true">
<div class="reorder-dialog">
<div class="reorder-hint" data-i18n="reorder.hint">Drag sections to reorder. Click OK to save.</div>
<div class="reorder-list" id="reorderList"></div>
<div class="reorder-footer">
<button class="btn btn-ghost" id="reorderCancelBtn" data-i18n="btn.cancel">Cancel</button>
<button class="btn btn-primary" id="reorderOkBtn" data-i18n="btn.ok">OK</button>
</div>
</div>
</div>

<script src="/shared/i18n.js"></script>
<script src="/shared/scripts.js"></script>
<script src="/shared/admin.js"></script>
Expand Down
218 changes: 218 additions & 0 deletions public/shared/admin.css
Original file line number Diff line number Diff line change
Expand Up @@ -2739,3 +2739,221 @@
}
.ats-pdf-scale-row input[type="range"] { width: 100px; }
}

/* =========================================================
Section Reorder Overlay
========================================================= */

.section-reorder-handle {
position: absolute;
top: 20px;
left: -14px;
width: 28px;
height: 28px;
display: flex;
align-items: center;
justify-content: center;
border: none;
background: var(--white);
color: var(--gray-500);
border-radius: 50%;
cursor: grab;
box-shadow: var(--shadow-md);
opacity: 0;
transform: translateX(6px) scale(0.85);
transition: opacity .18s ease, transform .18s ease, color .18s ease, background .18s ease;
z-index: 2;
padding: 0;
}

.section:hover .section-reorder-handle,
.section-reorder-handle:focus-visible {
opacity: 1;
transform: translateX(0) scale(1);
}

.section-reorder-handle:hover {
color: var(--primary);
background: var(--light);
}

.section-reorder-handle:active {
cursor: grabbing;
transform: scale(0.95);
}

.section-reorder-handle .material-symbols-outlined {
font-size: 18px;
pointer-events: none;
}

body.reorder-active .section-reorder-handle { opacity: 0; pointer-events: none; }

.reorder-overlay {
position: fixed;
inset: 0;
display: none;
align-items: center;
justify-content: center;
z-index: 2500;
background: rgba(0, 26, 77, 0);
backdrop-filter: blur(0);
-webkit-backdrop-filter: blur(0);
transition: background .28s ease, backdrop-filter .28s ease, -webkit-backdrop-filter .28s ease;
padding: 24px;
}

.reorder-overlay.active {
display: flex;
background: rgba(0, 26, 77, 0.55);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}

.reorder-dialog {
display: flex;
flex-direction: column;
gap: 18px;
width: 100%;
max-width: 440px;
max-height: 90vh;
opacity: 0;
transition: opacity .28s ease .05s;
}

.reorder-overlay.active .reorder-dialog {
opacity: 1;
}

.reorder-hint {
text-align: center;
color: var(--white);
font-size: 13px;
font-weight: 500;
opacity: 0.85;
text-shadow: 0 1px 6px rgba(0, 0, 0, 0.25);
}

.reorder-list {
display: flex;
flex-direction: column;
gap: 10px;
overflow-y: auto;
padding: 4px 2px;
}

.reorder-pill {
display: flex;
align-items: center;
gap: 12px;
padding: 14px 18px;
background: var(--white);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-md);
color: var(--primary);
font-size: 16px;
font-weight: 600;
cursor: grab;
user-select: none;
touch-action: none;
will-change: transform;
animation: reorderPillIn .32s cubic-bezier(.2,.8,.2,1) both;
transition: box-shadow .2s ease, opacity .2s ease;
}

.reorder-pill:hover {
box-shadow: var(--shadow-lg);
}

.reorder-pill:active {
cursor: grabbing;
}

.reorder-pill.dragging {
cursor: grabbing;
box-shadow: 0 18px 40px rgba(0, 0, 0, 0.25), 0 4px 10px rgba(0, 0, 0, 0.15);
transform: scale(1.04);
animation: none;
transition: none;
background: var(--white);
}

.reorder-pill--hidden {
opacity: 0.55;
}

.reorder-pill-grip {
font-size: 20px !important;
color: var(--gray-400);
flex-shrink: 0;
}

.reorder-pill-label {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

.reorder-pill-hidden-icon {
font-size: 18px !important;
color: var(--gray-400);
flex-shrink: 0;
}

.reorder-placeholder {
border: 2px dashed rgba(255, 255, 255, 0.45);
border-radius: var(--radius-lg);
background: rgba(255, 255, 255, 0.08);
transition: height .2s ease;
}

.reorder-footer {
display: flex;
justify-content: flex-end;
gap: 10px;
padding-top: 4px;
}

.reorder-footer .btn {
min-width: 96px;
}

.reorder-footer .btn-ghost {
background: rgba(255, 255, 255, 0.14);
color: var(--white);
border: 1px solid rgba(255, 255, 255, 0.3);
}

.reorder-footer .btn-ghost:hover {
background: rgba(255, 255, 255, 0.24);
}

@keyframes reorderPillIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: none; }
}

.reorder-pill--hidden {
animation-name: reorderPillInHidden;
}

@keyframes reorderPillInHidden {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 0.55; transform: none; }
}

@media (max-width: 600px) {
.section-reorder-handle {
left: 6px;
top: 16px;
}
.reorder-dialog { max-width: 100%; }
.reorder-pill { padding: 12px 14px; font-size: 15px; }
}

@media print {
.reorder-overlay,
.section-reorder-handle { display: none !important; }
}
Loading
Loading