Skip to content

Commit 06d4ee9

Browse files
author
CodeJudge
committed
feat: 首页最近提交动态
1 parent c231c2c commit 06d4ee9

3 files changed

Lines changed: 60 additions & 2 deletions

File tree

backend/src/routes/auth.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,18 @@ router.get('/language-stats', authenticate, (req, res) => {
4444
res.json({ languages: stats });
4545
});
4646

47+
router.get('/recent-submissions', authenticate, (req, res) => {
48+
const rows = queryAll(`
49+
SELECT s.id, s.problem_id, s.status, s.score, s.created_at, p.title as problem_title
50+
FROM submissions s
51+
JOIN problems p ON p.id = s.problem_id
52+
WHERE s.user_id = ?
53+
ORDER BY s.created_at DESC
54+
LIMIT 5
55+
`, [req.user.id]);
56+
res.json({ submissions: rows });
57+
});
58+
4759
router.get('/leaderboard', async (req, res) => {
4860
try {
4961
const rows = queryAll(`

frontend/src/pages/Home.tsx

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { useState, useEffect } from 'react';
22
import { Link } from 'react-router-dom';
3-
import { Code2, ListChecks, PenLine, ArrowRight, BookOpen, Sparkles, Zap, Flame, Calendar } from 'lucide-react';
3+
import { Code2, ListChecks, PenLine, ArrowRight, BookOpen, Sparkles, Zap, Flame, Calendar, CheckCircle, AlertTriangle, Clock, RefreshCw } from 'lucide-react';
44
import { useAuth } from '../context/AuthContext';
55
import api from '../services/api';
66
import { useDocumentTitle } from '../hooks/useDocumentTitle';
77
import ProblemCard from '../components/ProblemCard';
8+
import SubmissionStatus from '../components/SubmissionStatus';
89
import type { ProblemStats, Problem } from '../types';
910

1011
function AnimatedNumber({ target }: { target: number }) {
@@ -47,6 +48,8 @@ export default function Home() {
4748
const [recentProblems, setRecentProblems] = useState<Problem[]>([]);
4849
const [daily, setDaily] = useState<{ problem: Problem; date: string } | null>(null);
4950
const [dailyLoading, setDailyLoading] = useState(true);
51+
const [recentSubmissions, setRecentSubmissions] = useState<any[]>([]);
52+
const [submissionsLoading, setSubmissionsLoading] = useState(true);
5053

5154
useEffect(() => {
5255
api.problems.stats().then(setStats).catch(() => {});
@@ -63,7 +66,14 @@ export default function Home() {
6366
})
6467
.catch(() => {})
6568
.finally(() => setDailyLoading(false));
66-
}, []);
69+
if (user) {
70+
api.auth.recentSubmissions().then(res => {
71+
if (res.submissions) setRecentSubmissions(res.submissions);
72+
}).catch(() => {}).finally(() => setSubmissionsLoading(false));
73+
} else {
74+
setSubmissionsLoading(false);
75+
}
76+
}, [user]);
6777

6878
const tagCounts: Record<string, number> = {};
6979
recentProblems.forEach((p) => {
@@ -188,6 +198,41 @@ export default function Home() {
188198
</div>
189199
</section>
190200

201+
{/* Recent Submissions */}
202+
{user && (recentSubmissions.length > 0 || submissionsLoading) && (
203+
<section className="pb-16">
204+
<div className="flex items-center justify-between mb-6">
205+
<h2 className="text-xl font-bold text-white">最近提交</h2>
206+
<Link to="/submissions" className="text-sm text-primary-400 hover:text-primary-300 inline-flex items-center gap-1 transition-colors">
207+
查看全部 <ArrowRight size={14} />
208+
</Link>
209+
</div>
210+
<div className="space-y-2">
211+
{submissionsLoading ? (
212+
Array.from({ length: 3 }).map((_, i) => (
213+
<div key={i} className="card p-4 animate-pulse flex items-center gap-4">
214+
<div className="w-6 h-6 bg-dark-700 rounded" />
215+
<div className="h-4 bg-dark-700 rounded w-1/3" />
216+
<div className="h-4 bg-dark-700 rounded w-1/6 ml-auto" />
217+
</div>
218+
))
219+
) : (
220+
recentSubmissions.map((s: any) => (
221+
<Link
222+
key={s.id}
223+
to={`/submissions`}
224+
className="card p-4 flex items-center gap-4 hover:border-primary-500/40 transition-all duration-200"
225+
>
226+
<SubmissionStatus status={s.status} score={s.score} />
227+
<span className="flex-1 text-white text-sm truncate">{s.problem_title}</span>
228+
<span className="text-xs text-dark-400">{s.created_at?.slice(0, 16).replace('T', ' ')}</span>
229+
</Link>
230+
))
231+
)}
232+
</div>
233+
</section>
234+
)}
235+
191236
{/* Recent Problems */}
192237
{recentProblems.length > 0 && (
193238
<section className="pb-16">

frontend/src/services/api.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ const api = {
3737
leaderboard: () => request<any[]>('/auth/leaderboard'),
3838
changePassword: (body: { currentPassword: string; newPassword: string }) =>
3939
request<{ message: string }>('/auth/password', { method: 'PUT', body: JSON.stringify(body) }),
40+
recentSubmissions: () => request<{ submissions: any[] }>('/auth/recent-submissions'),
4041
},
4142

4243
problems: {

0 commit comments

Comments
 (0)