From f8cd73795b467634155973afe3edd8f1ab90bfd0 Mon Sep 17 00:00:00 2001 From: thatscringebro Date: Tue, 10 Mar 2026 14:15:40 -0400 Subject: [PATCH] table --- src/app.rs | 15 +++--- src/data_layer.rs | 5 +- src/entities.rs | 4 +- src/entities/transaction.rs | 7 ++- src/entities/{trxlist.rs => trxtable.rs} | 14 +++--- src/ui.rs | 60 ++++++++++-------------- 6 files changed, 47 insertions(+), 58 deletions(-) rename src/entities/{trxlist.rs => trxtable.rs} (76%) diff --git a/src/app.rs b/src/app.rs index 568789e..e56d954 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,4 +1,3 @@ -use ratatui::widgets::ListState; use sqlite::Connection; use crate::{data_layer, entities::*, enums::*}; @@ -7,11 +6,10 @@ pub struct App { pub current_screen: CurrentScreen, pub current_widget: CurrentWidget, pub acc_list: AccountList, - pub trx_list: TrxList, + pub trx_table: TrxTable, pub new_account: Account, pub new_transaction: Transaction, pub connection: Connection, - exit: bool, } impl App { @@ -30,11 +28,10 @@ impl App { current_screen: CurrentScreen::Main, current_widget: CurrentWidget::AccountList, acc_list: AccountList::new(), - trx_list: TrxList::new(), + trx_table: TrxTable::new(), new_account: Account::new(0, String::new(), AccountType::Cash), new_transaction: Transaction::new_empty(), connection: con, - exit: false, }; } @@ -51,16 +48,16 @@ impl App { pub fn get_list_trx(&mut self) -> Vec { let accounts = self - .trx_list + .trx_table .get_trx(self.acc_list.get_selected_id(), &self.connection); return accounts.to_vec(); } pub fn next_tr(&mut self) { - self.trx_list.state.select_next(); + self.trx_table.state.select_next(); } pub fn previous_tr(&mut self) { - self.trx_list.state.select_previous(); + self.trx_table.state.select_previous(); } pub fn save_new_account(&mut self) { @@ -71,7 +68,7 @@ impl App { pub fn save_new_tr(&mut self) { let tr = data_layer::upsert_transaction(&self.connection, self.new_transaction.clone()); - self.trx_list.add_tr(tr); + self.trx_table.add_tr(tr); self.new_transaction = Transaction::new_empty(); } } diff --git a/src/data_layer.rs b/src/data_layer.rs index aa68511..5ba58b1 100644 --- a/src/data_layer.rs +++ b/src/data_layer.rs @@ -101,8 +101,7 @@ pub fn get_accounts(con: &Connection) -> Vec { let mut statement = con.prepare(query).unwrap(); let mut vec = Vec::::new(); - let all = Account::new(0, "All".to_string(), AccountType::Cash); - vec.push(all); + vec.push(Account::new(0, "All".to_string(), AccountType::Cash)); while let Ok(State::Row) = statement.next() { vec.push(Account::new( @@ -209,7 +208,7 @@ pub fn upsert_transaction(con: &Connection, tr: Transaction) -> Transaction { id, tr.get_account().get_id(), tr.get_amount(), - tr.get_date(), + tr.get_date_utc(), tr.get_desc(), tr.get_type().get_id(), con, diff --git a/src/entities.rs b/src/entities.rs index 8da405e..893c1c3 100644 --- a/src/entities.rs +++ b/src/entities.rs @@ -1,9 +1,9 @@ pub mod account; pub mod accountlist; pub mod transaction; -pub mod trxlist; +pub mod trxtable; pub use account::{Account, AccountType}; pub use accountlist::*; pub use transaction::{Transaction, TransactionType}; -pub use trxlist::*; +pub use trxtable::*; diff --git a/src/entities/transaction.rs b/src/entities/transaction.rs index 16522da..e0dd454 100644 --- a/src/entities/transaction.rs +++ b/src/entities/transaction.rs @@ -1,5 +1,5 @@ use crate::{data_layer, entities::Account}; -use chrono::{DateTime, Utc}; +use chrono::{DateTime, Local, TimeZone, Utc}; use sqlite::Connection; #[derive(Clone)] @@ -58,7 +58,10 @@ impl Transaction { return self.amount; } - pub fn get_date(&self) -> DateTime { + pub fn get_date(&self) -> DateTime { + return Local.from_utc_datetime(&self.date.naive_local()); + } + pub fn get_date_utc(&self) -> DateTime { return self.date; } diff --git a/src/entities/trxlist.rs b/src/entities/trxtable.rs similarity index 76% rename from src/entities/trxlist.rs rename to src/entities/trxtable.rs index 7d34128..11a4640 100644 --- a/src/entities/trxlist.rs +++ b/src/entities/trxtable.rs @@ -1,18 +1,18 @@ -use ratatui::widgets::ListState; +use ratatui::widgets::TableState; use sqlite::Connection; use crate::{data_layer, entities::*}; -pub struct TrxList { +pub struct TrxTable { trx: Vec, ac_id: i64, - pub state: ListState, + pub state: TableState, } -impl TrxList { - pub fn new() -> TrxList { - let mut list_state = ListState::default(); +impl TrxTable { + pub fn new() -> TrxTable { + let mut list_state = TableState::default(); list_state.select_first(); - return TrxList { + return TrxTable { trx: Vec::new(), state: list_state, ac_id: 0, diff --git a/src/ui.rs b/src/ui.rs index 8668769..1430c54 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -8,11 +8,12 @@ use ratatui::{ layout::{Constraint, Direction, Layout, Rect}, style::{Color, Modifier, Style, Stylize, palette::tailwind::SLATE}, text::{Line, Text}, - widgets::{Block, Borders, HighlightSpacing, List, ListItem, Paragraph, StatefulWidget, Wrap}, + widgets::{ + Block, Borders, HighlightSpacing, List, ListItem, Paragraph, Row, StatefulWidget, Table, + Wrap, + }, }; -const NORMAL_ROW_BG: Color = SLATE.c950; -const ALT_ROW_BG_COLOR: Color = SLATE.c900; const TEXT_FG_COLOR: Color = SLATE.c200; const SELECTED_STYLE: Style = Style::new().bg(SLATE.c800).add_modifier(Modifier::BOLD); @@ -48,10 +49,7 @@ pub fn ui(frame: &mut Frame, app: &mut App) { .get_list_accounts() .iter() .enumerate() - .map(|(i, acc)| { - let color = alternate_colors(i); - ListItem::from(acc).bg(color) - }) + .map(|(i, acc)| ListItem::from(acc)) .collect(); let list = List::new(ac_items) @@ -74,27 +72,32 @@ pub fn ui(frame: &mut Frame, app: &mut App) { }; frame.render_widget(Paragraph::new(info).block(info_block), right_layout[0]); - let trx_items: Vec = app - .get_list_trx() - .iter() - .enumerate() - .map(|(i, tr)| { - let color = alternate_colors(i); - ListItem::from(tr).bg(color) - }) - .collect(); - - let trx_list = List::new(trx_items) + let trx_header = Row::new(["Date", "Amount", "Description"]); + let trx_rows = app.get_list_trx().into_iter().map(|tr| { + Row::new([ + tr.get_date().format("%Y-%m-%d").to_string(), + tr.get_amount().to_string(), + tr.get_desc(), + ]) + }); + let widths = [ + Constraint::Percentage(30), + Constraint::Percentage(20), + Constraint::Percentage(50), + ]; + let trx_table = Table::new(trx_rows, widths) .block(trx_block) - .highlight_style(SELECTED_STYLE) + .header(trx_header) + .row_highlight_style(SELECTED_STYLE) .highlight_symbol(">") - .highlight_spacing(HighlightSpacing::Always); + .highlight_spacing(HighlightSpacing::Always) + .column_spacing(1); StatefulWidget::render( - trx_list, + trx_table, right_layout[1], frame.buffer_mut(), - &mut app.trx_list.state, + &mut app.trx_table.state, ); if let CurrentScreen::NewAccount = app.current_screen { @@ -156,13 +159,6 @@ fn centered_rect(percent_x: u16, percent_y: u16, r: Rect) -> Rect { ]) .split(popup_layout[1])[1]; } -const fn alternate_colors(i: usize) -> Color { - if i % 2 == 0 { - NORMAL_ROW_BG - } else { - ALT_ROW_BG_COLOR - } -} impl From<&Account> for ListItem<'_> { fn from(value: &Account) -> Self { @@ -173,9 +169,3 @@ impl From<&Account> for ListItem<'_> { ListItem::new(line) } } -impl From<&Transaction> for ListItem<'_> { - fn from(value: &Transaction) -> Self { - let line = Line::styled(value.get_desc(), TEXT_FG_COLOR); - ListItem::new(line) - } -}