@@ -4,24 +4,64 @@ import api from '../api';
44import SEO from '../components/SEO' ;
55import PluginCard from '../components/PluginCard' ;
66
7+ // Global cache to persist data across component unmounts (navigation)
8+ // This allows the page to render immediately when going "back",
9+ // which is required for the browser to restore scroll position.
10+ let homeCache : {
11+ topPaid : any [ ] ;
12+ popular : any [ ] ;
13+ newest : any [ ] ;
14+ } | null = null ;
15+
716const Home = ( ) => {
817 const { t } = useTranslation ( ) ;
9- const [ plugins , setPlugins ] = useState < any [ ] > ( [ ] ) ;
10- const hasFetched = useRef ( false ) ;
18+ const [ topPaid , setTopPaid ] = useState < any [ ] > ( homeCache ?. topPaid || [ ] ) ;
19+ const [ popular , setPopular ] = useState < any [ ] > ( homeCache ?. popular || [ ] ) ;
20+ const [ newest , setNewest ] = useState < any [ ] > ( homeCache ?. newest || [ ] ) ;
21+ const [ loading , setLoading ] = useState ( ! homeCache ) ;
22+ const hasFetched = useRef ( ! ! homeCache ) ;
1123
1224 useEffect ( ( ) => {
1325 if ( hasFetched . current ) return ;
14- api . get ( '/plugins' , { params : { q : '' , sort : 'newest' } } )
15- . then ( res => {
16- setPlugins ( Array . isArray ( res . data ) ? res . data : [ ] ) ;
26+
27+ const fetchSections = async ( ) => {
28+ try {
29+ const [ topPaidRes , popularRes , newestRes ] = await Promise . all ( [
30+ api . get ( '/plugins' , { params : { type : 'paid' , sort : 'downloads' , limit : 4 } } ) ,
31+ api . get ( '/plugins' , { params : { sort : 'downloads' , limit : 8 } } ) ,
32+ api . get ( '/plugins' , { params : { sort : 'newest' , limit : 12 } } )
33+ ] ) ;
34+
35+ const data = {
36+ topPaid : Array . isArray ( topPaidRes . data ) ? topPaidRes . data : [ ] ,
37+ popular : Array . isArray ( popularRes . data ) ? popularRes . data : [ ] ,
38+ newest : Array . isArray ( newestRes . data ) ? newestRes . data : [ ]
39+ } ;
40+
41+ setTopPaid ( data . topPaid ) ;
42+ setPopular ( data . popular ) ;
43+ setNewest ( data . newest ) ;
44+ homeCache = data ;
1745 hasFetched . current = true ;
18- } )
19- . catch ( err => {
46+ } catch ( err ) {
2047 console . error ( 'Fetch error:' , err ) ;
21- setPlugins ( [ ] ) ;
22- } ) ;
48+ } finally {
49+ setLoading ( false ) ;
50+ }
51+ } ;
52+
53+ fetchSections ( ) ;
2354 } , [ ] ) ;
2455
56+ if ( loading ) {
57+ return (
58+ < div className = "loading-state" >
59+ < div className = "spinner" > </ div >
60+ < p > Discovering best plugins...</ p >
61+ </ div >
62+ ) ;
63+ }
64+
2565 return (
2666 < >
2767 < SEO
@@ -35,17 +75,40 @@ const Home = () => {
3575 </ section >
3676
3777 < div className = "container" id = "browse" >
38- < div className = "home-plugin-grid" >
39- { plugins . map ( ( plugin ) => (
40- < PluginCard key = { plugin . id } plugin = { plugin } />
41- ) ) }
42-
43- { plugins . length === 0 && (
44- < div className = "empty-state" >
45- < p > No plugins found. Check back later!</ p >
78+ { topPaid . length > 0 && (
79+ < section className = "home-section" >
80+ < h2 className = "section-title" > < span > Top</ span > Premium</ h2 >
81+ < div className = "home-plugin-grid" >
82+ { topPaid . map ( ( plugin ) => (
83+ < PluginCard key = { `top-${ plugin . id } ` } plugin = { plugin } />
84+ ) ) }
4685 </ div >
47- ) }
48- </ div >
86+ </ section >
87+ ) }
88+
89+ < section className = "home-section" >
90+ < h2 className = "section-title" > < span > Most</ span > Popular</ h2 >
91+ < div className = "home-plugin-grid" >
92+ { popular . map ( ( plugin ) => (
93+ < PluginCard key = { `pop-${ plugin . id } ` } plugin = { plugin } />
94+ ) ) }
95+ </ div >
96+ </ section >
97+
98+ < section className = "home-section" >
99+ < h2 className = "section-title" > < span > New</ span > & Trending </ h2 >
100+ < div className = "home-plugin-grid" >
101+ { newest . map ( ( plugin ) => (
102+ < PluginCard key = { `new-${ plugin . id } ` } plugin = { plugin } />
103+ ) ) }
104+ </ div >
105+ </ section >
106+
107+ { topPaid . length === 0 && popular . length === 0 && newest . length === 0 && (
108+ < div className = "empty-state" >
109+ < p > No plugins found. Check back later!</ p >
110+ </ div >
111+ ) }
49112 </ div >
50113 </ >
51114 ) ;
0 commit comments