feat: home page hash-based tab routing for shareable links

This commit is contained in:
2026-07-12 01:53:59 +08:00
parent 5bb2df7b52
commit 989a3ae4cf
2 changed files with 21 additions and 21 deletions

View File

@@ -55,7 +55,8 @@ const App = {
} }
if (page === 'install') { this.showPublic('install'); return; } if (page === 'install') { this.showPublic('install'); return; }
if (page === 'home' || page === 'login' || page === 'register') { this.showPublic(page); return; } if (page === 'home') { this.showPublic('home', param); return; }
if (page === 'login' || page === 'register') { this.showPublic(page); return; }
if (!Auth.logged()) { location.hash = '#/login'; return; } if (!Auth.logged()) { location.hash = '#/login'; return; }
this.showLayout(); this.showLayout();
@@ -83,13 +84,13 @@ const App = {
} }
}, },
showPublic(page) { showPublic(page, param) {
document.getElementById('top-auth').classList.remove('hidden'); document.getElementById('top-auth').classList.remove('hidden');
document.getElementById('main-layout').classList.add('hidden'); document.getElementById('main-layout').classList.add('hidden');
const pub = document.getElementById('public-page'); const pub = document.getElementById('public-page');
pub.classList.remove('hidden'); pub.classList.remove('hidden');
const comp = page === 'login' ? LoginPage : page === 'register' ? RegisterPage : page === 'install' ? InstallPage : HomePage; const comp = page === 'login' ? LoginPage : page === 'register' ? RegisterPage : page === 'install' ? InstallPage : HomePage;
Promise.resolve(comp.render()).then(html => { pub.innerHTML = html; if (comp.mount) comp.mount(); }); Promise.resolve(comp.render(param)).then(html => { pub.innerHTML = html; if (comp.mount) comp.mount(param); });
}, },
showLayout() { showLayout() {

View File

@@ -1,26 +1,25 @@
const HomePage = { const HomePage = {
async render() { async render(tab) {
const t = tab || 'report';
return `<div id="home-content" style="max-width:800px;margin:0 auto;padding:30px 0"> return `<div id="home-content" style="max-width:800px;margin:0 auto;padding:30px 0">
<div class="tab-nav"> <div class="tab-nav">
<button class="active" data-tab="report"><i class="fas fa-flag"></i> 举报</button> <button class="${t==='report'?'active':''}" data-tab="report"><i class="fas fa-flag"></i> 举报</button>
<button data-tab="suggestion"><i class="fas fa-lightbulb"></i> 建议</button> <button class="${t==='suggestion'?'active':''}" data-tab="suggestion"><i class="fas fa-lightbulb"></i> 建议</button>
<button data-tab="appeal"><i class="fas fa-gavel"></i> 申诉</button> <button class="${t==='appeal'?'active':''}" data-tab="appeal"><i class="fas fa-gavel"></i> 申诉</button>
<button data-tab="tracking"><i class="fas fa-search"></i> 追踪</button> <button class="${t==='tracking'?'active':''}" data-tab="tracking"><i class="fas fa-search"></i> 追踪</button>
</div> </div>
<div id="home-tab"></div> <div id="home-tab"></div>
</div>`; </div>`;
}, },
mount() { mount(tab) {
const t = tab || 'report';
const tabBtns = document.querySelectorAll('.tab-nav button'); const tabBtns = document.querySelectorAll('.tab-nav button');
const tabContent = document.getElementById('home-tab'); const tabContent = document.getElementById('home-tab');
let currentTab = 'report';
function switchTab(tab) { function switchContent(type) {
currentTab = tab; if (type === 'tracking') renderTracking(tabContent);
tabBtns.forEach(b => b.classList.toggle('active', b.dataset.tab === tab)); else TicketCreate.render(tabContent, { type, prefill: {}, backLink: null });
if (tab === 'tracking') renderTracking(tabContent);
else TicketCreate.render(tabContent, { type: tab, prefill: {}, backLink: null });
} }
function renderTracking(ct) { function renderTracking(ct) {
@@ -35,8 +34,8 @@ const HomePage = {
</div></div>`; </div></div>`;
} }
tabBtns.forEach(b => b.onclick = () => switchTab(b.dataset.tab)); tabBtns.forEach(b => b.onclick = () => App.navigate('home', b.dataset.tab));
switchTab('report'); switchContent(t);
this.searchTracking = async () => { this.searchTracking = async () => {
const token = document.getElementById('track-token').value.trim(); const token = document.getElementById('track-token').value.trim();
@@ -48,10 +47,10 @@ const HomePage = {
ct.innerHTML = tickets.length ? ` ct.innerHTML = tickets.length ? `
<div class="table-wrap"><table><thead><tr> <div class="table-wrap"><table><thead><tr>
<th>#</th><th>类型</th><th>标题</th><th>状态</th><th>时间</th><th>操作</th> <th>#</th><th>类型</th><th>标题</th><th>状态</th><th>时间</th><th>操作</th>
</tr></thead><tbody>${tickets.map(t => ` </tr></thead><tbody>${tickets.map(tick => `
<tr><td>${t.id}</td><td>${U.badge(t.type,'type')}</td><td>${U.esc(t.title)}</td> <tr><td>${tick.id}</td><td>${U.badge(tick.type,'type')}</td><td>${U.esc(tick.title)}</td>
<td>${U.badge(t.status,'status')}</td><td>${U.date(t.created_at)}</td> <td>${U.badge(tick.status,'status')}</td><td>${U.date(tick.created_at)}</td>
<td><button class="btn btn-o btn-sm" onclick="App.navigate('tracking');App.showTrackDetail(${t.id},'${token}')">查看</button></td></tr> <td><button class="btn btn-o btn-sm" onclick="App.navigate('home','tracking');HomePage.showTrackDetail(${tick.id},'${token}')">查看</button></td></tr>
`).join('')}</tbody></table></div>` : '<div class="empty"><i class="fas fa-inbox"></i><p>未找到工单</p></div>'; `).join('')}</tbody></table></div>` : '<div class="empty"><i class="fas fa-inbox"></i><p>未找到工单</p></div>';
} catch (ex) { ct.innerHTML = `<div class="alert alert-e">${ex.message}</div>`; } } catch (ex) { ct.innerHTML = `<div class="alert alert-e">${ex.message}</div>`; }
}; };