You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
4.8 KiB
138 lines
4.8 KiB
use perseus::prelude::*;
|
|
use serde::{Deserialize, Serialize};
|
|
use sycamore::prelude::*;
|
|
|
|
use crate::{
|
|
api::routes::transaction::get_transactions,
|
|
api::types::{company::Company, transaction::TransactionCompany},
|
|
components::{
|
|
base_async_select::{AsyncSelectRx, BaseAsyncSelect},
|
|
base_button::{BaseButton, BaseButtonStateRx},
|
|
main_content_container::MainContentContainer,
|
|
paginated_data_table::{PaginatedTable, PaginatedTableStateRx},
|
|
the_header::TheHeader,
|
|
},
|
|
global_state::AppStateRx,
|
|
};
|
|
|
|
#[derive(Serialize, Deserialize, Clone, ReactiveState)]
|
|
#[rx(alias = "TransactionsPageStateRx")]
|
|
pub struct TransactionsPageState {
|
|
pub company_slug: Option<String>,
|
|
}
|
|
|
|
#[auto_scope]
|
|
fn transactions_page<G: Html>(cx: Scope, state: &TransactionsPageStateRx) -> View<G> {
|
|
let global_state = Reactor::<G>::from_cx(cx).get_global_state::<AppStateRx>(cx);
|
|
let dark_mode = &global_state.dark_mode;
|
|
|
|
let expand = create_signal(cx, false);
|
|
let filter_expand = BaseButtonStateRx {
|
|
label: create_signal(cx, "Filters".to_string()),
|
|
disabled: create_signal(cx, false),
|
|
clicked: create_signal(cx, false),
|
|
};
|
|
|
|
create_effect(cx, move || {
|
|
if *filter_expand.clicked.get() {
|
|
filter_expand.clicked.set(false);
|
|
expand.set(!*expand.get());
|
|
}
|
|
});
|
|
|
|
let paginated_table_state: PaginatedTableStateRx<TransactionCompany, _, _> =
|
|
PaginatedTableStateRx {
|
|
record_label: "transactions".to_owned(),
|
|
route: get_transactions,
|
|
filter: (*state.company_slug.get()).clone(),
|
|
table_class: create_ref(cx, "".to_string()),
|
|
};
|
|
|
|
let async_select_prop: AsyncSelectRx<Company> = AsyncSelectRx {
|
|
remote_list: create_signal(cx, format!("{}company/", "http://localhost:8000/v1/")),
|
|
selected_item: create_signal(cx, None),
|
|
};
|
|
|
|
let search_button = BaseButtonStateRx {
|
|
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(cx, || {
|
|
if *search_button.clicked.get() {
|
|
search_button.clicked.set(false);
|
|
navigate(&format!(
|
|
"/transactions/{}",
|
|
(*async_select_prop.selected_item.get())
|
|
.clone()
|
|
.map_or("".to_string(), |c| c.slug)
|
|
));
|
|
}
|
|
});
|
|
|
|
view! {cx,
|
|
main (class=if *dark_mode.get() { "dark" } else { "" }) {
|
|
div (class="bg-slate-200 dark:bg-slate-700 text-slate-700 dark:text-slate-100 font-sans") {
|
|
TheHeader()
|
|
MainContentContainer(useless_prop=1) {
|
|
a (class="hover:underline", href="/transactions") {
|
|
h1 (
|
|
class="text-center text-lg"
|
|
) {
|
|
"Insider Transactions published by the AMF"
|
|
}
|
|
}
|
|
BaseButton(filter_expand)
|
|
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" },
|
|
)
|
|
)
|
|
{
|
|
div (class="w-80") {
|
|
p () {"Search for a company:"}
|
|
BaseAsyncSelect(async_select_prop)
|
|
BaseButton(search_button)
|
|
}
|
|
}
|
|
PaginatedTable(paginated_table_state)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn get_template<G: Html>() -> Template<G> {
|
|
Template::build("transactions")
|
|
.head(head)
|
|
.build_state_fn(get_build_state)
|
|
.build_paths_fn(get_build_paths)
|
|
.incremental_generation()
|
|
.view_with_state(transactions_page)
|
|
.build()
|
|
}
|
|
|
|
#[engine_only_fn]
|
|
fn head(cx: Scope) -> View<SsrNode> {
|
|
view! {cx,
|
|
title { "Fast Insiders" }
|
|
}
|
|
}
|
|
|
|
#[engine_only_fn]
|
|
async fn get_build_state(
|
|
StateGeneratorInfo { path, .. }: StateGeneratorInfo<()>,
|
|
) -> Result<TransactionsPageState, BlamedError<std::io::Error>> {
|
|
let company_slug = if path.is_empty() { None } else { Some(path) };
|
|
Ok(TransactionsPageState { company_slug })
|
|
}
|
|
|
|
#[engine_only_fn]
|
|
async fn get_build_paths() -> BuildPaths {
|
|
BuildPaths {
|
|
paths: vec!["".to_string()],
|
|
extra: ().into(),
|
|
}
|
|
}
|