From bfcceff28544022d560b56c08ec67c1d671ed981 Mon Sep 17 00:00:00 2001 From: Grant Azure Date: Sat, 28 Feb 2026 11:00:54 -0800 Subject: [PATCH] [arenabuddy] dark mode default --- Cargo.toml | 5 +- .../arenabuddy/src/app/components/cost.rs | 2 +- .../src/app/components/deck_list.rs | 20 +++---- .../src/app/components/event_log.rs | 42 +++++++------- .../src/app/components/match_info.rs | 20 +++---- .../src/app/components/mulligan_display.rs | 20 +++---- .../src/app/components/pagination.rs | 10 ++-- arenabuddy/arenabuddy/src/app/debug_logs.rs | 20 +++---- .../arenabuddy/src/app/draft_details.rs | 56 +++++++++---------- arenabuddy/arenabuddy/src/app/drafts.rs | 32 +++++------ arenabuddy/arenabuddy/src/app/error_logs.rs | 22 ++++---- .../arenabuddy/src/app/match_details.rs | 26 ++++----- arenabuddy/arenabuddy/src/app/matches.rs | 30 +++++----- arenabuddy/arenabuddy/src/app/pages.rs | 36 ++++++------ arenabuddy/arenabuddy/src/app/stats.rs | 34 +++++------ arenabuddy/arenabuddy/src/backend/sync.rs | 2 +- arenabuddy/arenabuddy/tailwind.css | 5 ++ 17 files changed, 195 insertions(+), 187 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6b13c0db..4a2638ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -86,7 +86,10 @@ tracing-appender = "0.2.4" tracing-opentelemetry = "0.32.1" opentelemetry = "0.31.0" opentelemetry_sdk = { version = "0.31.0", features = ["rt-tokio"] } -opentelemetry-otlp = { version = "0.31.0", default-features = false, features = ["grpc-tonic", "trace"] } +opentelemetry-otlp = { version = "0.31.0", default-features = false, features = [ + "grpc-tonic", + "trace", +] } reqwest = { version = "0.13.2", features = [ "form", "json", diff --git a/arenabuddy/arenabuddy/src/app/components/cost.rs b/arenabuddy/arenabuddy/src/app/components/cost.rs index 1845ea62..b50c548b 100644 --- a/arenabuddy/arenabuddy/src/app/components/cost.rs +++ b/arenabuddy/arenabuddy/src/app/components/cost.rs @@ -185,7 +185,7 @@ pub fn ManaCost(cost: Cost) -> Element { } else { // Fallback for missing SVGs div { - class: "w-4 h-4 bg-gray-200 rounded-full flex items-center justify-center text-xs flex-shrink-0", + class: "w-4 h-4 bg-gray-600 rounded-full flex items-center justify-center text-xs flex-shrink-0", "{symbol}" } } diff --git a/arenabuddy/arenabuddy/src/app/components/deck_list.rs b/arenabuddy/arenabuddy/src/app/components/deck_list.rs index e6a252fa..bf95d15a 100644 --- a/arenabuddy/arenabuddy/src/app/components/deck_list.rs +++ b/arenabuddy/arenabuddy/src/app/components/deck_list.rs @@ -17,8 +17,8 @@ pub fn DeckList( let hovered_card = use_signal(|| None::<(CardDisplayRecord, (f64, f64))>); rsx! { - div { class: "bg-white rounded-lg shadow-md overflow-hidden", - div { class: "bg-gradient-to-r from-indigo-500 to-indigo-600 py-4 px-6", + div { class: "bg-gray-800 rounded-lg border border-gray-700 overflow-hidden", + div { class: "bg-gradient-to-r from-violet-800 to-indigo-900 py-4 px-6", h2 { class: "text-xl font-bold text-white", "{title}" } } div { class: "p-6", @@ -48,17 +48,17 @@ pub fn DeckList( }} .deck-scrollbar::-webkit-scrollbar-track {{ - background: #f1f1f1; + background: #1f2937; border-radius: 8px; }} .deck-scrollbar::-webkit-scrollbar-thumb {{ - background: #c5c5c5; + background: #4b5563; border-radius: 8px; }} .deck-scrollbar::-webkit-scrollbar-thumb:hover {{ - background: #a0a0a0; + background: #6b7280; }} "# } @@ -95,7 +95,7 @@ fn NonLandCards( if let Some(cards) = main_deck.get(&card_type) { if !cards.is_empty() { div { class: "mb-4", - h4 { class: "text-md font-medium text-gray-700 mb-2", + h4 { class: "text-md font-medium text-gray-300 mb-2", if show_quantities { "{card_type} ({deck.total_by_type(card_type)})" } else { @@ -124,7 +124,7 @@ fn Lands( if let Some(lands) = main_deck.get(&CardType::Land).filter(|l| !l.is_empty()) { rsx! { div { - h3 { class: "text-lg font-semibold text-gray-800 border-b pb-2", + h3 { class: "text-lg font-semibold text-gray-200 border-b border-gray-700 pb-2", if show_quantities { "Lands ({deck.total_by_type(CardType::Land)})" } else { @@ -155,7 +155,7 @@ fn Sideboard( } else { rsx! { div { - h3 { class: "text-lg font-semibold text-gray-800 border-b pb-2", + h3 { class: "text-lg font-semibold text-gray-200 border-b border-gray-700 pb-2", if show_quantities { "Sideboard ({sideboard.len()})" } else { @@ -180,7 +180,7 @@ fn CardRow( ) -> Element { rsx! { div { - class: "flex items-center justify-between py-1 px-2 hover:bg-gray-50 rounded text-sm cursor-pointer", + class: "flex items-center justify-between py-1 px-2 hover:bg-gray-700/50 rounded text-sm cursor-pointer", onmouseenter: move |event| { let coords = event.client_coordinates(); hovered_card.set(Some((card.clone(), (coords.x, coords.y)))); @@ -190,7 +190,7 @@ fn CardRow( }, div { class: "flex items-center space-x-2", if show_quantities { - span { class: "font-medium text-gray-600 w-6 text-center", + span { class: "font-medium text-gray-400 w-6 text-center", "{card.quantity}" } } diff --git a/arenabuddy/arenabuddy/src/app/components/event_log.rs b/arenabuddy/arenabuddy/src/app/components/event_log.rs index 23e72048..c23800e4 100644 --- a/arenabuddy/arenabuddy/src/app/components/event_log.rs +++ b/arenabuddy/arenabuddy/src/app/components/event_log.rs @@ -21,8 +21,8 @@ pub fn EventLogDisplay(event_logs: Vec, controller_seat_id: i32) - }; rsx! { - div { class: "bg-white rounded-lg shadow-md overflow-hidden", - div { class: "bg-gradient-to-r from-emerald-500 to-emerald-600 py-4 px-6", + div { class: "bg-gray-800 rounded-lg border border-gray-700 overflow-hidden", + div { class: "bg-gradient-to-r from-emerald-900 to-emerald-800 py-4 px-6", h2 { class: "text-xl font-bold text-white", "Event Log" } } div { class: "p-6", @@ -58,9 +58,9 @@ fn GameSelector(game_numbers: Vec, selected: i32, on_select: EventHandler, selected: i32, on_select: EventHandler Element { rsx! { div { class: "mb-6", - h3 { class: "text-lg font-semibold text-gray-700 mb-3 border-b pb-2", + h3 { class: "text-lg font-semibold text-gray-300 mb-3 border-b border-gray-700 pb-2", "Game {event_log.game_number}" } div { class: "space-y-2", @@ -169,9 +169,9 @@ fn TurnGroup(group: TurnEventGroup, controller_seat_id: i32) -> Element { }; let header_bg = if is_your_turn { - "bg-blue-50 hover:bg-blue-100" + "bg-blue-900/20 hover:bg-blue-900/30" } else { - "bg-red-50 hover:bg-red-100" + "bg-red-900/20 hover:bg-red-900/30" }; let chevron_class = if expanded() { @@ -181,7 +181,7 @@ fn TurnGroup(group: TurnEventGroup, controller_seat_id: i32) -> Element { }; rsx! { - div { class: "border rounded-lg overflow-hidden", + div { class: "border border-gray-700 rounded-lg overflow-hidden", div { class: "px-4 py-2 cursor-pointer flex justify-between items-center {header_bg} transition-colors duration-150", onclick: move |_| { @@ -189,9 +189,9 @@ fn TurnGroup(group: TurnEventGroup, controller_seat_id: i32) -> Element { expanded.set(!current); }, div { class: "flex items-center gap-2", - span { class: "font-semibold text-gray-700", "{turn_label}" } + span { class: "font-semibold text-gray-300", "{turn_label}" } span { class: "text-sm text-gray-500", "({player_label})" } - span { class: "px-2 py-0.5 text-xs rounded-full bg-gray-200 text-gray-600", + span { class: "px-2 py-0.5 text-xs rounded-full bg-gray-700 text-gray-400", "{group.events.len()} events" } } @@ -210,7 +210,7 @@ fn TurnGroup(group: TurnEventGroup, controller_seat_id: i32) -> Element { } } if expanded() { - div { class: "divide-y divide-gray-100", + div { class: "divide-y divide-gray-700", for event in &group.events { EventRow { event: event.clone(), controller_seat_id } } @@ -228,13 +228,13 @@ fn TurnGroup(group: TurnEventGroup, controller_seat_id: i32) -> Element { fn style_to_css(style: ActionStyle) -> &'static str { match style { ActionStyle::Normal => "", - ActionStyle::Phase => "text-gray-400 text-xs italic", - ActionStyle::PlayerAction => "text-blue-800", - ActionStyle::OpponentAction => "text-red-800", - ActionStyle::Attack | ActionStyle::Negative => "text-red-700", - ActionStyle::Defense => "text-blue-700", - ActionStyle::Damage => "text-orange-700", - ActionStyle::Positive => "text-green-700", + ActionStyle::Phase => "text-gray-500 text-xs italic", + ActionStyle::PlayerAction => "text-blue-300", + ActionStyle::OpponentAction => "text-red-300", + ActionStyle::Attack | ActionStyle::Negative => "text-red-400", + ActionStyle::Defense => "text-blue-400", + ActionStyle::Damage => "text-orange-400", + ActionStyle::Positive => "text-emerald-400", ActionStyle::Emphasized => "font-semibold", } } @@ -268,7 +268,7 @@ fn EventRow(event: GameEvent, controller_seat_id: i32) -> Element { span { class: "flex-shrink-0 w-6 text-center", "{display.icon}" } span { class: "flex-grow", "{display.description}" } if let Some(badge) = phase_badge { - span { class: "flex-shrink-0 px-2 py-0.5 text-xs rounded-full bg-gray-100 text-gray-500", + span { class: "flex-shrink-0 px-2 py-0.5 text-xs rounded-full bg-gray-700 text-gray-400", "{badge}" } } diff --git a/arenabuddy/arenabuddy/src/app/components/match_info.rs b/arenabuddy/arenabuddy/src/app/components/match_info.rs index 82a96b75..ca0f869e 100644 --- a/arenabuddy/arenabuddy/src/app/components/match_info.rs +++ b/arenabuddy/arenabuddy/src/app/components/match_info.rs @@ -3,19 +3,19 @@ use dioxus::prelude::*; #[component] pub fn MatchInfo(controller_player_name: String, opponent_player_name: String, did_controller_win: bool) -> Element { rsx! { - div { class: "bg-white rounded-lg shadow-md overflow-hidden", - div { class: "bg-gradient-to-r from-blue-500 to-blue-600 py-4 px-6", + div { class: "bg-gray-800 rounded-lg border border-gray-700 overflow-hidden", + div { class: "bg-gradient-to-r from-amber-900 to-amber-800 py-4 px-6", h2 { class: "text-xl font-bold text-white", "Match Information" } } div { class: "p-6", div { class: "mb-4", - h3 { class: "text-lg font-semibold text-gray-700 mb-2", "Players" } + h3 { class: "text-lg font-semibold text-gray-300 mb-2", "Players" } div { class: "flex flex-col gap-2", - div { class: "bg-blue-50 p-3 rounded-md", + div { class: "bg-blue-900/20 p-3 rounded-md", span { class: "font-semibold", "You" } " {controller_player_name}" } - div { class: "bg-red-50 p-3 rounded-md", + div { class: "bg-red-900/20 p-3 rounded-md", span { class: "font-semibold", "Opponent" } " {opponent_player_name}" } @@ -23,19 +23,19 @@ pub fn MatchInfo(controller_player_name: String, opponent_player_name: String, d } div { class: "mb-4", - h3 { class: "text-lg font-semibold text-gray-700 mb-2", "Game Details" } + h3 { class: "text-lg font-semibold text-gray-300 mb-2", "Game Details" } div { class: "grid grid-cols-2 gap-2", - div { class: "bg-gray-50 p-3 rounded-md", + div { class: "bg-gray-900/50 p-3 rounded-md", span { class: "text-sm text-gray-500 block", "Format" } span { class: "font-medium", "unknown" } } - div { class: "bg-gray-50 p-3 rounded-md", + div { class: "bg-gray-900/50 p-3 rounded-md", span { class: "text-sm text-gray-500 block", "Result" } span { class: "font-medium", if did_controller_win { - span { class: "text-green-600 font-bold", "Victory" } + span { class: "text-amber-400 font-bold", "Victory" } } else { - span { class: "text-red-600 font-bold", "Defeat" } + span { class: "text-red-400 font-bold", "Defeat" } } } } diff --git a/arenabuddy/arenabuddy/src/app/components/mulligan_display.rs b/arenabuddy/arenabuddy/src/app/components/mulligan_display.rs index 02cda49a..c5d61cb5 100644 --- a/arenabuddy/arenabuddy/src/app/components/mulligan_display.rs +++ b/arenabuddy/arenabuddy/src/app/components/mulligan_display.rs @@ -4,8 +4,8 @@ use dioxus::prelude::*; #[component] pub fn MulliganDisplay(mulligans: Vec) -> Element { rsx! { - div { class: "bg-white rounded-lg shadow-md overflow-hidden", - div { class: "bg-gradient-to-r from-amber-500 to-amber-600 py-4 px-6", + div { class: "bg-gray-800 rounded-lg border border-gray-700 overflow-hidden", + div { class: "bg-gradient-to-r from-amber-900 to-amber-800 py-4 px-6", h2 { class: "text-xl font-bold text-white", "Mulligan Decisions" } } div { class: "p-6", @@ -37,17 +37,17 @@ fn MulliganCard(mulligan: Mulligan) -> Element { let decision_class = get_decision_class(&mulligan.decision); rsx! { - div { class: "border rounded-lg overflow-hidden shadow-sm", + div { class: "border border-gray-700 rounded-lg overflow-hidden", // Header section - div { class: "bg-gray-100 px-4 py-3 border-b", + div { class: "bg-gray-900 px-4 py-3 border-b border-gray-700", div { class: "flex justify-between items-center", - h3 { class: "font-semibold text-gray-700", + h3 { class: "font-semibold text-gray-300", "Game {mulligan.game_number} to Keep {mulligan.number_to_keep}" } // Badges div { class: "flex items-center space-x-2", - span { class: "px-2 py-1 text-xs rounded-full bg-purple-100 text-purple-800", + span { class: "px-2 py-1 text-xs rounded-full bg-violet-900/40 text-violet-300", "{mulligan.play_draw}" } span { class: "px-2 py-1 text-xs rounded-full {decision_class}", @@ -55,7 +55,7 @@ fn MulliganCard(mulligan: Mulligan) -> Element { } } } - div { class: "mt-1 text-sm text-gray-600", + div { class: "mt-1 text-sm text-gray-400", "vs {mulligan.opponent_identity}" } } @@ -85,8 +85,8 @@ fn MulliganCard(mulligan: Mulligan) -> Element { fn get_decision_class(decision: &str) -> &'static str { match decision { - "keep" => "bg-green-100 text-green-800", - "mulligan" => "bg-red-100 text-red-800", - _ => "bg-gray-100 text-gray-800", + "keep" => "bg-emerald-900/40 text-emerald-300", + "mulligan" => "bg-red-900/40 text-red-300", + _ => "bg-gray-700 text-gray-300", } } diff --git a/arenabuddy/arenabuddy/src/app/components/pagination.rs b/arenabuddy/arenabuddy/src/app/components/pagination.rs index 0d6953ee..dc60e0a7 100644 --- a/arenabuddy/arenabuddy/src/app/components/pagination.rs +++ b/arenabuddy/arenabuddy/src/app/components/pagination.rs @@ -7,22 +7,22 @@ pub fn Pagination(current_page: Signal, total_pages: usize, total_items: let end = ((page + 1) * page_size).min(total_items); rsx! { - div { class: "flex justify-between items-center py-3 px-4 border-b bg-gray-50", - p { class: "text-sm text-gray-600", + div { class: "flex justify-between items-center py-3 px-4 border-b border-gray-700 bg-gray-900", + p { class: "text-sm text-gray-400", "Showing {start}–{end} of {total_items}" } div { class: "flex items-center space-x-2", button { - class: "px-3 py-1 rounded text-sm bg-gray-200 hover:bg-gray-300 disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-150", + class: "px-3 py-1 rounded text-sm bg-gray-700 hover:bg-gray-600 disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-150", disabled: page == 0, onclick: move |_| current_page.set(page.saturating_sub(1)), "Previous" } - span { class: "px-3 py-1 text-sm text-gray-600", + span { class: "px-3 py-1 text-sm text-gray-400", "Page {page + 1} of {total_pages}" } button { - class: "px-3 py-1 rounded text-sm bg-gray-200 hover:bg-gray-300 disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-150", + class: "px-3 py-1 rounded text-sm bg-gray-700 hover:bg-gray-600 disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-150", disabled: page + 1 >= total_pages, onclick: move |_| current_page.set(page + 1), "Next" diff --git a/arenabuddy/arenabuddy/src/app/debug_logs.rs b/arenabuddy/arenabuddy/src/app/debug_logs.rs index bda73dd5..e8d7eb8c 100644 --- a/arenabuddy/arenabuddy/src/app/debug_logs.rs +++ b/arenabuddy/arenabuddy/src/app/debug_logs.rs @@ -80,18 +80,18 @@ pub fn DebugLogs() -> Element { }; rsx! { - div { class: "bg-white rounded-lg shadow-md p-6", - h1 { class: "text-2xl font-bold mb-4 text-gray-800", "Debug Logs Configuration" } + div { class: "bg-gray-800 rounded-lg border border-gray-700 p-6", + h1 { class: "text-2xl font-bold mb-4 text-gray-100", "Debug Logs Configuration" } div { class: "mb-6", - p { class: "text-gray-600 mb-4", + p { class: "text-gray-400 mb-4", "Select a directory where debug logs will be saved. This helps with troubleshooting and debugging Arena Buddy." } button { onclick: on_select_directory, disabled: is_loading() || is_initial_load(), - class: "bg-blue-600 hover:bg-blue-700 disabled:bg-gray-400 text-white font-medium py-2 px-4 rounded-lg transition-colors duration-200", + class: "bg-amber-600 hover:bg-amber-700 disabled:bg-gray-600 text-white font-medium py-2 px-4 rounded-lg transition-colors duration-200", if is_initial_load() { "Loading..." } else if is_loading() { @@ -105,13 +105,13 @@ pub fn DebugLogs() -> Element { } if let Some(logs) = selected_dir() { - div { class: "mb-4 p-3 bg-gray-100 rounded-lg", - p { class: "text-sm font-medium text-gray-700", + div { class: "mb-4 p-3 bg-gray-900 rounded-lg", + p { class: "text-sm font-medium text-gray-300", "Debug Logs ({logs.len()} entries):" } div { class: "max-h-48 overflow-y-auto", for log in logs { - p { class: "text-sm text-gray-600 break-all font-mono", "{log}" } + p { class: "text-sm text-gray-400 break-all font-mono", "{log}" } } } } @@ -123,11 +123,11 @@ pub fn DebugLogs() -> Element { let is_info = msg.contains("Loaded current") || msg.contains("No debug logs directory configured"); let class = if is_error { - "p-3 bg-red-100 border border-red-400 text-red-700 rounded-lg" + "p-3 bg-red-900/30 border border-red-700 text-red-300 rounded-lg" } else if is_info { - "p-3 bg-blue-100 border border-blue-400 text-blue-700 rounded-lg" + "p-3 bg-blue-900/30 border border-blue-700 text-blue-300 rounded-lg" } else { - "p-3 bg-green-100 border border-green-400 text-green-700 rounded-lg" + "p-3 bg-emerald-900/30 border border-emerald-700 text-emerald-300 rounded-lg" }; rsx! { diff --git a/arenabuddy/arenabuddy/src/app/draft_details.rs b/arenabuddy/arenabuddy/src/app/draft_details.rs index 5848352a..e1b5bf20 100644 --- a/arenabuddy/arenabuddy/src/app/draft_details.rs +++ b/arenabuddy/arenabuddy/src/app/draft_details.rs @@ -30,7 +30,7 @@ pub fn DraftDetails(id: String) -> Element { div { class: "mb-6", Link { to: Route::Drafts { }, - class: "inline-flex items-center bg-gray-200 hover:bg-gray-300 text-gray-800 font-semibold py-2 px-4 rounded-full transition-all duration-200 shadow-sm hover:shadow-md", + class: "inline-flex items-center bg-gray-700 hover:bg-gray-600 text-gray-200 font-semibold py-2 px-4 rounded-full transition-all duration-200", svg { xmlns: "http://www.w3.org/2000/svg", class: "h-5 w-5 mr-2", @@ -50,12 +50,12 @@ pub fn DraftDetails(id: String) -> Element { match data.as_ref() { None => rsx! { - div { class: "bg-white rounded-lg shadow-md p-12 text-center text-gray-500", + div { class: "bg-gray-800 rounded-lg border border-gray-700 p-12 text-center text-gray-500", div { class: "animate-pulse", "Loading draft details..." } } }, Some(Err(err)) => rsx! { - div { class: "bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4", + div { class: "bg-red-900/30 border border-red-700 text-red-300 px-4 py-3 rounded mb-4", p { "Failed to load draft details: {err}" } } }, @@ -74,30 +74,30 @@ pub fn DraftDetails(id: String) -> Element { #[component] fn DraftHeader(draft: DraftDetailsDisplay) -> Element { rsx! { - div { class: "bg-white rounded-lg shadow-md p-6 mb-6", - h1 { class: "text-2xl font-bold text-gray-800 mb-4", + div { class: "bg-gray-800 rounded-lg border border-gray-700 p-6 mb-6", + h1 { class: "text-2xl font-bold text-gray-100 mb-4", "{draft.metadata().set_code()} Draft" } div { class: "grid grid-cols-2 md:grid-cols-4 gap-4", div { - p { class: "text-sm text-gray-600", "Format" } + p { class: "text-sm text-gray-400", "Format" } p { class: "font-semibold", "{draft.metadata().format()}" } } div { - p { class: "text-sm text-gray-600", "Status" } + p { class: "text-sm text-gray-400", "Status" } p { class: "font-semibold", - class: if draft.metadata().status() == "DraftStatus_Complete" { "text-green-600" } else { "text-yellow-600" }, + class: if draft.metadata().status() == "DraftStatus_Complete" { "text-amber-400" } else { "text-yellow-400" }, if draft.metadata().status() == "DraftStatus_Complete" { "COMPLETE" } else { "IN PROGRESS" } } } div { - p { class: "text-sm text-gray-600", "Date" } + p { class: "text-sm text-gray-400", "Date" } p { class: "font-semibold", "{draft.metadata().created_at()}" } } div { - p { class: "text-sm text-gray-600", "Total Picks" } + p { class: "text-sm text-gray-400", "Total Picks" } p { class: "font-semibold", "{draft.total_picks()}" } } } @@ -108,8 +108,8 @@ fn DraftHeader(draft: DraftDetailsDisplay) -> Element { #[component] fn DraftPacksSection(draft: DraftDetailsDisplay) -> Element { rsx! { - div { class: "bg-white rounded-lg shadow-md p-6", - h2 { class: "text-xl font-bold text-gray-800 mb-4", "Draft Picks" } + div { class: "bg-gray-800 rounded-lg border border-gray-700 p-6", + h2 { class: "text-xl font-bold text-gray-100 mb-4", "Draft Picks" } if draft.packs().is_empty() { div { class: "text-center text-gray-500 py-8", @@ -135,9 +135,9 @@ fn DraftPacksSection(draft: DraftDetailsDisplay) -> Element { #[component] fn PackSection(pack_number: usize, packs: Vec) -> Element { rsx! { - div { class: "border-b pb-6 last:border-b-0", - h3 { class: "text-lg font-semibold text-gray-800 mb-4 flex items-center", - span { class: "bg-blue-100 text-blue-800 px-3 py-1 rounded-full text-sm mr-2", + div { class: "border-b border-gray-700 pb-6 last:border-b-0", + h3 { class: "text-lg font-semibold text-gray-200 mb-4 flex items-center", + span { class: "bg-amber-900/40 text-amber-300 px-3 py-1 rounded-full text-sm mr-2", "Pack {pack_number}" } span { class: "text-sm text-gray-500 font-normal", @@ -159,14 +159,14 @@ fn DraftPackRow(pack: EnrichedDraftPack) -> Element { let mut show_available = use_signal(|| false); rsx! { - div { class: "border rounded-lg p-3 bg-gray-50 hover:bg-gray-100 transition-colors", + div { class: "border border-gray-700 rounded-lg p-3 bg-gray-900 hover:bg-gray-800 transition-colors", // Pack header with pick info and picked card inline div { class: "flex justify-between items-start gap-3", div { class: "flex items-start gap-3 flex-1", // Pick info div { class: "flex-shrink-0", div { class: "flex items-center gap-2 mb-1", - span { class: "text-sm font-medium text-gray-700", + span { class: "text-sm font-medium text-gray-300", "Pick {pack.pick_number()}" } span { class: "text-xs text-gray-500", @@ -174,7 +174,7 @@ fn DraftPackRow(pack: EnrichedDraftPack) -> Element { } } if let Some(picked_name) = pack.picked_card_name() { - p { class: "text-xs text-blue-600 font-medium truncate max-w-[150px]", + p { class: "text-xs text-amber-400 font-medium truncate max-w-[150px]", "{picked_name}" } } @@ -187,7 +187,7 @@ fn DraftPackRow(pack: EnrichedDraftPack) -> Element { } button { - class: "text-xs text-blue-600 hover:text-blue-800 font-medium flex-shrink-0", + class: "text-xs text-amber-400 hover:text-amber-300 font-medium flex-shrink-0", onclick: move |_| show_available.set(!show_available()), if show_available() { "Hide" } else { "Show all" } } @@ -195,7 +195,7 @@ fn DraftPackRow(pack: EnrichedDraftPack) -> Element { // Available cards (collapsible) if show_available() { - div { class: "mt-4 pt-4 border-t border-gray-200", + div { class: "mt-4 pt-4 border-t border-gray-700", p { class: "text-xs text-gray-500 mb-3", "Available cards:" } div { class: "grid grid-cols-4 sm:grid-cols-5 md:grid-cols-6 lg:grid-cols-8 xl:grid-cols-10 gap-2", for card in pack.available() { @@ -211,15 +211,15 @@ fn DraftPackRow(pack: EnrichedDraftPack) -> Element { #[component] fn CardDisplay(card: CardDisplayRecord, is_picked: bool, size: String) -> Element { let bg_class = if is_picked { - "bg-blue-100 border-blue-300" + "bg-amber-900/30 border-amber-500" } else { - "bg-white border-gray-200" + "bg-gray-800 border-gray-600" }; let text_class = if is_picked { - "text-blue-700 font-semibold" + "text-amber-300 font-semibold" } else { - "text-gray-700" + "text-gray-300" }; let size_class = match size.as_str() { @@ -244,14 +244,14 @@ fn CardDisplay(card: CardDisplayRecord, is_picked: bool, size: String) -> Elemen loading: "lazy" } if is_picked && size != "small" { - div { class: "absolute top-1 right-1 bg-blue-600 text-white text-xs px-1.5 py-0.5 rounded-full shadow font-semibold", + div { class: "absolute top-1 right-1 bg-amber-500 text-white text-xs px-1.5 py-0.5 rounded-full shadow font-semibold", "✓" } } } } else { // Fallback when no image - div { class: "p-3 bg-gray-100", + div { class: "p-3 bg-gray-700", // Card name p { class: "{text_class} text-sm font-medium", "{card.name}" @@ -259,11 +259,11 @@ fn CardDisplay(card: CardDisplayRecord, is_picked: bool, size: String) -> Elemen // Card details div { class: "flex justify-between items-center mt-1", - span { class: "text-xs text-gray-600", + span { class: "text-xs text-gray-400", "{card.type_field}" } if !card.mana.is_empty() { - span { class: "text-xs text-gray-700 font-mono", + span { class: "text-xs text-gray-300 font-mono", "{card.mana}" } } diff --git a/arenabuddy/arenabuddy/src/app/drafts.rs b/arenabuddy/arenabuddy/src/app/drafts.rs index 97eb48ce..9e965b86 100644 --- a/arenabuddy/arenabuddy/src/app/drafts.rs +++ b/arenabuddy/arenabuddy/src/app/drafts.rs @@ -14,19 +14,19 @@ fn DraftRow(draft: Draft) -> Element { rsx! { Link { to: Route::DraftDetails { id: draft.id().to_string() }, - class: "table-row hover:bg-gray-100 transition-colors duration-150 cursor-pointer", - td { class: "py-3 px-4 border-b", - span { class: "text-blue-600 font-medium", + class: "table-row hover:bg-gray-700/50 transition-colors duration-150 cursor-pointer", + td { class: "py-3 px-4 border-b border-gray-700", + span { class: "text-amber-400 font-medium", "{draft.set_code()}" } } - td { class: "py-3 px-4 border-b", "{draft.format()}" } - td { class: "py-3 px-4 border-b", - span { class: if draft.status() == "DraftStatus_Complete" { "text-green-600" } else { "text-yellow-600" }, + td { class: "py-3 px-4 border-b border-gray-700", "{draft.format()}" } + td { class: "py-3 px-4 border-b border-gray-700", + span { class: if draft.status() == "DraftStatus_Complete" { "text-amber-400" } else { "text-yellow-400" }, if draft.status() == "DraftStatus_Complete" { "COMPLETE" } else { "IN PROGRESS" } } } - td { class: "py-3 px-4 border-b text-gray-500", "{draft.created_at()}" } + td { class: "py-3 px-4 border-b border-gray-700 text-gray-500", "{draft.created_at()}" } } } } @@ -55,10 +55,10 @@ pub fn Drafts() -> Element { rsx! { div { class: "container mx-auto px-4 py-8 max-w-5xl", div { class: "flex justify-between items-center mb-6", - h1 { class: "text-2xl font-bold text-gray-800", "Draft History" } + h1 { class: "text-2xl font-bold text-gray-100", "Draft History" } button { onclick: refresh_drafts, - class: "bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded shadow transition-colors duration-150 flex items-center", + class: "bg-amber-600 hover:bg-amber-700 text-white py-2 px-4 rounded transition-colors duration-150 flex items-center", disabled: data.is_none(), if data.is_none() { "Loading..." @@ -68,7 +68,7 @@ pub fn Drafts() -> Element { } } - div { class: "bg-white rounded-lg shadow-md overflow-hidden", + div { class: "bg-gray-800 rounded-lg border border-gray-700 overflow-hidden", match data.as_ref() { None => rsx! { div { class: "p-12 text-center text-gray-500", @@ -76,7 +76,7 @@ pub fn Drafts() -> Element { } }, Some(Err(err)) => rsx! { - div { class: "bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded m-4", + div { class: "bg-red-900/30 border border-red-700 text-red-300 px-4 py-3 rounded m-4", p { "Failed to load drafts: {err}" } } }, @@ -102,11 +102,11 @@ pub fn Drafts() -> Element { div { class: "overflow-x-auto", table { class: "min-w-full table-auto", thead { - tr { class: "bg-gray-100 text-left", - th { class: "py-3 px-4 font-semibold text-gray-700", "Set" } - th { class: "py-3 px-4 font-semibold text-gray-700", "Format" } - th { class: "py-3 px-4 font-semibold text-gray-700", "Status" } - th { class: "py-3 px-4 font-semibold text-gray-700", "Date" } + tr { class: "bg-gray-900 text-left", + th { class: "py-3 px-4 font-semibold text-gray-400", "Set" } + th { class: "py-3 px-4 font-semibold text-gray-400", "Format" } + th { class: "py-3 px-4 font-semibold text-gray-400", "Status" } + th { class: "py-3 px-4 font-semibold text-gray-400", "Date" } } } tbody { diff --git a/arenabuddy/arenabuddy/src/app/error_logs.rs b/arenabuddy/arenabuddy/src/app/error_logs.rs index 7c811f3d..727b64df 100644 --- a/arenabuddy/arenabuddy/src/app/error_logs.rs +++ b/arenabuddy/arenabuddy/src/app/error_logs.rs @@ -43,12 +43,12 @@ pub fn ErrorLogs() -> Element { rsx! { div { class: "max-w-6xl mx-auto p-2 sm:p-4", - div { class: "bg-white rounded-lg shadow-lg p-4 sm:p-6 mb-8", - div { class: "flex justify-between items-center mb-6 border-b pb-4", - h1 { class: "text-2xl font-bold text-gray-800", "Error Logs" } + div { class: "bg-gray-800 rounded-lg border border-gray-700 p-4 sm:p-6 mb-8", + div { class: "flex justify-between items-center mb-6 border-b border-gray-700 pb-4", + h1 { class: "text-2xl font-bold text-gray-100", "Error Logs" } button { onclick: move |_| load_logs(), - class: "bg-blue-600 hover:bg-blue-700 text-white font-medium py-2 px-4 rounded-md transition-colors duration-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50", + class: "bg-amber-600 hover:bg-amber-700 text-white font-medium py-2 px-4 rounded-md transition-colors duration-300 focus:outline-none focus:ring-2 focus:ring-amber-500 focus:ring-opacity-50", disabled: is_loading(), if is_loading() { "Loading..." } else { "Refresh Logs" } } @@ -57,28 +57,28 @@ pub fn ErrorLogs() -> Element { div { if is_loading() { div { class: "flex justify-center items-center h-64", - div { class: "animate-pulse text-gray-600", "Loading logs..." } + div { class: "animate-pulse text-gray-400", "Loading logs..." } } } else if has_error() { - div { class: "bg-red-50 border-l-4 border-red-500 p-4 mb-4", + div { class: "bg-red-900/20 border-l-4 border-red-500 p-4 mb-4", div { class: "flex", div { class: "ml-3", - p { class: "text-red-700 font-medium", "Error loading logs" } - p { class: "text-red-600 mt-1", + p { class: "text-red-300 font-medium", "Error loading logs" } + p { class: "text-red-400 mt-1", "There was a problem fetching the error logs. Please try again." } } } } } else if error_logs().is_empty() { - div { class: "bg-gray-50 border border-gray-200 rounded-md p-6 text-center", - p { class: "text-gray-600", "No error logs found." } + div { class: "bg-gray-900 border border-gray-700 rounded-md p-6 text-center", + p { class: "text-gray-400", "No error logs found." } } } else { div { textarea { readonly: true, - class: "border border-gray-300 rounded-md bg-gray-50 font-mono text-sm leading-relaxed text-gray-800 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 w-full h-96 p-4", + class: "border border-gray-600 rounded-md bg-gray-900 font-mono text-sm leading-relaxed text-gray-200 focus:outline-none focus:ring-2 focus:ring-amber-500 focus:border-amber-500 w-full h-96 p-4", value: "{error_logs().join(\"\\n\")}" } } diff --git a/arenabuddy/arenabuddy/src/app/match_details.rs b/arenabuddy/arenabuddy/src/app/match_details.rs index 03d397ac..3ef858de 100644 --- a/arenabuddy/arenabuddy/src/app/match_details.rs +++ b/arenabuddy/arenabuddy/src/app/match_details.rs @@ -34,7 +34,7 @@ pub(crate) fn MatchDetails(id: String) -> Element { div { class: "mb-4", Link { to: Route::Matches{}, - class: "inline-flex items-center bg-gray-200 hover:bg-gray-300 text-gray-800 font-semibold py-2 px-4 rounded-full transition-all duration-200 shadow-sm hover:shadow-md", + class: "inline-flex items-center bg-gray-700 hover:bg-gray-600 text-gray-200 font-semibold py-2 px-4 rounded-full transition-all duration-200", svg { xmlns: "http://www.w3.org/2000/svg", class: "h-5 w-5 mr-2", @@ -51,7 +51,7 @@ pub(crate) fn MatchDetails(id: String) -> Element { } } - div { class: "bg-gradient-to-r from-purple-700 to-blue-600 rounded-lg shadow-lg mb-8 p-6 text-white", + div { class: "bg-gradient-to-r from-violet-900 to-purple-800 rounded-lg shadow-lg shadow-black/20 mb-8 p-6 text-white", div { class: "flex justify-between items-center", h1 { class: "text-3xl font-bold", "Match Details" } div { class: "flex gap-2", @@ -87,18 +87,18 @@ pub(crate) fn MatchDetails(id: String) -> Element { match data.as_ref() { None => rsx! { - div { class: "bg-white rounded-lg shadow-md p-8 text-center", + div { class: "bg-gray-800 rounded-lg border border-gray-700 p-8 text-center", div { class: "animate-pulse flex flex-col items-center", - div { class: "w-12 h-12 border-4 border-blue-500 border-t-transparent rounded-full animate-spin mb-4" } - p { class: "text-gray-600", "Loading match details..." } + div { class: "w-12 h-12 border-4 border-amber-500 border-t-transparent rounded-full animate-spin mb-4" } + p { class: "text-gray-400", "Loading match details..." } } } }, Some(Err(err)) => rsx! { - div { class: "bg-white rounded-lg shadow-md p-8", + div { class: "bg-gray-800 rounded-lg border border-gray-700 p-8", div { - class: "bg-red-100 border-l-4 border-red-500 text-red-700 p-4 rounded", + class: "bg-red-900/30 border-l-4 border-red-500 text-red-300 p-4 rounded", role: "alert", p { class: "font-bold", "Error" } p { "Could not find match details for ID: {id}: {err}" } @@ -117,26 +117,26 @@ pub(crate) fn MatchDetails(id: String) -> Element { did_controller_win: details.did_controller_win } - div { class: "flex gap-1 mb-6 border-b border-gray-200", + div { class: "flex gap-1 mb-6 border-b border-gray-700", button { class: if active_tab() == 0 { - "px-4 py-2 font-medium text-blue-600 border-b-2 border-blue-600" + "px-4 py-2 font-medium text-amber-400 border-b-2 border-amber-400" } else { - "px-4 py-2 font-medium text-gray-500 hover:text-gray-700" + "px-4 py-2 font-medium text-gray-500 hover:text-gray-300" }, onclick: move |_| active_tab.set(0), "Overview" } button { class: if active_tab() == 1 { - "px-4 py-2 font-medium text-blue-600 border-b-2 border-blue-600" + "px-4 py-2 font-medium text-amber-400 border-b-2 border-amber-400" } else { - "px-4 py-2 font-medium text-gray-500 hover:text-gray-700" + "px-4 py-2 font-medium text-gray-500 hover:text-gray-300" }, onclick: move |_| active_tab.set(1), "Event Log" if event_count > 0 { - span { class: "ml-2 px-2 py-0.5 text-xs rounded-full bg-emerald-100 text-emerald-800", + span { class: "ml-2 px-2 py-0.5 text-xs rounded-full bg-emerald-900/40 text-emerald-300", "{event_count}" } } diff --git a/arenabuddy/arenabuddy/src/app/matches.rs b/arenabuddy/arenabuddy/src/app/matches.rs index b18e4061..21852f8f 100644 --- a/arenabuddy/arenabuddy/src/app/matches.rs +++ b/arenabuddy/arenabuddy/src/app/matches.rs @@ -15,14 +15,14 @@ fn MatchRow(m: MTGAMatch) -> Element { rsx! { Link { to: Route::MatchDetails { id: m.id().to_string() }, - class: "table-row hover:bg-gray-100 transition-colors duration-150 cursor-pointer", - td { class: "py-3 px-4 border-b", - span { class: "text-blue-600 font-medium", + class: "table-row hover:bg-gray-700/50 transition-colors duration-150 cursor-pointer", + td { class: "py-3 px-4 border-b border-gray-700", + span { class: "text-amber-400 font-medium", "{m.controller_player_name()}" } } - td { class: "py-3 px-4 border-b", "{m.opponent_player_name()}" } - td { class: "py-3 px-4 border-b text-gray-500", "{date}" } + td { class: "py-3 px-4 border-b border-gray-700", "{m.opponent_player_name()}" } + td { class: "py-3 px-4 border-b border-gray-700 text-gray-500", "{date}" } } } } @@ -47,10 +47,10 @@ pub(crate) fn Matches() -> Element { rsx! { div { class: "container mx-auto px-4 py-8 max-w-5xl", div { class: "flex justify-between items-center mb-6", - h1 { class: "text-2xl font-bold text-gray-800", "Match History" } + h1 { class: "text-2xl font-bold text-gray-100", "Match History" } button { onclick: refresh_matches, - class: "bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded shadow transition-colors duration-150 flex items-center", + class: "bg-amber-600 hover:bg-amber-700 text-white py-2 px-4 rounded transition-colors duration-150 flex items-center", disabled: data.is_none(), if data.is_none() { "Loading..." @@ -62,7 +62,7 @@ pub(crate) fn Matches() -> Element { match &*data { None => rsx! { - div { class: "bg-white rounded-lg shadow-md overflow-hidden", + div { class: "bg-gray-800 rounded-lg border border-gray-700 overflow-hidden", div { class: "p-12 text-center text-gray-500", div { class: "animate-pulse", "Loading match data..." } } @@ -70,10 +70,10 @@ pub(crate) fn Matches() -> Element { }, Some(Err(err)) => rsx! { - div { class: "bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4", + div { class: "bg-red-900/30 border border-red-700 text-red-300 px-4 py-3 rounded mb-4", p { "Failed to load matches: {err}" } } - div { class: "bg-white rounded-lg shadow-md overflow-hidden", + div { class: "bg-gray-800 rounded-lg border border-gray-700 overflow-hidden", div { class: "p-12 text-center text-gray-500", "No match data available" } @@ -88,7 +88,7 @@ pub(crate) fn Matches() -> Element { let end = (start + PAGE_SIZE).min(total_items); rsx! { - div { class: "bg-white rounded-lg shadow-md overflow-hidden", + div { class: "bg-gray-800 rounded-lg border border-gray-700 overflow-hidden", if matches_data.is_empty() { div { class: "p-12 text-center text-gray-500", "No matches found. Play some games in MTG Arena!" @@ -103,10 +103,10 @@ pub(crate) fn Matches() -> Element { div { class: "overflow-x-auto", table { class: "min-w-full table-fixed", thead { - tr { class: "bg-gray-100 text-left", - th { class: "py-3 px-4 font-semibold text-gray-700 w-1/3", "Controller" } - th { class: "py-3 px-4 font-semibold text-gray-700 w-1/3", "Opponent" } - th { class: "py-3 px-4 font-semibold text-gray-700 w-1/3", "Date" } + tr { class: "bg-gray-900 text-left", + th { class: "py-3 px-4 font-semibold text-gray-400 w-1/3", "Controller" } + th { class: "py-3 px-4 font-semibold text-gray-400 w-1/3", "Opponent" } + th { class: "py-3 px-4 font-semibold text-gray-400 w-1/3", "Date" } } } tbody { diff --git a/arenabuddy/arenabuddy/src/app/pages.rs b/arenabuddy/arenabuddy/src/app/pages.rs index c28883e3..5940cd73 100644 --- a/arenabuddy/arenabuddy/src/app/pages.rs +++ b/arenabuddy/arenabuddy/src/app/pages.rs @@ -45,9 +45,9 @@ pub enum Route { #[component] fn Home() -> Element { rsx! { - div { class: "bg-white rounded-lg shadow-md p-6", - h1 { class: "text-2xl font-bold mb-4 text-gray-800", "Home Page" } - p { class: "text-gray-600", + div { class: "bg-gray-800 rounded-lg border border-gray-700 p-6", + h1 { class: "text-2xl font-bold mb-4 text-gray-100", "Home Page" } + p { class: "text-gray-400", "Welcome to ArenaBuddy. Track and analyze your Arena matches." } } @@ -57,12 +57,12 @@ fn Home() -> Element { #[component] fn Contact() -> Element { rsx! { - div { class: "bg-white rounded-lg shadow-md p-6", - h1 { class: "text-2xl font-bold mb-4 text-gray-800", "Contact" } + div { class: "bg-gray-800 rounded-lg border border-gray-700 p-6", + h1 { class: "text-2xl font-bold mb-4 text-gray-100", "Contact" } a { href: "#", onclick: move |_| open_github(), - class: "text-blue-600 hover:text-blue-800 transition-colors duration-200", + class: "text-amber-400 hover:text-amber-300 transition-colors duration-200", "Github Repo" } } @@ -73,8 +73,8 @@ fn Contact() -> Element { fn PageNotFound(route: Vec) -> Element { rsx! { div { class: "text-center mt-8", - h1 { class: "text-2xl font-bold text-red-600", "Page Not Found" } - p { class: "mt-2 text-gray-600", + h1 { class: "text-2xl font-bold text-red-400", "Page Not Found" } + p { class: "mt-2 text-gray-400", "The page you're looking for doesn't exist." } } @@ -184,62 +184,62 @@ fn Layout() -> Element { }; rsx! { - nav { class: "bg-gray-800 p-4 shadow-md", + nav { class: "bg-gray-950 p-4 border-b border-gray-800", div { class: "container mx-auto flex justify-between items-center", ul { class: "flex space-x-6 text-white", li { Link { to: Route::Home {}, - class: "hover:text-blue-400 transition-colors duration-200", + class: "hover:text-amber-400 transition-colors duration-200", "Home" } } li { Link { to: Route::Matches {}, - class: "hover:text-blue-400 transition-colors duration-200", + class: "hover:text-amber-400 transition-colors duration-200", "Matches" } } li { Link { to: Route::Drafts { }, - class: "hover:text-blue-400 transition-colors duration-200", + class: "hover:text-amber-400 transition-colors duration-200", "Drafts" } } li { Link { to: Route::Stats {}, - class: "hover:text-blue-400 transition-colors duration-200", + class: "hover:text-amber-400 transition-colors duration-200", "Stats" } } li { Link { to: Route::ErrorLogs {}, - class: "hover:text-blue-400 transition-colors duration-200", + class: "hover:text-amber-400 transition-colors duration-200", "Error Logs" } } li { Link { to: Route::DebugLogs {}, - class: "hover:text-blue-400 transition-colors duration-200", + class: "hover:text-amber-400 transition-colors duration-200", "Debug Logs" } } li { Link { to: Route::Contact {}, - class: "hover:text-blue-400 transition-colors duration-200", + class: "hover:text-amber-400 transition-colors duration-200", "Contact" } } } div { class: "text-white flex items-center space-x-3", if let Some(username) = login_status() { - span { class: "text-green-400 text-sm", "Logged in as {username}" } + span { class: "text-emerald-400 text-sm", "Logged in as {username}" } button { class: "bg-red-600 hover:bg-red-700 text-white text-sm px-3 py-1 rounded transition-colors duration-200", onclick: on_logout, @@ -249,7 +249,7 @@ fn Layout() -> Element { span { class: "text-yellow-400 text-sm", "Logging in..." } } else { button { - class: "bg-indigo-600 hover:bg-indigo-700 text-white text-sm px-3 py-1 rounded transition-colors duration-200", + class: "bg-violet-600 hover:bg-violet-700 text-white text-sm px-3 py-1 rounded transition-colors duration-200", onclick: on_login, "Login with Discord" } diff --git a/arenabuddy/arenabuddy/src/app/stats.rs b/arenabuddy/arenabuddy/src/app/stats.rs index 203d268a..47392805 100644 --- a/arenabuddy/arenabuddy/src/app/stats.rs +++ b/arenabuddy/arenabuddy/src/app/stats.rs @@ -10,8 +10,8 @@ fn format_rate(rate: Option) -> String { #[component] fn StatCard(title: &'static str, children: Element) -> Element { rsx! { - div { class: "bg-white rounded-lg shadow-md p-6", - h2 { class: "text-lg font-semibold text-gray-700 mb-4", "{title}" } + div { class: "bg-gray-800 rounded-lg border border-gray-700 p-6", + h2 { class: "text-lg font-semibold text-gray-300 mb-4", "{title}" } {children} } } @@ -20,12 +20,12 @@ fn StatCard(title: &'static str, children: Element) -> Element { #[component] fn RecordLine(label: &'static str, wins: i64, losses: i64, rate: Option) -> Element { rsx! { - div { class: "flex justify-between items-center py-2 border-b border-gray-100 last:border-0", - span { class: "text-gray-600", "{label}" } + div { class: "flex justify-between items-center py-2 border-b border-gray-700 last:border-0", + span { class: "text-gray-400", "{label}" } div { class: "flex items-center space-x-3", - span { class: "text-green-600 font-medium", "{wins}W" } - span { class: "text-gray-400", "-" } - span { class: "text-red-600 font-medium", "{losses}L" } + span { class: "text-amber-400 font-medium", "{wins}W" } + span { class: "text-gray-600", "-" } + span { class: "text-red-400 font-medium", "{losses}L" } span { class: "text-gray-500 text-sm ml-2", "({format_rate(rate)})" } } } @@ -99,12 +99,12 @@ fn StatsDisplay(stats: MatchStats) -> Element { if !stats.opponents.is_empty() { StatCard { title: "Top Opponents", for opp in stats.opponents.iter() { - div { class: "flex justify-between items-center py-2 border-b border-gray-100 last:border-0", - span { class: "text-gray-600 truncate mr-4", "{opp.name}" } + div { class: "flex justify-between items-center py-2 border-b border-gray-700 last:border-0", + span { class: "text-gray-400 truncate mr-4", "{opp.name}" } div { class: "flex items-center space-x-3 flex-shrink-0", - span { class: "text-green-600 font-medium", "{opp.wins}W" } - span { class: "text-gray-400", "-" } - span { class: "text-red-600 font-medium", "{opp.losses}L" } + span { class: "text-amber-400 font-medium", "{opp.wins}W" } + span { class: "text-gray-600", "-" } + span { class: "text-red-400 font-medium", "{opp.losses}L" } span { class: "text-gray-500 text-sm ml-2", "({opp.matches} matches)" } @@ -135,10 +135,10 @@ pub(crate) fn Stats() -> Element { rsx! { div { class: "container mx-auto px-4 py-8 max-w-5xl", div { class: "flex justify-between items-center mb-6", - h1 { class: "text-2xl font-bold text-gray-800", "Match Statistics" } + h1 { class: "text-2xl font-bold text-gray-100", "Match Statistics" } button { onclick: refresh, - class: "bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded shadow transition-colors duration-150", + class: "bg-amber-600 hover:bg-amber-700 text-white py-2 px-4 rounded transition-colors duration-150", disabled: data.is_none(), if data.is_none() { "Loading..." @@ -150,13 +150,13 @@ pub(crate) fn Stats() -> Element { match &*data { None => rsx! { - div { class: "bg-white rounded-lg shadow-md p-12 text-center text-gray-500", + div { class: "bg-gray-800 rounded-lg border border-gray-700 p-12 text-center text-gray-500", div { class: "animate-pulse", "Loading statistics..." } } }, Some(Err(err)) => rsx! { - div { class: "bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded", + div { class: "bg-red-900/30 border border-red-700 text-red-300 px-4 py-3 rounded", p { "Failed to load statistics: {err}" } } }, @@ -164,7 +164,7 @@ pub(crate) fn Stats() -> Element { Some(Ok(stats)) => { if stats.total_matches == 0 { rsx! { - div { class: "bg-white rounded-lg shadow-md p-12 text-center text-gray-500", + div { class: "bg-gray-800 rounded-lg border border-gray-700 p-12 text-center text-gray-500", "No match data available. Play some games in MTG Arena!" } } diff --git a/arenabuddy/arenabuddy/src/backend/sync.rs b/arenabuddy/arenabuddy/src/backend/sync.rs index d0bd289e..cc61fd6b 100644 --- a/arenabuddy/arenabuddy/src/backend/sync.rs +++ b/arenabuddy/arenabuddy/src/backend/sync.rs @@ -1,7 +1,7 @@ use std::collections::HashSet; use arenabuddy_core::{ - models::{MTGAMatch, MatchData}, + models::MatchData, services::match_service::{GetMatchDataRequest, ListMatchesRequest, match_service_client::MatchServiceClient}, }; use arenabuddy_data::{ArenabuddyRepository, MatchDB}; diff --git a/arenabuddy/arenabuddy/tailwind.css b/arenabuddy/arenabuddy/tailwind.css index cff74dc9..cb37d961 100644 --- a/arenabuddy/arenabuddy/tailwind.css +++ b/arenabuddy/arenabuddy/tailwind.css @@ -4,3 +4,8 @@ @source "./src/**/*.{rs,html,css}"; @source "./dist/**/*.html"; @source "./index.html"; + +body { + background-color: var(--color-gray-950); + color: var(--color-gray-200); +}