Skip to content

Commit 6d8e3e2

Browse files
author
CodeJudge
committed
feat: 代码复制 + 答题进度条
1 parent 585490c commit 6d8e3e2

2 files changed

Lines changed: 40 additions & 6 deletions

File tree

frontend/src/pages/Problems.tsx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import toast from 'react-hot-toast';
2020
import api from '../services/api';
2121
import ProblemCard from '../components/ProblemCard';
2222
import type { Problem, PaginatedResponse, ProblemStats } from '../types';
23+
import { useAuth } from '../context/AuthContext';
2324
import { useBookmarks } from '../context/BookmarkContext';
2425
import { useDocumentTitle } from '../hooks/useDocumentTitle';
2526

@@ -66,6 +67,9 @@ export default function Problems() {
6667
const [jumpPage, setJumpPage] = useState('');
6768
const [bookmarkFilter, setBookmarkFilter] = useState(false);
6869
const { isBookmarked } = useBookmarks();
70+
const { user } = useAuth();
71+
const [userStats, setUserStats] = useState<{ accepted: number } | null>(null);
72+
const totalProblems = stats?.total ?? 0;
6973

7074
const fetchStats = useCallback(async () => {
7175
try {
@@ -90,6 +94,15 @@ export default function Problems() {
9094
fetchTags();
9195
}, [fetchStats, fetchTags]);
9296

97+
useEffect(() => {
98+
if (!user) return;
99+
api.auth.profile().then((res: any) => {
100+
if (res?.accepted_count != null) {
101+
setUserStats({ accepted: res.accepted_count });
102+
}
103+
}).catch(() => {});
104+
}, [user]);
105+
93106
const fetchProblems = useCallback(async () => {
94107
setLoading(true);
95108
setError(null);
@@ -256,6 +269,22 @@ export default function Problems() {
256269
</div>
257270
)}
258271

272+
{/* Completion Progress */}
273+
{user && userStats && (
274+
<div className="card p-4 mb-4">
275+
<div className="flex items-center justify-between mb-2">
276+
<h3 className="text-sm font-medium text-dark-200">答题进度</h3>
277+
<span className="text-xs text-dark-400">{userStats.accepted} / {totalProblems} 通过</span>
278+
</div>
279+
<div className="h-2 bg-dark-700 rounded-full overflow-hidden">
280+
<div
281+
className="h-full bg-gradient-to-r from-primary-500 to-emerald-500 rounded-full transition-all duration-500"
282+
style={{ width: `${totalProblems > 0 ? Math.min(100, (userStats.accepted / totalProblems) * 100) : 0}%` }}
283+
/>
284+
</div>
285+
</div>
286+
)}
287+
259288
{/* Filters & Page Size */}
260289
<div className="flex flex-wrap items-center gap-4 mb-6">
261290
<div className="flex gap-1">

frontend/src/pages/Submissions.tsx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
CheckCircle,
1313
Code,
1414
Award,
15+
Clipboard,
1516
} from 'lucide-react';
1617
import toast from 'react-hot-toast';
1718
import api from '../services/api';
@@ -260,12 +261,16 @@ export default function Submissions() {
260261
<div className="px-4 pb-4 mt-2 border-t border-dark-700 pt-3">
261262
{submission.code && (
262263
<div className="mb-3">
263-
<p className="text-xs text-gray-500 mb-1">
264-
提交代码
265-
</p>
266-
<pre className="bg-dark-900 rounded p-3 text-sm text-gray-300 overflow-auto max-h-60">
267-
{submission.code}
268-
</pre>
264+
<div className="flex items-center justify-between mb-1">
265+
<p className="text-xs text-dark-500">提交代码</p>
266+
<button
267+
onClick={() => { navigator.clipboard.writeText(submission.code); toast.success('代码已复制'); }}
268+
className="flex items-center gap-1 text-xs text-dark-400 hover:text-white transition-colors"
269+
>
270+
<Clipboard className="w-3.5 h-3.5" /> 复制
271+
</button>
272+
</div>
273+
<pre className="bg-dark-900 rounded p-3 text-sm text-dark-300 overflow-auto max-h-60">{submission.code}</pre>
269274
</div>
270275
)}
271276

0 commit comments

Comments
 (0)