intro is now separated
This commit is contained in:
30
client/src/pages/intro/logic.rs
Normal file
30
client/src/pages/intro/logic.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
// src/tui/functions/intro.rs
|
||||
use crate::state::app::state::AppState;
|
||||
use crate::buffer::state::{AppView, BufferState};
|
||||
|
||||
/// Handles intro screen selection by updating view history and managing focus state.
|
||||
/// 0: Continue (restores last form or default)
|
||||
/// 1: Admin view
|
||||
/// 2: Login view
|
||||
/// 3: Register view (with focus reset)
|
||||
pub fn handle_intro_selection(
|
||||
app_state: &mut AppState,
|
||||
buffer_state: &mut BufferState,
|
||||
index: usize,
|
||||
) {
|
||||
let target_view = match index {
|
||||
0 => AppView::Form,
|
||||
1 => AppView::Admin,
|
||||
2 => AppView::Login,
|
||||
3 => AppView::Register,
|
||||
_ => return,
|
||||
};
|
||||
|
||||
buffer_state.update_history(target_view);
|
||||
|
||||
// Register view requires focus reset
|
||||
if index == 3 {
|
||||
app_state.ui.focus_outside_canvas = false;
|
||||
app_state.focused_button_index = 0;
|
||||
}
|
||||
}
|
||||
9
client/src/pages/intro/mod.rs
Normal file
9
client/src/pages/intro/mod.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
// src/pages/intro/mod.rs
|
||||
|
||||
pub mod state;
|
||||
pub mod ui;
|
||||
pub mod logic;
|
||||
|
||||
pub use state::*;
|
||||
pub use ui::render_intro;
|
||||
pub use logic::*;
|
||||
25
client/src/pages/intro/state.rs
Normal file
25
client/src/pages/intro/state.rs
Normal file
@@ -0,0 +1,25 @@
|
||||
// src/state/pages/intro.rs
|
||||
|
||||
#[derive(Default, Clone, Debug)]
|
||||
pub struct IntroState {
|
||||
pub selected_option: usize,
|
||||
}
|
||||
|
||||
impl IntroState {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub fn next_option(&mut self) {
|
||||
if self.selected_option < 3 {
|
||||
self.selected_option += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn previous_option(&mut self) {
|
||||
if self.selected_option > 0 {
|
||||
self.selected_option -= 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
87
client/src/pages/intro/ui.rs
Normal file
87
client/src/pages/intro/ui.rs
Normal file
@@ -0,0 +1,87 @@
|
||||
// src/pages/intro/ui.rs
|
||||
use ratatui::{
|
||||
layout::{Alignment, Constraint, Direction, Layout, Rect},
|
||||
style::Style,
|
||||
text::{Line, Span},
|
||||
widgets::{Block, BorderType, Borders, Paragraph},
|
||||
prelude::Margin,
|
||||
Frame,
|
||||
};
|
||||
use crate::config::colors::themes::Theme;
|
||||
use crate::pages::intro::IntroState;
|
||||
|
||||
pub fn render_intro(f: &mut Frame, intro_state: &IntroState, area: Rect, theme: &Theme) {
|
||||
let block = Block::default()
|
||||
.borders(Borders::ALL)
|
||||
.border_type(BorderType::Rounded)
|
||||
.border_style(Style::default().fg(theme.accent))
|
||||
.style(Style::default().bg(theme.bg));
|
||||
|
||||
let inner_area = block.inner(area);
|
||||
f.render_widget(block, area);
|
||||
|
||||
// Center layout
|
||||
let chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints([
|
||||
Constraint::Percentage(40),
|
||||
Constraint::Length(5),
|
||||
Constraint::Percentage(40),
|
||||
])
|
||||
.split(inner_area);
|
||||
|
||||
// Title
|
||||
let title = Line::from(vec![
|
||||
Span::styled("komp_ac", Style::default().fg(theme.highlight)),
|
||||
Span::styled(" v", Style::default().fg(theme.fg)),
|
||||
Span::styled(env!("CARGO_PKG_VERSION"), Style::default().fg(theme.secondary)),
|
||||
]);
|
||||
let title_para = Paragraph::new(title)
|
||||
.alignment(Alignment::Center);
|
||||
f.render_widget(title_para, chunks[1]);
|
||||
|
||||
// Buttons - now with 4 options
|
||||
let button_area = Layout::default()
|
||||
.direction(Direction::Horizontal)
|
||||
.constraints([
|
||||
Constraint::Percentage(25),
|
||||
Constraint::Percentage(25),
|
||||
Constraint::Percentage(25),
|
||||
Constraint::Percentage(25),
|
||||
])
|
||||
.split(chunks[1].inner(Margin {
|
||||
horizontal: 1,
|
||||
vertical: 1
|
||||
}));
|
||||
|
||||
let buttons = ["Continue", "Admin", "Login", "Register"];
|
||||
for (i, &text) in buttons.iter().enumerate() {
|
||||
render_button(f, button_area[i], text, intro_state.selected_option == i, theme);
|
||||
}
|
||||
}
|
||||
|
||||
fn render_button(f: &mut Frame, area: Rect, text: &str, selected: bool, theme: &Theme) {
|
||||
let button_style = Style::default()
|
||||
.fg(if selected { theme.highlight } else { theme.fg })
|
||||
.bg(theme.bg)
|
||||
.add_modifier(if selected {
|
||||
ratatui::style::Modifier::BOLD
|
||||
} else {
|
||||
ratatui::style::Modifier::empty()
|
||||
});
|
||||
|
||||
let border_style = Style::default()
|
||||
.fg(if selected { theme.accent } else { theme.border });
|
||||
|
||||
let button = Paragraph::new(text)
|
||||
.style(button_style)
|
||||
.alignment(Alignment::Center)
|
||||
.block(
|
||||
Block::default()
|
||||
.borders(Borders::ALL)
|
||||
.border_type(BorderType::Double)
|
||||
.border_style(border_style),
|
||||
);
|
||||
|
||||
f.render_widget(button, area);
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
// src/pages/mod.rs
|
||||
|
||||
pub mod routing;
|
||||
pub mod forms;
|
||||
pub mod intro;
|
||||
pub mod login;
|
||||
pub mod register;
|
||||
pub mod forms;
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
use crate::state::pages::{
|
||||
admin::AdminState,
|
||||
auth::AuthState,
|
||||
intro::IntroState,
|
||||
add_logic::AddLogicState,
|
||||
add_table::AddTableState,
|
||||
};
|
||||
use crate::pages::forms::FormState;
|
||||
use crate::pages::login::LoginState;
|
||||
use crate::pages::register::RegisterState;
|
||||
use crate::pages::intro::IntroState;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Page {
|
||||
|
||||
Reference in New Issue
Block a user