11import { useState , useEffect } from 'react' ;
22import { 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' ;
44import { useAuth } from '../context/AuthContext' ;
55import api from '../services/api' ;
66import { useDocumentTitle } from '../hooks/useDocumentTitle' ;
77import ProblemCard from '../components/ProblemCard' ;
8+ import SubmissionStatus from '../components/SubmissionStatus' ;
89import type { ProblemStats , Problem } from '../types' ;
910
1011function 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" >
0 commit comments