This commit is contained in:
zjb 2025-05-29 15:56:24 +08:00
parent cd7d95c8e9
commit 3b476a29d4
4 changed files with 418 additions and 0 deletions

View File

@ -70,6 +70,11 @@ module.exports = {
position: 'left',
dropdownActiveClassDisabled: true
},
{
to: '/feedback',
position: 'right',
label: '问题反馈'
},
// {
// href: 'https://github.com/boxyhq',
// position: 'right',
@ -173,6 +178,13 @@ module.exports = {
highlightSearchTermsOnTargetPage: true,
blogRouteBasePath: "/",
explicitSearchResultPath: true,
indexDocs: true,
indexBlog: false,
indexPages: true,
docsRouteBasePath: "/",
searchResultLimits: 8,
searchBarPosition: "right",
searchBarShortcutHint: true,
// For Docs using Chinese, The `language` is recommended to set to:
// ```
// language: ["en", "zh"],

View File

@ -16,6 +16,10 @@
--ifm-color-primary-lightest: rgb(146, 224, 208);
--ifm-code-font-size: 95%;
--search-local-modal-background:#1b2440;
--search-local-highlight-color: #466aff;
--search-local-hit-background: #f0f4ff;
--search-local-hit-shadow: 0 1px 3px 0 #d4e0ee;
--search-local-hit-active-color: #fff;
}
.navbar{
background-color: rgba(27, 36, 64, 1);
@ -149,4 +153,64 @@ html[data-theme='dark'] .docusaurus-highlight-code-line {
.widget{
display: none!important;
opacity: 0;
}
/* 优化搜索框样式 */
.navbar__search-input {
border-radius: 4px;
transition: width 0.2s ease-in-out;
border: 1px solid transparent;
}
.navbar__search-input:focus {
width: 260px;
border-color: var(--ifm-color-primary);
}
/* 搜索结果样式 */
.search-result-match {
color: var(--search-local-highlight-color);
font-weight: bold;
}
.search-result-item {
padding: 1rem;
margin-bottom: 0.5rem;
border-radius: 8px;
background-color: var(--search-local-hit-background);
box-shadow: var(--search-local-hit-shadow);
transition: all 0.2s ease;
}
.search-result-item:hover {
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
/* 问题反馈导航按钮样式 */
.navbar__items a[href="/feedback"] {
background-color: rgba(70, 106, 255, 0.1);
color: var(--ifm-color-primary) !important;
padding: 0.5rem 1rem;
border-radius: 4px;
font-weight: 500;
transition: all 0.2s ease;
}
.navbar__items a[href="/feedback"]:hover {
background-color: rgba(70, 106, 255, 0.2);
}
/* 暗黑模式适配 */
html[data-theme='dark'] {
--search-local-hit-background: #2a2a3c;
--search-local-hit-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.4);
}
html[data-theme='dark'] .navbar__items a[href="/feedback"] {
background-color: rgba(70, 106, 255, 0.2);
}
html[data-theme='dark'] .navbar__items a[href="/feedback"]:hover {
background-color: rgba(70, 106, 255, 0.3);
}

182
src/pages/feedback.js Normal file
View File

@ -0,0 +1,182 @@
const React = require('react');
const { useState } = React;
const Layout = require('@theme/Layout').default;
const styles = require('./feedback.module.css');
function Feedback() {
const [formData, setFormData] = useState({
name: '',
email: '',
type: '功能建议',
content: '',
});
const [submitted, setSubmitted] = useState(false);
const [error, setError] = useState('');
const [isSubmitting, setIsSubmitting] = useState(false);
const validateEmail = (email) => {
const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return re.test(email);
};
const handleChange = (e) => {
const { name, value } = e.target;
setFormData(prevData => ({
...prevData,
[name]: value
}));
setError('');
};
const handleSubmit = async (e) => {
e.preventDefault();
if (!formData.name.trim()) {
setError('请输入您的姓名');
return;
}
if (!formData.email.trim()) {
setError('请输入您的邮箱地址');
return;
}
if (!validateEmail(formData.email)) {
setError('请输入有效的邮箱地址');
return;
}
if (!formData.content.trim()) {
setError('请输入反馈内容');
return;
}
setIsSubmitting(true);
try {
// 模拟API调用
await new Promise(resolve => setTimeout(resolve, 1000));
console.log('表单提交:', formData);
setSubmitted(true);
setError('');
} catch (err) {
setError('提交失败,请稍后重试');
} finally {
setIsSubmitting(false);
}
};
if (submitted) {
return (
<Layout title="反馈已提交 - GitLink帮助中心">
<div className={styles.feedbackContainer}>
<div className={styles.successMessage}>
<h1>感谢您的反馈</h1>
<p>我们已收到您的反馈意见将认真处理每一条建议<br />您的支持是我们不断进步的动力</p>
<div>
<button
className={styles.button}
onClick={() => {
setSubmitted(false);
setFormData({
name: '',
email: '',
type: '功能建议',
content: '',
});
}}
>
继续提交反馈
</button>
<a href="/" className={styles.homeLink}>返回首页</a>
</div>
</div>
</div>
</Layout>
);
}
return (
<Layout title="问题反馈 - GitLink帮助中心">
<div className={styles.feedbackContainer}>
<h1>问题反馈</h1>
<p className={styles.subtitle}>
欢迎提供您的宝贵意见帮助我们做得更好
</p>
{error && <div className={styles.errorMessage}>{error}</div>}
<form onSubmit={handleSubmit} className={styles.feedbackForm}>
<div className={styles.formGroup}>
<label htmlFor="name">姓名 <span className={styles.required}>*</span></label>
<input
type="text"
id="name"
name="name"
value={formData.name}
onChange={handleChange}
placeholder="请输入您的姓名"
disabled={isSubmitting}
required
/>
</div>
<div className={styles.formGroup}>
<label htmlFor="email">邮箱 <span className={styles.required}>*</span></label>
<input
type="email"
id="email"
name="email"
value={formData.email}
onChange={handleChange}
placeholder="请输入您的邮箱地址"
disabled={isSubmitting}
required
/>
</div>
<div className={styles.formGroup}>
<label htmlFor="type">反馈类型</label>
<select
id="type"
name="type"
value={formData.type}
onChange={handleChange}
disabled={isSubmitting}
>
<option value="功能建议">功能建议</option>
<option value="问题报告">问题报告</option>
<option value="使用咨询">使用咨询</option>
<option value="其他">其他</option>
</select>
</div>
<div className={styles.formGroup}>
<label htmlFor="content">反馈内容 <span className={styles.required}>*</span></label>
<textarea
id="content"
name="content"
value={formData.content}
onChange={handleChange}
placeholder="请详细描述您遇到的问题或建议..."
rows="6"
disabled={isSubmitting}
required
/>
</div>
<button
type="submit"
className={styles.button}
disabled={isSubmitting}
>
{isSubmitting ? '提交中...' : '提交反馈'}
</button>
</form>
</div>
</Layout>
);
}
module.exports = Feedback;

View File

@ -0,0 +1,160 @@
.feedbackContainer {
max-width: 800px;
margin: 2rem auto;
padding: 2.5rem;
background: #ffffff;
border-radius: 8px;
box-shadow: 8px 6px 18px rgba(171, 202, 255, 0.24);
}
.subtitle {
color: #666;
margin-bottom: 2rem;
text-align: center;
font-size: 1rem;
line-height: 1.5;
}
h1 {
text-align: center;
color: #1b2440;
margin-bottom: 1rem;
font-size: 2rem;
font-weight: 600;
}
.feedbackForm {
display: flex;
flex-direction: column;
gap: 1.25rem;
}
.formGroup {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.formGroup label {
font-weight: 500;
color: #1b2440;
font-size: 0.95rem;
}
.required {
color: #e53e3e;
margin-left: 4px;
}
.formGroup input,
.formGroup select,
.formGroup textarea {
padding: 0.75rem;
border: 1px solid #d4e0ee;
border-radius: 4px;
font-size: 0.95rem;
transition: all 0.2s ease;
background-color: #fff;
}
.formGroup input:focus,
.formGroup select:focus,
.formGroup textarea:focus {
outline: none;
border-color: #466aff;
box-shadow: 0 0 0 3px rgba(70, 106, 255, 0.1);
}
.formGroup input:hover,
.formGroup select:hover,
.formGroup textarea:hover {
border-color: #466aff;
}
.formGroup input::placeholder,
.formGroup textarea::placeholder {
color: #94a3b8;
}
.button {
background-color: #466aff;
color: white;
padding: 0.75rem 1.5rem;
border: none;
border-radius: 4px;
font-size: 1rem;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
margin-top: 0.5rem;
}
.button:hover {
background-color: #3451cc;
transform: translateY(-1px);
}
.button:disabled {
background-color: #94a3b8;
cursor: not-allowed;
transform: none;
}
.errorMessage {
background-color: #fff5f5;
border: 1px solid #feb2b2;
color: #e53e3e;
padding: 0.75rem;
border-radius: 4px;
margin-bottom: 1rem;
text-align: center;
font-size: 0.95rem;
}
.successMessage {
text-align: center;
padding: 2rem;
}
.successMessage h1 {
color: #466aff;
margin-bottom: 1rem;
font-size: 1.75rem;
}
.successMessage p {
color: #1b2440;
margin-bottom: 2rem;
font-size: 1rem;
line-height: 1.5;
}
.homeLink {
display: inline-block;
margin-top: 1rem;
color: #466aff;
text-decoration: none;
font-weight: 500;
margin-left: 1rem;
transition: all 0.2s ease;
}
.homeLink:hover {
color: #3451cc;
text-decoration: none;
}
@media (max-width: 768px) {
.feedbackContainer {
margin: 1rem;
padding: 1.5rem;
}
h1 {
font-size: 1.75rem;
}
.button {
width: 100%;
}
}