Download app/templates/admin/dashboard.html from mistpe/newBlog: direct link, hf CLI and curl.
- Browser
- Download file 10.3 kB
-
https://huggingface.co/spaces/mistpe/newBlog/resolve/main/app/templates/admin/dashboard.html
- Command line
-
hf download hf://spaces/mistpe/newBlog/app/templates/admin/dashboard.html
-
curl -L -o dashboard.html https://huggingface.co/spaces/mistpe/newBlog/resolve/main/app/templates/admin/dashboard.html
10.3 kB
| {% extends "base.html" %} | |
| {% block title %}管理面板 - Wisdom Hub{% endblock %} | |
| {% block content %} | |
| <div class="dashboard-container" style=" | |
| max-width: 1200px; | |
| margin: 0 auto; | |
| background: linear-gradient(135deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.8)); | |
| backdrop-filter: blur(10px); | |
| border-radius: 24px; | |
| box-shadow: 0 8px 32px rgba(99, 145, 197, 0.15); | |
| border: 1px solid rgba(99, 145, 197, 0.2); | |
| padding: 2rem; | |
| "> | |
| <div class="dashboard-header" style=" | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| margin-bottom: 2rem; | |
| padding-bottom: 1.5rem; | |
| border-bottom: 2px solid #B3CFEF; | |
| "> | |
| <div style="display: flex; align-items: center; gap: 1rem;"> | |
| <i class="fas fa-chart-line" style=" | |
| font-size: 2rem; | |
| color: #6391C5; | |
| "></i> | |
| <h2 style=" | |
| font-size: 1.75rem; | |
| font-weight: 600; | |
| color: #6391C5; | |
| margin: 0; | |
| ">文章管理</h2> | |
| </div> | |
| <div class="dashboard-actions" style=" | |
| display: flex; | |
| gap: 1rem; | |
| "> | |
| <button onclick="location.href='{{ url_for('admin.editor') }}'" style=" | |
| padding: 0.75rem 1.5rem; | |
| background: linear-gradient(135deg, #6391C5, #C5CDFD); | |
| color: white; | |
| border: none; | |
| border-radius: 12px; | |
| font-weight: 500; | |
| cursor: pointer; | |
| transition: all 0.3s ease; | |
| display: flex; | |
| align-items: center; | |
| gap: 0.5rem; | |
| "> | |
| <i class="fas fa-plus"></i> | |
| 新建文章 | |
| </button> | |
| <button onclick="exportData()" style=" | |
| padding: 0.75rem 1.5rem; | |
| background: rgba(99, 145, 197, 0.1); | |
| color: #6391C5; | |
| border: 2px solid #B3CFEF; | |
| border-radius: 12px; | |
| font-weight: 500; | |
| cursor: pointer; | |
| transition: all 0.3s ease; | |
| display: flex; | |
| align-items: center; | |
| gap: 0.5rem; | |
| "> | |
| <i class="fas fa-download"></i> | |
| 导出数据 | |
| </button> | |
| <button onclick="document.getElementById('importInput').click()" style=" | |
| padding: 0.75rem 1.5rem; | |
| background: rgba(99, 145, 197, 0.1); | |
| color: #6391C5; | |
| border: 2px solid #B3CFEF; | |
| border-radius: 12px; | |
| font-weight: 500; | |
| cursor: pointer; | |
| transition: all 0.3s ease; | |
| display: flex; | |
| align-items: center; | |
| gap: 0.5rem; | |
| "> | |
| <i class="fas fa-upload"></i> | |
| 导入数据 | |
| </button> | |
| <input type="file" id="importInput" style="display: none" accept=".db"> | |
| </div> | |
| </div> | |
| <div class="articles-table" style=" | |
| background: white; | |
| border-radius: 16px; | |
| box-shadow: 0 4px 16px rgba(99, 145, 197, 0.1); | |
| overflow: hidden; | |
| "> | |
| <table style="width: 100%; border-collapse: collapse;"> | |
| <thead> | |
| <tr style="background: #FEEEDA;"> | |
| <th style=" | |
| text-align: left; | |
| padding: 1rem 1.5rem; | |
| color: #6391C5; | |
| font-weight: 600; | |
| border-bottom: 2px solid #B3CFEF; | |
| ">标题</th> | |
| <th style=" | |
| text-align: left; | |
| padding: 1rem 1.5rem; | |
| color: #6391C5; | |
| font-weight: 600; | |
| border-bottom: 2px solid #B3CFEF; | |
| ">创建时间</th> | |
| <th style=" | |
| text-align: left; | |
| padding: 1rem 1.5rem; | |
| color: #6391C5; | |
| font-weight: 600; | |
| border-bottom: 2px solid #B3CFEF; | |
| ">更新时间</th> | |
| <th style=" | |
| text-align: left; | |
| padding: 1rem 1.5rem; | |
| color: #6391C5; | |
| font-weight: 600; | |
| border-bottom: 2px solid #B3CFEF; | |
| ">操作</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| {% for article in articles %} | |
| <tr style="transition: all 0.3s ease;"> | |
| <td style=" | |
| padding: 1rem 1.5rem; | |
| border-bottom: 1px solid #B3CFEF; | |
| color: #6391C5; | |
| ">{{ article.title }}</td> | |
| <td style=" | |
| padding: 1rem 1.5rem; | |
| border-bottom: 1px solid #B3CFEF; | |
| color: #6391C5; | |
| ">{{ article.created_at.strftime('%Y-%m-%d') }}</td> | |
| <td style=" | |
| padding: 1rem 1.5rem; | |
| border-bottom: 1px solid #B3CFEF; | |
| color: #6391C5; | |
| ">{{ article.updated_at.strftime('%Y-%m-%d') }}</td> | |
| <td style=" | |
| padding: 1rem 1.5rem; | |
| border-bottom: 1px solid #B3CFEF; | |
| "> | |
| <div style="display: flex; gap: 0.5rem;"> | |
| <a href="{{ url_for('admin.editor', slug=article.slug) }}" style=" | |
| padding: 0.5rem 1rem; | |
| background: linear-gradient(135deg, #6391C5, #C5CDFD); | |
| color: white; | |
| border-radius: 8px; | |
| text-decoration: none; | |
| font-size: 0.875rem; | |
| transition: all 0.3s ease; | |
| ">编辑</a> | |
| <button onclick="deleteArticle('{{ article.slug }}')" style=" | |
| padding: 0.5rem 1rem; | |
| background: rgba(255, 71, 87, 0.1); | |
| color: #ff4757; | |
| border: 1px solid rgba(255, 71, 87, 0.2); | |
| border-radius: 8px; | |
| font-size: 0.875rem; | |
| cursor: pointer; | |
| transition: all 0.3s ease; | |
| ">删除</button> | |
| </div> | |
| </td> | |
| </tr> | |
| {% endfor %} | |
| </tbody> | |
| </table> | |
| </div> | |
| </div> | |
| <script> | |
| // 表格行悬停效果 | |
| document.querySelectorAll('tbody tr').forEach(row => { | |
| row.addEventListener('mouseenter', () => { | |
| row.style.background = 'rgba(99, 145, 197, 0.05)'; | |
| }); | |
| row.addEventListener('mouseleave', () => { | |
| row.style.background = 'white'; | |
| }); | |
| }); | |
| // 按钮悬停效果 | |
| document.querySelectorAll('button').forEach(button => { | |
| button.addEventListener('mouseenter', () => { | |
| if (button.style.background.includes('linear-gradient')) { | |
| button.style.transform = 'translateY(-2px)'; | |
| button.style.boxShadow = '0 4px 12px rgba(99, 145, 197, 0.2)'; | |
| } else if (button.style.background.includes('rgba(255, 71, 87')) { | |
| button.style.background = 'rgba(255, 71, 87, 0.2)'; | |
| } else { | |
| button.style.borderColor = '#6391C5'; | |
| button.style.background = 'rgba(99, 145, 197, 0.15)'; | |
| } | |
| }); | |
| button.addEventListener('mouseleave', () => { | |
| if (button.style.background.includes('linear-gradient')) { | |
| button.style.transform = 'none'; | |
| button.style.boxShadow = 'none'; | |
| } else if (button.style.background.includes('rgba(255, 71, 87')) { | |
| button.style.background = 'rgba(255, 71, 87, 0.1)'; | |
| } else { | |
| button.style.borderColor = '#B3CFEF'; | |
| button.style.background = 'rgba(99, 145, 197, 0.1)'; | |
| } | |
| }); | |
| }); | |
| // 编辑链接悬停效果 | |
| document.querySelectorAll('a').forEach(link => { | |
| if (link.style.background.includes('linear-gradient')) { | |
| link.addEventListener('mouseenter', () => { | |
| link.style.transform = 'translateY(-2px)'; | |
| link.style.boxShadow = '0 4px 12px rgba(99, 145, 197, 0.2)'; | |
| }); | |
| link.addEventListener('mouseleave', () => { | |
| link.style.transform = 'none'; | |
| link.style.boxShadow = 'none'; | |
| }); | |
| } | |
| }); | |
| async function deleteArticle(slug) { | |
| if (!confirm('确定要删除这篇文章吗?')) return; | |
| try { | |
| const response = await fetch(`/api/articles/${slug}`, { | |
| method: 'DELETE' | |
| }); | |
| if (response.ok) { | |
| location.reload(); | |
| } | |
| } catch (error) { | |
| console.error('Error:', error); | |
| alert('删除失败,请重试'); | |
| } | |
| } | |
| async function exportData() { | |
| try { | |
| window.location.href = '/api/export'; | |
| } catch (error) { | |
| console.error('Error:', error); | |
| alert('导出失败,请重试'); | |
| } | |
| } | |
| document.getElementById('importInput').addEventListener('change', async (event) => { | |
| const file = event.target.files[0]; | |
| if (!file) return; | |
| try { | |
| const formData = new FormData(); | |
| formData.append('file', file); | |
| const response = await fetch('/api/import', { | |
| method: 'POST', | |
| body: formData | |
| }); | |
| const data = await response.json(); | |
| if (response.ok) { | |
| alert('导入成功,页面将刷新'); | |
| location.reload(); | |
| } else { | |
| throw new Error(data.error || '导入失败'); | |
| } | |
| } catch (error) { | |
| console.error('Error:', error); | |
| alert('导入失败:' + error.message); | |
| } | |
| }); | |
| </script> | |
| {% endblock %} |