@ -1,11 +1,10 @@
use perseus ::{ navigate , Html , RenderFnResult , RenderFnResultWithCause , SsrNode , Template } ;
use perseus ::prelude ::* ;
use serde ::{ Deserialize , Serialize } ;
use sycamore ::prelude ::* ;
use crate ::{
api ::{
routes ::transaction ::get_transactions ,
types ::{ company ::Company , transaction ::TransactionCompany } ,
} ,
api ::routes ::transaction ::get_transactions ,
api ::types ::{ company ::Company , transaction ::TransactionCompany } ,
components ::{
base_async_select ::{ AsyncSelectRx , BaseAsyncSelect } ,
base_button ::{ BaseButton , BaseButtonStateRx } ,
@ -14,68 +13,69 @@ use crate::{
global_state ::AppStateRx ,
} ;
#[ perseus::make_rx(IndexPageStateRx) ]
#[ derive(Serialize, Deserialize, Clone, ReactiveState) ]
#[ rx(alias = " IndexPageStateRx " ) ]
pub struct IndexPageState {
pub company_slug : String ,
}
#[ perseus::template_rx ]
pub fn index_page (
IndexPageStateRx { company_slug } : IndexPageStateRx ,
global_state : AppStateRx ,
) -> View < G > {
let dark_mode = global_state . dark_mode ;
#[ auto_scope ]
fn index_page < G : Html > ( cx : Scope , state : & IndexPageStateRx ) -> View < G > {
let global_state = Reactor ::< G > ::from_cx ( cx ) . get_global_state ::< AppStateRx > ( cx ) ;
let dark_mode = & global_state . dark_mode ;
let dark_mode_2 = dark_mode . clone ( ) ;
let dark_mode_3 = dark_mode . clone ( ) ;
let expand = Signal::new ( false ) ;
let expand = create_signal( cx , false ) ;
let filter_expand = BaseButtonStateRx {
label : Signal::new ( "Filters" . to_string ( ) ) . handle ( ) ,
disabled : Signal::new ( false ) . handle ( ) ,
clicked : Signal::new ( false ) ,
label : create_signal( cx , "Filters" . to_string ( ) ) ,
disabled : create_signal( cx , false ) ,
clicked : create_signal( cx , false ) ,
} ;
create_effect ( c loned! ( ( filter_e xpand , expand ) = > move | | {
create_effect ( c x, move | | {
if * filter_expand . clicked . get ( ) {
filter_expand . clicked . set ( false ) ;
expand . set ( ! * expand . get ( ) ) ;
}
} ) ) ;
} ) ;
let toggle_dark_mode = cloned ! ( ( ) = > move | _ | dark_mode_2 . set ( ! * dark_mode . get ( ) ) ) ;
let toggle_dark_mode = move | _ | dark_mode_2 . set ( ! * dark_mode . get ( ) ) ;
let paginated_table_state : PaginatedTableStateRx < TransactionCompany , _ , _ > =
PaginatedTableStateRx {
route : get_transactions ,
filter : if ( * company_slug. get ( ) ) . is_empty ( ) {
filter : if ( * state. company_slug. get ( ) ) . is_empty ( ) {
None
} else {
Some ( ( * company_slug. get ( ) ) . clone ( ) )
Some ( ( * state. company_slug. get ( ) ) . clone ( ) )
} ,
} ;
let async_select_prop : AsyncSelectRx < Company > = AsyncSelectRx {
remote_list : Signal::new ( format! ( "{}company/" , global_state . config . get ( ) . api_url ) ) . handle ( ) ,
selected_item : Signal::new ( None ) ,
remote_list : create_signal( cx , format! ( "{}company/" , "http://localhost:8000/v1/" ) ) ,
selected_item : create_signal( cx , None ) ,
} ;
let async_select_prop2 = async_select_prop . clone ( ) ;
let search_button = BaseButtonStateRx {
label : Signal ::new ( "Search" . to_string ( ) ) . handle ( ) ,
disabled : create_memo ( cloned ! ( ( async_select_prop ) = > move | | {
async_select_prop . selected_item . get ( ) . is_none ( )
} ) ) ,
clicked : Signal ::new ( false ) ,
label : create_signal ( cx , "Search" . to_string ( ) ) ,
disabled : create_memo ( cx , move | | async_select_prop . selected_item . get ( ) . is_none ( ) ) ,
clicked : create_signal ( cx , false ) ,
} ;
create_effect ( c loned! ( ( search_button ) = > move | | {
create_effect ( c x, | | {
if * search_button . clicked . get ( ) {
search_button . clicked . set ( false ) ;
navigate ( & format! ( "/index/{}" , ( * async_select_prop2 . selected_item . get ( ) ) . clone ( ) . map_or ( "" . to_string ( ) , | c | c . slug ) ) ) ;
}
} ) ) ;
navigate ( & format! (
"/{}" ,
( * async_select_prop . selected_item . get ( ) )
. clone ( )
. map_or ( "" . to_string ( ) , | c | c . slug )
) ) ;
}
} ) ;
view ! {
view ! { cx ,
main ( class = if * dark_mode_3 . get ( ) { "dark" } else { "" } ) {
div ( class = "bg-slate-200 dark:bg-slate-700 text-slate-700 dark:text-slate-100 font-sans" ) {
header ( class = "shadow-md h-12 p-2 align-middle w-full bg-gray-100 dark:bg-slate-500/30 backdrop-blur-lg" ) {
@ -101,7 +101,7 @@ pub fn index_page(
}
}
BaseButton ( filter_expand )
div ( ) { } // Without this useless div, the code doesn't run in the browser
div { } // Without this useless div, the code doesn't run in the browser
div ( id = "filters" , class = format! ( "p-2 border rounded-lg border-slate-200 dark:border-slate-800 bg-slate-200 dark:bg-slate-700 transition-all ease-in {}" ,
if * expand . get ( ) { "h-40 visible" } else { "h-0 collapse" } ,
)
@ -122,30 +122,38 @@ pub fn index_page(
}
pub fn get_template < G : Html > ( ) -> Template < G > {
Template ::new ( "index" )
. build_paths_fn( get_build_paths )
Template ::build ( "index" )
. head( head )
. build_state_fn ( get_build_state )
. template( index_page )
. build_paths_fn( get_build_paths )
. incremental_generation ( )
. head ( head )
. view_with_state ( index_page )
. build ( )
}
#[ perseus::head ]
pub fn head ( _props : IndexPageStat e) -> View < SsrNode > {
view ! {
#[ engine_only_fn ]
fn head ( cx : Scop e) -> View < SsrNode > {
view ! { cx ,
title { "Fast Insiders" }
}
}
#[ perseus::autoserde(build_state) ]
pub async fn get_build_state (
path : String ,
_locale : String ,
) -> RenderFnResultWithCause < IndexPageState > {
let company_slug : String = path . clone ( ) . drain ( "index" . len ( ) .. ) . collect ( ) ;
#[ engine_only_fn ]
async fn get_build_state (
StateGeneratorInfo { path , .. } : StateGeneratorInfo < ( ) > ,
) -> Result < IndexPageState , BlamedError < std ::io ::Error > > {
let company_slug : String = path
. split ( "transactions" )
. nth ( 1 )
. unwrap_or ( & ( "/" . to_owned ( ) + & path ) )
. to_string ( ) ;
Ok ( IndexPageState { company_slug } )
}
pub async fn get_build_paths ( ) -> RenderFnResult < Vec < String > > {
Ok ( vec! [ "" . to_string ( ) ] )
#[ engine_only_fn ]
async fn get_build_paths ( ) -> BuildPaths {
BuildPaths {
paths : vec ! [ "" . to_string ( ) ] ,
extra : ( ) . into ( ) ,
}
}