From 09935e64781df4ddfdb0e06b616d55981d8ef8fd Mon Sep 17 00:00:00 2001 From: zhangyuheng Date: Tue, 10 Mar 2026 15:20:28 +0800 Subject: [PATCH] feat: add share functionality and update modal layout in facilities --- css/pages/facilities.css | 36 +++++++++++++++++++++++++ facilities.html | 11 +++++--- js/facilities_script.js | 57 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 3 deletions(-) diff --git a/css/pages/facilities.css b/css/pages/facilities.css index 33afdf9..fba2b2f 100644 --- a/css/pages/facilities.css +++ b/css/pages/facilities.css @@ -314,6 +314,13 @@ flex-wrap: wrap; } +.modal-actions { + display: flex; + gap: 8px; + align-items: center; + flex-shrink: 0; +} + .large-badge { padding: 6px 14px; border-radius: 8px; @@ -533,6 +540,35 @@ transform: translateY(-1px); } +.btn-share-facility { + display: inline-flex; + align-items: center; + gap: 6px; + padding: 6px 16px; + background: transparent; + color: var(--text-secondary); + border: 1.5px solid rgba(0,0,0,0.12); + border-radius: 18px; + font-size: 13px; + font-weight: 600; + cursor: pointer; + transition: var(--transition); + white-space: nowrap; + flex-shrink: 0; +} + +.btn-share-facility:hover { + color: var(--accent-color); + border-color: var(--accent-color); + background: rgba(0,113,227,0.04); +} + +.btn-share-facility.shared { + color: #15803d; + border-color: #34c759; + background: #e8fceb; +} + .btn-edit-facility { display: inline-flex; align-items: center; diff --git a/facilities.html b/facilities.html index 68ebd1c..430b3da 100644 --- a/facilities.html +++ b/facilities.html @@ -117,9 +117,14 @@ - + diff --git a/js/facilities_script.js b/js/facilities_script.js index dc28618..531f049 100644 --- a/js/facilities_script.js +++ b/js/facilities_script.js @@ -19,12 +19,36 @@ document.addEventListener('DOMContentLoaded', () => { let currentDetailItem = null; + // Generate stable anchor ID for a facility + function generateFacilityId(item) { + var raw = (item.title || ''); + var hash = 0; + for (var i = 0; i < raw.length; i++) { + hash = ((hash << 5) - hash) + raw.charCodeAt(i); + hash |= 0; + } + return 'f' + Math.abs(hash).toString(36); + } + + // Handle URL hash: auto-open facility modal + function handleHashNavigation() { + var hash = location.hash.replace('#', ''); + if (!hash) return; + for (var i = 0; i < facilitiesData.length; i++) { + if (generateFacilityId(facilitiesData[i]) === hash) { + openModal(facilitiesData[i]); + return; + } + } + } + // 1. Fetch Data fetch('data/facilities.json') .then(response => response.json()) .then(data => { facilitiesData = data; renderGrid(); + handleHashNavigation(); }) .catch(err => { console.error('Error loading facilities:', err); @@ -66,12 +90,14 @@ document.addEventListener('DOMContentLoaded', () => { closeModal.addEventListener('click', () => { modal.style.display = 'none'; document.body.style.overflow = 'auto'; // Enable scrolling + history.replaceState(null, '', location.pathname + location.search); }); window.addEventListener('click', (e) => { if (e.target === modal) { modal.style.display = 'none'; document.body.style.overflow = 'auto'; + history.replaceState(null, '', location.pathname + location.search); } }); @@ -177,6 +203,10 @@ document.addEventListener('DOMContentLoaded', () => { modal.style.display = 'block'; document.body.style.overflow = 'hidden'; // Prevent scrolling background + + // Update URL hash + var anchorId = generateFacilityId(item); + history.replaceState(null, '', '#' + anchorId); } function renderContentList(container, list) { @@ -302,6 +332,33 @@ document.addEventListener('DOMContentLoaded', () => { openEditor(null); }); + // Share facility link + document.getElementById('btn-share-facility').addEventListener('click', () => { + if (!currentDetailItem) return; + var anchorId = generateFacilityId(currentDetailItem); + var url = location.origin + location.pathname + '#' + anchorId; + var btn = document.getElementById('btn-share-facility'); + navigator.clipboard.writeText(url).then(() => { + btn.innerHTML = ' 已复制链接'; + btn.classList.add('shared'); + setTimeout(() => { + btn.innerHTML = ' 分享'; + btn.classList.remove('shared'); + }, 2000); + }).catch(() => { + var tmp = document.createElement('input'); + tmp.value = url; + document.body.appendChild(tmp); + tmp.select(); + document.execCommand('copy'); + document.body.removeChild(tmp); + btn.innerHTML = ' 已复制链接'; + setTimeout(() => { + btn.innerHTML = ' 分享'; + }, 2000); + }); + }); + // Open editor from detail modal document.getElementById('btn-edit-facility').addEventListener('click', () => { if (currentDetailItem) {