@ -774,6 +774,69 @@
-webkit-overflow-scrolling: touch;
-webkit-overflow-scrolling: touch;
}
}
/* Edit Panel Overlay - Similar to Admin */
.edit-panel-overlay {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 60vh;
background: rgba(30, 30, 30, 0.95);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
transform: translateY(100%);
transition: transform 0.3s ease;
z-index: 1001;
border-radius: 20px 20px 0 0;
box-shadow: 0 -4px 20px rgba(0,0,0,0.3);
display: flex;
flex-direction: column;
}
.edit-panel-overlay.active {
transform: translateY(0);
}
.edit-panel-header {
padding: 20px;
border-bottom: 1px solid #444;
display: flex;
justify-content: space-between;
align-items: center;
flex-shrink: 0;
}
.edit-panel-header h2 {
color: #4CAF50;
margin: 0;
font-size: 20px;
}
.edit-panel-close {
background: none;
border: none;
color: #aaa;
font-size: 28px;
cursor: pointer;
padding: 0;
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
}
.edit-panel-close:hover {
color: white;
}
.edit-panel-content {
padding: 20px;
overflow-y: auto;
flex: 1;
-webkit-overflow-scrolling: touch;
}
/* Admin Panel Styles - Simple and Working */
/* Admin Panel Styles - Simple and Working */
.admin-setting-group {
.admin-setting-group {
padding: 15px;
padding: 15px;
@ -3840,6 +3903,12 @@
[editTab, navTab, adminTab].forEach(tab => tab.classList.remove('active'));
[editTab, navTab, adminTab].forEach(tab => tab.classList.remove('active'));
[editContent, navContent, adminContent].forEach(content => content.classList.remove('active'));
[editContent, navContent, adminContent].forEach(content => content.classList.remove('active'));
// Close any open overlays
const editOverlay = document.querySelector('.edit-panel-overlay');
const adminOverlay = document.querySelector('.admin-panel-overlay');
if (editOverlay) editOverlay.classList.remove('active');
if (adminOverlay) adminOverlay.classList.remove('active');
if (tabName === 'edit') {
if (tabName === 'edit') {
// Check authentication for edit mode
// Check authentication for edit mode
if (!isAuthenticated) {
if (!isAuthenticated) {
@ -3847,8 +3916,12 @@
return;
return;
}
}
// Show edit overlay instead of tab content
editTab.classList.add('active');
editTab.classList.add('active');
editContent.classList.add('active');
const editOverlay = document.querySelector('.edit-panel-overlay');
if (editOverlay) {
editOverlay.classList.add('active');
}
navMode = false;
navMode = false;
// Show geocache list toggle in edit mode
// Show geocache list toggle in edit mode
@ -5986,6 +6059,25 @@
document.getElementById('navTab').addEventListener('click', () => switchTab('navigate'));
document.getElementById('navTab').addEventListener('click', () => switchTab('navigate'));
document.getElementById('adminTab').addEventListener('click', () => switchTab('admin'));
document.getElementById('adminTab').addEventListener('click', () => switchTab('admin'));
// Edit overlay close button
setTimeout(() => {
const editCloseBtn = document.getElementById('editCloseBtn');
if (editCloseBtn) {
editCloseBtn.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
const editOverlay = document.querySelector('.edit-panel-overlay');
if (editOverlay) {
editOverlay.classList.remove('active');
}
// Remove active class from edit tab
document.getElementById('editTab').classList.remove('active');
// Switch to navigate tab
switchTab('navigate');
});
}
}, 100);
// Admin overlay close button - defer to ensure DOM element exists
// Admin overlay close button - defer to ensure DOM element exists
setTimeout(() => {
setTimeout(() => {
const adminCloseBtn = document.getElementById('adminCloseBtn');
const adminCloseBtn = document.getElementById('adminCloseBtn');
@ -6421,6 +6513,77 @@
< / script >
< / script >
<!-- Edit Panel Overlay -->
< div class = "edit-panel-overlay" id = "editOverlay" >
< div class = "edit-panel-header" >
< h2 > ✏️ Edit Tools< / h2 >
< button class = "edit-panel-close" id = "editCloseBtn" > ×< / button >
< / div >
< div class = "edit-panel-content" id = "editOverlayContent" >
< div class = "section" >
< div class = "section-title" > File< / div >
< input type = "file" id = "kmlFile" accept = ".kml" >
< button class = "action-btn" id = "reloadBtn" style = "background: #17a2b8;" > Reload Tracks< / button >
< button class = "action-btn" id = "exportBtn" > Export to File< / button >
< button class = "action-btn" id = "saveServerBtn" style = "background: #28a745;" > Save to Server< / button >
< / div >
< div class = "section" >
< div class = "section-title" > Track Tools< / div >
< div class = "tool-buttons" >
< button class = "tool-btn" id = "selectTool" title = "Select track, then press Delete key to remove" > Select< / button >
< button class = "tool-btn" id = "splitTool" title = "Click on a track to split it" > Split< / button >
< button class = "tool-btn" id = "drawTool" title = "Draw a new track" > Draw< / button >
< button class = "tool-btn" id = "reshapeTool" title = "Drag points to reshape track" > Reshape< / button >
< button class = "tool-btn" id = "smoothTool" title = "Brush over track to smooth it" > Smooth< / button >
< button class = "action-btn" id = "remeshBtn" title = "Remesh selected tracks with even spacing" > Remesh Selected< / button >
< button class = "tool-btn" id = "geocacheTool" title = "Place a geocache" > 📍 Cache< / button >
< / div >
< div class = "slider-group" id = "reshapeControls" style = "display: none;" >
< label > Anchor Distance (points beyond stay fixed)< / label >
< input type = "range" id = "anchorDistance" min = "3" max = "50" value = "10" >
< div class = "slider-value" > < span id = "anchorValue" > 10< / span > points< / div >
< label style = "margin-top: 8px;" > Falloff (how sharply effect fades)< / label >
< input type = "range" id = "reshapeFalloff" min = "0.5" max = "3" value = "1" step = "0.1" >
< div class = "slider-value" > < span id = "falloffValue" > 1.0< / span > < / div >
< / div >
< div class = "slider-group" id = "smoothControls" style = "display: none;" >
< label > Brush Size (pixels)< / label >
< input type = "range" id = "smoothBrushSize" min = "10" max = "100" value = "30" >
< div class = "slider-value" > < span id = "brushSizeValue" > 30< / span > px< / div >
< label style = "margin-top: 8px;" > Strength< / label >
< input type = "range" id = "smoothStrength" min = "0.1" max = "1" value = "0.5" step = "0.1" >
< div class = "slider-value" > < span id = "strengthValue" > 0.5< / span > < / div >
< / div >
< / div >
< div class = "section" >
< div class = "section-title" > Merge / Simplify< / div >
< div class = "slider-group" >
< label > Merge Threshold< / label >
< input type = "range" id = "mergeThreshold" min = "1" max = "10" value = "5" step = "0.5" >
< div class = "slider-value" > < span id = "thresholdValue" > 5< / span > meters< / div >
< / div >
< button class = "action-btn" id = "previewBtn" style = "background: #17a2b8;" > Preview Merge< / button >
< button class = "action-btn" id = "applyMergeBtn" style = "display: none;" > Apply Merge< / button >
< button class = "action-btn secondary" id = "cancelPreviewBtn" style = "display: none;" > Cancel Preview< / button >
< div style = "margin-top: 8px;" >
< button class = "action-btn secondary" id = "mergeConnectBtn" > Connect End-to-End< / button >
< / div >
< div style = "border-top: 1px solid #eee; margin-top: 10px; padding-top: 10px;" >
< button class = "action-btn" id = "selectAllBtn" style = "background: #6c757d;" > Select All< / button >
< button class = "action-btn secondary" id = "clearSelectionBtn" > Clear Selection< / button >
< / div >
< / div >
< div class = "section" >
< div class = "section-title" > Tracks (< span id = "trackCount" > 0< / span > )< / div >
< div class = "track-list" id = "trackList" > < / div >
< button class = "action-btn" id = "undoBtn" style = "background: #6c757d;" > Undo< / button >
< / div >
< / div >
< / div >
<!-- Admin Panel Overlay -->
<!-- Admin Panel Overlay -->
< div class = "admin-panel-overlay" id = "adminOverlay" >
< div class = "admin-panel-overlay" id = "adminOverlay" >
< div class = "admin-panel-header" >
< div class = "admin-panel-header" >