parent
faf4222020
commit
b98abe886f
@ -1,109 +0,0 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import styles from './styles.module.css';
|
||||
|
||||
const Comments = () => {
|
||||
const [comments, setComments] = useState([]);
|
||||
const [newComment, setNewComment] = useState('');
|
||||
const [name, setName] = useState('');
|
||||
const [mounted, setMounted] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
const savedComments = localStorage.getItem('docComments');
|
||||
if (savedComments) {
|
||||
try {
|
||||
setComments(JSON.parse(savedComments));
|
||||
} catch (e) {
|
||||
console.error('Failed to parse comments:', e);
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
const saveComments = (newComments) => {
|
||||
try {
|
||||
localStorage.setItem('docComments', JSON.stringify(newComments));
|
||||
} catch (e) {
|
||||
console.error('Failed to save comments:', e);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
if (!newComment.trim() || !name.trim()) return;
|
||||
|
||||
const comment = {
|
||||
id: Date.now(),
|
||||
name,
|
||||
content: newComment,
|
||||
date: new Date().toLocaleString(),
|
||||
};
|
||||
|
||||
const updatedComments = [...comments, comment];
|
||||
setComments(updatedComments);
|
||||
saveComments(updatedComments);
|
||||
setNewComment('');
|
||||
};
|
||||
|
||||
const handleDelete = (commentId) => {
|
||||
const updatedComments = comments.filter(comment => comment.id !== commentId);
|
||||
setComments(updatedComments);
|
||||
saveComments(updatedComments);
|
||||
};
|
||||
|
||||
if (!mounted) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.commentsContainer}>
|
||||
<h2 className={styles.title}>评论</h2>
|
||||
|
||||
<form onSubmit={handleSubmit} className={styles.form}>
|
||||
<div className={styles.inputGroup}>
|
||||
<input
|
||||
type="text"
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
placeholder="您的名字"
|
||||
className={styles.input}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.inputGroup}>
|
||||
<textarea
|
||||
value={newComment}
|
||||
onChange={(e) => setNewComment(e.target.value)}
|
||||
placeholder="写下您的评论..."
|
||||
className={styles.textarea}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<button type="submit" className={styles.submitButton}>
|
||||
发表评论
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div className={styles.commentsList}>
|
||||
{comments.map((comment) => (
|
||||
<div key={comment.id} className={styles.comment}>
|
||||
<div className={styles.commentHeader}>
|
||||
<span className={styles.commentName}>{comment.name}</span>
|
||||
<div className={styles.commentActions}>
|
||||
<span className={styles.commentDate}>{comment.date}</span>
|
||||
<button
|
||||
onClick={() => handleDelete(comment.id)}
|
||||
className={styles.deleteButton}
|
||||
>
|
||||
删除
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<p className={styles.commentContent}>{comment.content}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Comments;
|
@ -1,114 +0,0 @@
|
||||
.commentsContainer {
|
||||
margin: 2rem 0;
|
||||
padding: 1rem;
|
||||
border-radius: 8px;
|
||||
background-color: var(--ifm-background-color);
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
color: var(--ifm-color-primary);
|
||||
}
|
||||
|
||||
.form {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.inputGroup {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.input,
|
||||
.textarea {
|
||||
width: 100%;
|
||||
padding: 0.75rem;
|
||||
border: 1px solid var(--ifm-color-emphasis-300);
|
||||
border-radius: 4px;
|
||||
background-color: var(--ifm-background-color);
|
||||
color: var(--ifm-color-emphasis-900);
|
||||
font-size: 1rem;
|
||||
transition: border-color 0.2s ease;
|
||||
}
|
||||
|
||||
.input:focus,
|
||||
.textarea:focus {
|
||||
outline: none;
|
||||
border-color: var(--ifm-color-primary);
|
||||
}
|
||||
|
||||
.textarea {
|
||||
min-height: 100px;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
.submitButton {
|
||||
padding: 0.75rem 1.5rem;
|
||||
background-color: var(--ifm-color-primary);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
font-size: 1rem;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.submitButton:hover {
|
||||
background-color: var(--ifm-color-primary-darker);
|
||||
}
|
||||
|
||||
.commentsList {
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.comment {
|
||||
padding: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
border: 1px solid var(--ifm-color-emphasis-300);
|
||||
border-radius: 4px;
|
||||
background-color: var(--ifm-background-color);
|
||||
}
|
||||
|
||||
.commentHeader {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.commentName {
|
||||
font-weight: bold;
|
||||
color: var(--ifm-color-primary);
|
||||
}
|
||||
|
||||
.commentActions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.commentDate {
|
||||
font-size: 0.875rem;
|
||||
color: var(--ifm-color-emphasis-600);
|
||||
}
|
||||
|
||||
.deleteButton {
|
||||
padding: 0.25rem 0.5rem;
|
||||
background-color: var(--ifm-color-danger);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
font-size: 0.875rem;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.deleteButton:hover {
|
||||
background-color: var(--ifm-color-danger-darker);
|
||||
}
|
||||
|
||||
.commentContent {
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
color: var(--ifm-color-emphasis-900);
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
import React from 'react';
|
||||
import clsx from 'clsx';
|
||||
import {useDoc} from '@docusaurus/theme-common/internal';
|
||||
import DocItemContent from '@theme-original/DocItem/Content';
|
||||
import DocItemFooter from '@theme-original/DocItem/Footer';
|
||||
import DocItemPaginator from '@theme-original/DocItem/Paginator';
|
||||
import DocItemTOCMobile from '@theme-original/DocItem/TOC/Mobile';
|
||||
import DocItemTOCDesktop from '@theme-original/DocItem/TOC/Desktop';
|
||||
import DocVersionBadge from '@theme-original/DocVersionBadge';
|
||||
import DocVersionBanner from '@theme-original/DocVersionBanner';
|
||||
import DocBreadcrumbs from '@theme-original/DocBreadcrumbs';
|
||||
import styles from './styles.module.css';
|
||||
import Comments from '@site/src/components/Comments';
|
||||
|
||||
export default function DocItem(props) {
|
||||
const {metadata, frontMatter, assets} = useDoc();
|
||||
const {
|
||||
hide_table_of_contents: hideTableOfContents,
|
||||
toc_min_heading_level: tocMinHeadingLevel,
|
||||
toc_max_heading_level: tocMaxHeadingLevel,
|
||||
} = frontMatter;
|
||||
const {hide_comment_section: hideCommentSection} = frontMatter;
|
||||
|
||||
return (
|
||||
<div className={clsx(styles.docItemContainer, 'container')}>
|
||||
<div className={styles.docItemCol}>
|
||||
<DocVersionBanner />
|
||||
<div className={styles.docItemMain}>
|
||||
<DocBreadcrumbs />
|
||||
<DocVersionBadge />
|
||||
<DocItemContent>
|
||||
<DocItemTOCMobile
|
||||
toc={props.toc}
|
||||
minHeadingLevel={tocMinHeadingLevel}
|
||||
maxHeadingLevel={tocMaxHeadingLevel}
|
||||
/>
|
||||
<DocItemContent {...props} />
|
||||
{!hideCommentSection && <Comments />}
|
||||
</DocItemContent>
|
||||
<DocItemFooter {...props} />
|
||||
</div>
|
||||
<DocItemPaginator />
|
||||
</div>
|
||||
{!hideTableOfContents && props.toc && (
|
||||
<div className="col col--3">
|
||||
<DocItemTOCDesktop
|
||||
toc={props.toc}
|
||||
minHeadingLevel={tocMinHeadingLevel}
|
||||
maxHeadingLevel={tocMaxHeadingLevel}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
.docItemContainer {
|
||||
margin: 0 auto;
|
||||
padding: 0 1rem;
|
||||
}
|
||||
|
||||
.docItemCol {
|
||||
flex: 1 0 75%;
|
||||
max-width: 75%;
|
||||
}
|
||||
|
||||
.docItemMain {
|
||||
flex: 1 0 auto;
|
||||
}
|
||||
|
||||
@media (max-width: 996px) {
|
||||
.docItemCol {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
Loading…
Reference in new issue