refactor, added ip validation
Some checks failed
/ Check (push) Successful in 1m33s
/ Format (push) Successful in 1m23s
/ Clippy (push) Has started running
/ Build (push) Has been cancelled

This commit is contained in:
Phani Pavan K
2025-08-29 10:40:24 +05:30
parent 4eab7aeaac
commit ebd66bfaf6
8 changed files with 90 additions and 60 deletions

170
src/ui/mod.rs Normal file
View File

@@ -0,0 +1,170 @@
#![allow(non_snake_case)]
mod centeredRect;
use ratatui::{
Frame,
layout::{Constraint, Direction, Layout},
style::{Color, Style},
text::{Line, Span, Text},
widgets::{Block, Borders, List, ListItem, Paragraph, Wrap},
};
use crate::app::status::CurrentScreen;
use crate::app::{AppState, status::EditingField};
use crate::ui::centeredRect::centered_rect;
pub fn ui(frame: &mut Frame, app: &AppState) {
let chunks = Layout::default()
.direction(ratatui::layout::Direction::Vertical)
.constraints([
Constraint::Length(3),
Constraint::Min(3),
Constraint::Length(3),
])
.split(frame.area());
let footerChunks = Layout::default()
.direction(ratatui::layout::Direction::Horizontal)
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
.split(chunks[2]);
let titleBlock = Block::default()
.borders(Borders::ALL)
.style(Style::default());
let title = Paragraph::new(Text::styled(
"Create new entry",
Style::default().fg(Color::Green),
))
.block(titleBlock);
frame.render_widget(title, chunks[0]);
let mut currentItems = Vec::<ListItem>::new();
for (i, e) in app.entries.iter().enumerate() {
currentItems.push(ListItem::new(Line::from(Span::styled(
format!("{}. {}", i, e),
Style::default().fg(Color::Yellow),
))));
}
let list = List::new(currentItems);
frame.render_widget(list, chunks[1]);
if let CurrentScreen::Exit = app.screen {
let exitPopup = Block::default()
.title("Save and Exit?")
.borders(Borders::ALL)
.style(Style::default().bg(Color::DarkGray));
let exitText = Text::styled(
"Save the current config and exit? (enter/esc)",
Style::default().fg(Color::Red),
);
let exitPara = Paragraph::new(exitText)
.block(exitPopup)
.wrap(Wrap { trim: false });
let area = centered_rect(60, 25, frame.area());
frame.render_widget(exitPara, area);
}
if let Some(edit) = &app.currentlyEditing {
let popup = Block::default()
.title("Add an entry")
.borders(Borders::NONE)
.style(Style::default().bg(Color::DarkGray));
let area = centered_rect(60, 25, frame.area());
frame.render_widget(popup, area);
let fields = Layout::default()
.direction(Direction::Horizontal)
.margin(1)
.constraints([
Constraint::Percentage(25),
Constraint::Percentage(25),
Constraint::Percentage(25),
Constraint::Percentage(25),
])
.split(area);
let mut fromIPBlock = Block::default().title("From IP").borders(Borders::ALL);
let mut toIPBlock = Block::default().title("To IP").borders(Borders::ALL);
let mut fromPortBlock = Block::default().title("From Port").borders(Borders::ALL);
let mut toPortBlock = Block::default().title("To Port").borders(Borders::ALL);
let activeStyle = Style::default().bg(Color::LightYellow).fg(Color::Black);
match edit {
EditingField::FromIP => fromIPBlock = fromIPBlock.style(activeStyle),
EditingField::ToIP => toIPBlock = toIPBlock.style(activeStyle),
EditingField::FromPort => fromPortBlock = fromPortBlock.style(activeStyle),
EditingField::ToPort => toPortBlock = toPortBlock.style(activeStyle),
}
let fromIPPara = Paragraph::new(app.fromIP.clone()).block(fromIPBlock);
let toIPPara = Paragraph::new(app.toIP.clone()).block(toIPBlock);
let fromPortPara = Paragraph::new(app.fromPort.clone()).block(fromPortBlock);
let toPortPara = Paragraph::new(app.toPort.clone()).block(toPortBlock);
frame.render_widget(fromIPPara, fields[0]);
frame.render_widget(fromPortPara, fields[1]);
frame.render_widget(toIPPara, fields[2]);
frame.render_widget(toPortPara, fields[3]);
};
let screenHelp = vec![
match app.screen {
CurrentScreen::Main => Span::styled("Main Screen", Style::default().fg(Color::Green)),
CurrentScreen::Add => Span::styled("Add entry", Style::default().fg(Color::Yellow)),
CurrentScreen::Exit => {
Span::styled("Exit Screen", Style::default().fg(Color::LightRed))
}
CurrentScreen::Settings => Span::styled("Settings", Style::default().fg(Color::Blue)),
}
.to_owned(),
Span::styled(" | ", Style::default().fg(Color::White)),
{
if let Some(editing) = &app.currentlyEditing {
let curEdit = match editing {
EditingField::FromIP => "From IP",
EditingField::ToIP => "To IP",
EditingField::FromPort => "From Port",
EditingField::ToPort => "To Port",
};
Span::styled(
format!("Editing: {curEdit}"),
Style::default().fg(Color::Green),
)
} else {
Span::styled("Not Editing", Style::default().fg(Color::DarkGray))
}
},
];
let helpFooter =
Paragraph::new(Line::from(screenHelp)).block(Block::default().borders(Borders::ALL));
let keybinds = {
match app.screen {
CurrentScreen::Main => Span::styled(
"(a) add entry / (q) save and quit",
Style::default().fg(Color::Red),
),
CurrentScreen::Add => Span::styled(
"(l) localhost / (enter/tab) next field / (c) clear / (C) clear all / (esc) main menu",
Style::default().fg(Color::Red),
),
CurrentScreen::Settings => Span::styled("", Style::default().fg(Color::Red)),
CurrentScreen::Exit => Span::styled(
"(enter) save and exit / (esc) main menu",
Style::default().fg(Color::Red),
),
}
};
let keyBindFooter =
Paragraph::new(Line::from(keybinds)).block(Block::default().borders(Borders::ALL));
frame.render_widget(helpFooter, footerChunks[0]);
frame.render_widget(keyBindFooter, footerChunks[1]);
}