Files
tech-forum/frontend/create.html
hubian e7ebc3a4d6 feat: 添加浏览器标签图标favicon
- 创建 favicon.svg(渐变背景 + </>代码符号)
- 所有页面添加 favicon 链接
2026-04-12 17:56:25 +08:00

157 lines
6.8 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<title>发布帖子 - 技术论坛</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://cdn.jsdelivr.net/npm/remixicon@3.5.0/fonts/remixicon.css" rel="stylesheet">
<style>
.gradient-bg { background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%); }
</style>
</head>
<body class="bg-gray-50 min-h-screen">
<!-- 导航栏 -->
<nav class="bg-white border-b border-gray-100">
<div class="max-w-4xl mx-auto px-4 py-4">
<a href="/" class="text-gray-600 hover:text-gray-800 flex items-center gap-1">
<i class="ri-arrow-left-line"></i> 返回首页
</a>
</div>
</nav>
<main class="max-w-4xl mx-auto px-4 py-8">
<h1 class="text-2xl font-bold text-gray-800 mb-6">发布新帖子</h1>
<form id="postForm" class="bg-white rounded-lg border border-gray-100 p-6">
<!-- 帖子类型 -->
<div class="mb-6">
<label class="block text-sm font-medium text-gray-700 mb-2">帖子类型</label>
<div class="flex gap-4">
<label class="flex items-center gap-2 cursor-pointer">
<input type="radio" name="type" value="discussion" checked class="text-blue-600">
<span class="flex items-center gap-1">
<i class="ri-discuss-line text-blue-500"></i> 技术交流
</span>
</label>
<label class="flex items-center gap-2 cursor-pointer">
<input type="radio" name="type" value="share" class="text-purple-600">
<span class="flex items-center gap-1">
<i class="ri-tools-line text-purple-500"></i> 工具分享
</span>
</label>
</div>
</div>
<!-- 标题 -->
<div class="mb-6">
<label class="block text-sm font-medium text-gray-700 mb-2">标题</label>
<input type="text" id="title" placeholder="请输入帖子标题"
class="w-full px-4 py-3 border border-gray-200 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent">
</div>
<!-- 内容 -->
<div class="mb-6">
<label class="block text-sm font-medium text-gray-700 mb-2">内容</label>
<textarea id="content" rows="12" placeholder="请输入帖子内容支持Markdown格式..."
class="w-full px-4 py-3 border border-gray-200 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent resize-none"></textarea>
</div>
<!-- 标签 -->
<div class="mb-6">
<label class="block text-sm font-medium text-gray-700 mb-2">
标签 <span class="text-gray-400">(用逗号分隔)</span>
</label>
<input type="text" id="tags" placeholder="如Python, Django, Web开发"
class="w-full px-4 py-3 border border-gray-200 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent">
</div>
<!-- 提交按钮 -->
<div class="flex gap-3">
<button type="submit" class="px-6 py-3 gradient-bg text-white rounded-lg font-medium hover:opacity-90">
发布帖子
</button>
<button type="button" onclick="saveDraft()" class="px-6 py-3 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50">
保存草稿
</button>
</div>
</form>
<div id="errorMsg" class="mt-4 p-3 bg-red-50 text-red-500 rounded-lg text-sm hidden"></div>
</main>
<script>
// 检查登录
if (!localStorage.getItem('token')) {
window.location.href = '/login';
}
document.getElementById('postForm').addEventListener('submit', async (e) => {
e.preventDefault();
const title = document.getElementById('title').value.trim();
const content = document.getElementById('content').value.trim();
const type = document.querySelector('input[name="type"]:checked').value;
const tagsInput = document.getElementById('tags').value.trim();
const tags = tagsInput ? tagsInput.split(',').map(t => t.trim()).filter(t => t) : [];
if (!title || title.length < 5) {
showError('标题至少5个字符');
return;
}
if (!content || content.length < 10) {
showError('内容至少10个字符');
return;
}
try {
const res = await fetch('/api/posts', {
method: 'POST',
headers: {
'Authorization': `Bearer ${localStorage.getItem('token')}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ title, content, type, tags })
});
const data = await res.json();
if (data.success) {
window.location.href = `/post/${data.post_id}`;
} else {
showError(data.error || '发布失败');
}
} catch (err) {
showError('网络错误,请重试');
}
});
function saveDraft() {
const draft = {
title: document.getElementById('title').value,
content: document.getElementById('content').value,
type: document.querySelector('input[name="type"]:checked').value,
tags: document.getElementById('tags').value
};
localStorage.setItem('post_draft', JSON.stringify(draft));
alert('草稿已保存');
}
// 恢复草稿
const savedDraft = localStorage.getItem('post_draft');
if (savedDraft) {
const draft = JSON.parse(savedDraft);
if (draft.title) document.getElementById('title').value = draft.title;
if (draft.content) document.getElementById('content').value = draft.content;
if (draft.type) document.querySelector(`input[value="${draft.type}"]`).checked = true;
if (draft.tags) document.getElementById('tags').value = draft.tags;
}
function showError(msg) {
const el = document.getElementById('errorMsg');
el.textContent = msg;
el.classList.remove('hidden');
}
</script>
</body>
</html>