1- use leptos:: { prelude:: * , serde_json} ;
1+ use leptos:: prelude:: * ;
2+ #[ cfg( feature = "ssr" ) ]
3+ use leptos:: serde_json;
24
35use crate :: components:: ContributorCard ;
46#[ cfg( feature = "ssr" ) ]
@@ -97,7 +99,7 @@ pub struct Contributor {
9799 pub contributions : u64 ,
98100}
99101
100- #[ derive( Clone , Debug , PartialEq , Eq , Serialize , Deserialize ) ]
102+ #[ derive( Clone , Debug , Default , PartialEq , Eq , Serialize , Deserialize ) ]
101103pub struct ContributorsResponse {
102104 pub contributors : Vec < Contributor > ,
103105 pub total : usize ,
@@ -156,9 +158,10 @@ pub async fn load_contributors() -> ContributorsResponse {
156158 }
157159 #[ cfg( not( feature = "ssr" ) ) ]
158160 {
159- ContributorsResponse {
160- contributors : vec ! [ ] ,
161- total : 0 ,
161+ use gloo_net:: http:: Request ;
162+ match Request :: get ( "/contributors.json" ) . send ( ) . await {
163+ Ok ( resp) => resp. json :: < ContributorsResponse > ( ) . await . unwrap_or_default ( ) ,
164+ Err ( _) => ContributorsResponse :: default ( ) ,
162165 }
163166 }
164167}
@@ -171,6 +174,10 @@ async fn fetch_contributors() -> ContributorsResponse {
171174 if let Ok ( contents) = std:: fs:: read_to_string ( CONTRIBUTORS_CACHE_PATH ) {
172175 if let Ok ( cached) = serde_json:: from_str :: < ContributorsResponse > ( & contents) {
173176 println ! ( "Loaded {} contributors from cache ({})" , cached. total, CONTRIBUTORS_CACHE_PATH ) ;
177+ let dist_path = std:: env:: var ( "LEPTOS_SITE_ROOT" ) . unwrap_or_else ( |_| "dist" . to_string ( ) ) ;
178+ let _ = std:: fs:: create_dir_all ( & dist_path) ;
179+ let json_path = format ! ( "{}/contributors.json" , dist_path) ;
180+ let _ = std:: fs:: write ( & json_path, & contents) ;
174181 return cached;
175182 }
176183 }
@@ -200,6 +207,16 @@ async fn fetch_contributors() -> ContributorsResponse {
200207 }
201208 }
202209
210+ if let Ok ( json) = serde_json:: to_string ( & response) {
211+ let dist_path = std:: env:: var ( "LEPTOS_SITE_ROOT" ) . unwrap_or_else ( |_| "dist" . to_string ( ) ) ;
212+ let _ = std:: fs:: create_dir_all ( & dist_path) ;
213+ let json_path = format ! ( "{}/contributors.json" , dist_path) ;
214+ match std:: fs:: write ( & json_path, & json) {
215+ Ok ( _) => println ! ( "Wrote contributors to {}" , json_path) ,
216+ Err ( e) => eprintln ! ( "Failed to write {}: {}" , json_path, e) ,
217+ }
218+ }
219+
203220 response
204221}
205222
@@ -431,6 +448,8 @@ async fn fetch_user_profiles_batch(
431448
432449#[ component]
433450pub fn Contributors ( ) -> impl IntoView {
451+ let contributors = LocalResource :: new ( || load_contributors ( ) ) ;
452+
434453 view ! {
435454 <section class="bg-orange-300/30 dark:bg-transparent py-16 min-h-[80vh]" >
436455 <div class="flex flex-col gap-y-6 container mx-auto px-4" >
@@ -452,25 +471,31 @@ pub fn Contributors() -> impl IntoView {
452471 , podemos seguir construyendo un ecosistema Rust más fuerte y accesible para todos.
453472 </p>
454473 <div class="mt-6 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-5 gap-6" >
455- <Await future=load_contributors( ) let : res>
456- { res
457- . contributors
458- . iter( )
459- . map( |item| {
460- view! {
461- <ContributorCard
462- name=item. login. clone( )
463- description=item. bio. clone( )
464- link=item. url. clone( )
465- brand_src=item. avatar_url. clone( )
466- twitter=item. twitter_username. clone( )
467- location=item. location. clone( )
468- contributions=item. contributions
469- />
470- }
471- } )
472- . collect:: <Vec <_>>( ) }
473- </Await >
474+ <Suspense fallback=|| ( ) >
475+ { move || {
476+ contributors
477+ . get( )
478+ . map( |res| {
479+ res. contributors
480+ . clone( )
481+ . into_iter( )
482+ . map( |item| {
483+ view! {
484+ <ContributorCard
485+ name=item. login. clone( )
486+ description=item. bio. clone( )
487+ link=item. url. clone( )
488+ brand_src=item. avatar_url. clone( )
489+ twitter=item. twitter_username. clone( )
490+ location=item. location. clone( )
491+ contributions=item. contributions
492+ />
493+ }
494+ } )
495+ . collect:: <Vec <_>>( )
496+ } )
497+ } }
498+ </Suspense >
474499 </div>
475500 </div>
476501 </section>
0 commit comments