Самый деградантский код проверки на правильность логина и пароля,

который я когда-либо писал
master
Алексей Алексей 2026-06-06 19:41:46 +10:00
parent ec2cae91c0
commit f6bb3306ee
6 changed files with 296 additions and 85 deletions

104
code/Cargo.lock generated
View File

@ -509,6 +509,15 @@ dependencies = [
"generic-array", "generic-array",
] ]
[[package]]
name = "block-buffer"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be"
dependencies = [
"hybrid-array",
]
[[package]] [[package]]
name = "block2" name = "block2"
version = "0.5.1" version = "0.5.1"
@ -749,7 +758,9 @@ dependencies = [
"egui", "egui",
"egui_dock", "egui_dock",
"egui_extras", "egui_extras",
"hex",
"rust_decimal", "rust_decimal",
"sha2 0.11.0",
"sqlx", "sqlx",
"tokio", "tokio",
] ]
@ -799,6 +810,12 @@ version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
[[package]]
name = "const-oid"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c"
[[package]] [[package]]
name = "core-foundation" name = "core-foundation"
version = "0.9.4" version = "0.9.4"
@ -858,6 +875,15 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "cpufeatures"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "crc" name = "crc"
version = "3.4.0" version = "3.4.0"
@ -913,6 +939,15 @@ dependencies = [
"typenum", "typenum",
] ]
[[package]]
name = "crypto-common"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453"
dependencies = [
"hybrid-array",
]
[[package]] [[package]]
name = "cursor-icon" name = "cursor-icon"
version = "1.2.0" version = "1.2.0"
@ -925,7 +960,7 @@ version = "0.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb"
dependencies = [ dependencies = [
"const-oid", "const-oid 0.9.6",
"pem-rfc7468", "pem-rfc7468",
"zeroize", "zeroize",
] ]
@ -936,12 +971,23 @@ version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [ dependencies = [
"block-buffer", "block-buffer 0.10.4",
"const-oid", "const-oid 0.9.6",
"crypto-common", "crypto-common 0.1.7",
"subtle", "subtle",
] ]
[[package]]
name = "digest"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2"
dependencies = [
"block-buffer 0.12.0",
"const-oid 0.10.2",
"crypto-common 0.2.2",
]
[[package]] [[package]]
name = "dispatch" name = "dispatch"
version = "0.2.0" version = "0.2.0"
@ -1815,7 +1861,7 @@ version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
dependencies = [ dependencies = [
"digest", "digest 0.10.7",
] ]
[[package]] [[package]]
@ -1827,6 +1873,15 @@ dependencies = [
"windows-sys 0.61.2", "windows-sys 0.61.2",
] ]
[[package]]
name = "hybrid-array"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da"
dependencies = [
"typenum",
]
[[package]] [[package]]
name = "iana-time-zone" name = "iana-time-zone"
version = "0.1.65" version = "0.1.65"
@ -2005,7 +2060,7 @@ dependencies = [
"portable-atomic-util", "portable-atomic-util",
"serde_core", "serde_core",
"wasm-bindgen", "wasm-bindgen",
"windows-sys 0.52.0", "windows-sys 0.61.2",
] ]
[[package]] [[package]]
@ -2239,7 +2294,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"digest", "digest 0.10.7",
] ]
[[package]] [[package]]
@ -3365,8 +3420,8 @@ version = "0.9.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d"
dependencies = [ dependencies = [
"const-oid", "const-oid 0.9.6",
"digest", "digest 0.10.7",
"num-bigint-dig", "num-bigint-dig",
"num-integer", "num-integer",
"num-traits", "num-traits",
@ -3591,8 +3646,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cpufeatures", "cpufeatures 0.2.17",
"digest", "digest 0.10.7",
] ]
[[package]] [[package]]
@ -3602,8 +3657,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cpufeatures", "cpufeatures 0.2.17",
"digest", "digest 0.10.7",
]
[[package]]
name = "sha2"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4"
dependencies = [
"cfg-if",
"cpufeatures 0.3.0",
"digest 0.11.3",
] ]
[[package]] [[package]]
@ -3628,7 +3694,7 @@ version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
dependencies = [ dependencies = [
"digest", "digest 0.10.7",
"rand_core", "rand_core",
] ]
@ -3844,7 +3910,7 @@ dependencies = [
"percent-encoding", "percent-encoding",
"serde", "serde",
"serde_json", "serde_json",
"sha2", "sha2 0.10.9",
"smallvec", "smallvec",
"thiserror 2.0.18", "thiserror 2.0.18",
"tokio", "tokio",
@ -3881,7 +3947,7 @@ dependencies = [
"quote", "quote",
"serde", "serde",
"serde_json", "serde_json",
"sha2", "sha2 0.10.9",
"sqlx-core", "sqlx-core",
"sqlx-mysql", "sqlx-mysql",
"sqlx-postgres", "sqlx-postgres",
@ -3905,7 +3971,7 @@ dependencies = [
"bytes", "bytes",
"chrono", "chrono",
"crc", "crc",
"digest", "digest 0.10.7",
"dotenvy", "dotenvy",
"either", "either",
"futures-channel", "futures-channel",
@ -3926,7 +3992,7 @@ dependencies = [
"rsa", "rsa",
"serde", "serde",
"sha1", "sha1",
"sha2", "sha2 0.10.9",
"smallvec", "smallvec",
"sqlx-core", "sqlx-core",
"stringprep", "stringprep",
@ -3966,7 +4032,7 @@ dependencies = [
"rand", "rand",
"serde", "serde",
"serde_json", "serde_json",
"sha2", "sha2 0.10.9",
"smallvec", "smallvec",
"sqlx-core", "sqlx-core",
"stringprep", "stringprep",

View File

@ -12,7 +12,9 @@ eframe = "0.34.2"
egui = "0.34.2" egui = "0.34.2"
egui_dock = "0.19.1" egui_dock = "0.19.1"
egui_extras = {version = "0.34.2", features = ["datepicker"]} egui_extras = {version = "0.34.2", features = ["datepicker"]}
hex = "0.4.3"
rust_decimal = {version = "1.42.0", features = ["macros"]} rust_decimal = {version = "1.42.0", features = ["macros"]}
sha2 = "0.11.0"
sqlx = {version="0.8.6", features = ["runtime-tokio", "mysql","bigdecimal","chrono"]} sqlx = {version="0.8.6", features = ["runtime-tokio", "mysql","bigdecimal","chrono"]}
tokio={version = "1.52.3", features = ["full"]} tokio={version = "1.52.3", features = ["full"]}

View File

@ -1,22 +1,30 @@
use std::{collections::HashMap, ops::Deref, str::FromStr, sync::Arc}; use std::{collections::HashMap, ops::Deref, str::FromStr, sync::Arc};
use crate::{ use crate::{
database::DBOperator, material_tab::MaterialTabViewer, models::{ database::DBOperator,
Equipment, Material, MaterialCategory, MaterialRow, ModalStatus, ModalWinState, Position, material_tab::MaterialTabViewer,
Worker, models::{
}, tab::*, worker_tab::* Equipment, LoginModalState, Material, MaterialCategory, MaterialRow, ModalStatus,
ModalWinState, Position, Worker,
},
tab::*,
worker_tab::*,
}; };
use egui::{TextBuffer, Vec2, mutex::RwLock}; use egui::{TextBuffer, Vec2, mutex::RwLock};
use egui_dock::{DockArea, Style, TabViewer}; use egui_dock::{DockArea, Style, TabViewer};
use egui_extras::{Column, TableBuilder}; use egui_extras::{Column, TableBuilder};
use sha2::{Digest, Sha256};
use sqlx::types::BigDecimal; use sqlx::types::BigDecimal;
pub struct App { pub struct App<'a> {
pub login_modal_state: LoginModalState<'a>,
pub tree: egui_dock::DockState<Tab>, pub tree: egui_dock::DockState<Tab>,
pub main_viewer: MainTabViewer, pub main_viewer: MainTabViewer,
pub db_oper: DBOperator,
pub rt: tokio::runtime::Runtime,
} }
impl Default for App { impl Default for App<'_> {
fn default() -> Self { fn default() -> Self {
let tree = egui_dock::DockState::new(vec![ let tree = egui_dock::DockState::new(vec![
Tab { Tab {
@ -49,17 +57,80 @@ impl Default for App {
}, },
]); ]);
let main_viewer = MainTabViewer::default(); let main_viewer = MainTabViewer::default();
Self { tree, main_viewer } let rt = tokio::runtime::Runtime::new().unwrap();
Self {
tree,
main_viewer,
login_modal_state: LoginModalState {
is_open: true,
data: HashMap::from([("login", String::new()), ("password", String::new())]),
status: crate::models::LoginStatus::Login,
..Default::default()
},
db_oper: rt.block_on(DBOperator::new()),
rt,
}
} }
} }
impl App { impl App<'_> {
pub fn new(_cc: &eframe::CreationContext<'_>) -> Self { pub fn new(_cc: &eframe::CreationContext<'_>) -> Self {
Default::default() Default::default()
} }
} }
impl eframe::App for App { impl eframe::App for App<'_> {
fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) { fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) {
if self.login_modal_state.is_open {
egui::Modal::new(egui::Id::new("login_modal")).show(ui.ctx(), |ui| {
ui.label("Пройдите авторизацию:");
ui.add(
egui::TextEdit::singleline(
self.login_modal_state.data.get_mut("login").unwrap(),
)
.hint_text("Введите логин"),
);
ui.add(
egui::TextEdit::singleline(
self.login_modal_state.data.get_mut("password").unwrap(),
)
.password(true)
.hint_text("Пароль"),
);
if self.login_modal_state.fail {
ui.label(&self.login_modal_state.fail_message);
}
ui.vertical_centered(|ui| {
if ui.button("Авторизоваться").clicked()
|| ui.input(|i| i.key_pressed(egui::Key::Enter))
{
let uname = self.login_modal_state.data.get("login").unwrap().clone();
if self.rt.block_on(async {
self.db_oper.check_username(uname.clone()).await.unwrap()
}) {
self.login_modal_state.fail = false;
let mut hashed_pass = Sha256::new();
hashed_pass
.update(self.login_modal_state.data.get("password").unwrap());
let pass_hash = hex::encode(hashed_pass.finalize());
if self.rt.block_on(async {
self.db_oper.check_password(uname, pass_hash).await.unwrap()
}) {
self.login_modal_state.fail = false;
self.login_modal_state.status =
crate::models::LoginStatus::Finished;
self.login_modal_state.is_open = false;
} else {
self.login_modal_state.fail = true;
self.login_modal_state.fail_message = "Неверный пароль".to_string();
}
} else {
self.login_modal_state.fail = true;
self.login_modal_state.fail_message = "Неверный логин".to_string();
}
}
});
});
}
DockArea::new(&mut self.tree) DockArea::new(&mut self.tree)
.style(Style::from_egui(ui.style().as_ref())) .style(Style::from_egui(ui.style().as_ref()))
.show_inside(ui, &mut self.main_viewer); .show_inside(ui, &mut self.main_viewer);
@ -205,7 +276,20 @@ impl MainTabViewer {
}); });
row.col(|ui| { row.col(|ui| {
if ui.button("Удалить").clicked() { if ui.button("Удалить").clicked() {
println!("WOr!k"); self.equipment_modal_state.is_open = true;
self.equipment_modal_state.status = ModalStatus::Remove;
self.equipment_modal_state
.data
.insert("id".into(), eq.id.to_string());
self.equipment_modal_state
.data
.insert("name".into(), eq.name.clone());
self.equipment_modal_state
.data
.insert("inv_numver".into(), eq.inv_number.clone());
self.equipment_modal_state
.data
.insert("worker_id".into(), eq.worker.id.to_string());
} }
}); });
if row.response().double_clicked() { if row.response().double_clicked() {
@ -232,33 +316,35 @@ impl MainTabViewer {
if ui.button("Закрыть").clicked() { if ui.button("Закрыть").clicked() {
self.equipment_modal_state.is_open = false; self.equipment_modal_state.is_open = false;
} }
egui::Grid::new("process_equipment_grid").show(ui, |ui| { if self.equipment_modal_state.status != ModalStatus::Remove {
ui.label("Название"); egui::Grid::new("process_equipment_grid").show(ui, |ui| {
let mut name = self.equipment_modal_state.data.get_mut("name").unwrap(); ui.label("Название");
ui.add_sized(Vec2::new(200.0, 20.0), egui::TextEdit::singleline(name)); let mut name = self.equipment_modal_state.data.get_mut("name").unwrap();
ui.end_row(); ui.add_sized(Vec2::new(200.0, 20.0), egui::TextEdit::singleline(name));
ui.end_row();
ui.label("Инв. номер"); ui.label("Инв. номер");
let mut inv_num = self let mut inv_num = self
.equipment_modal_state .equipment_modal_state
.data .data
.get_mut("inv_number") .get_mut("inv_number")
.unwrap(); .unwrap();
ui.text_edit_singleline(inv_num); ui.text_edit_singleline(inv_num);
ui.end_row(); ui.end_row();
ui.label("Ответственный"); ui.label("Ответственный");
// egui::ComboBox::new("process_equipment_combobox"); // egui::ComboBox::new("process_equipment_combobox");
ui.end_row(); ui.end_row();
ui.label("Дата последнего\nтехобслуживания"); ui.label("Дата последнего\nтехобслуживания");
let mut maintenance = self let mut maintenance = self
.equipment_modal_state .equipment_modal_state
.data .data
.get_mut("maintenance_date") .get_mut("maintenance_date")
.unwrap(); .unwrap();
ui.text_edit_singleline(maintenance); ui.text_edit_singleline(maintenance);
}); });
}
}); });
} }
} }

View File

@ -283,6 +283,43 @@ impl DBOperator {
Err(_) => Ok(false), Err(_) => Ok(false),
} }
} }
pub async fn check_username(&self, username: String) -> Result<bool, sqlx::Error> {
let ans = sqlx::query("SELECT * FROM Brewery.profile WHERE login=?")
.bind(username)
.fetch_all(&self.pool)
.await;
match ans {
Ok(n) => {
if n.len() > 0 {
return Ok(true);
} else {
return Ok(false);
}
}
Err(_) => Ok(false),
}
}
pub async fn check_password(
&self,
username: String,
password_hash: String,
) -> Result<bool, sqlx::Error> {
let ans = sqlx::query("SELECT * FROM Brewery.profile WHERE login=? AND password=?")
.bind(username)
.bind(password_hash)
.fetch_all(&self.pool)
.await;
match ans {
Ok(n) => {
if n.len() > 0 {
return Ok(true);
} else {
return Ok(false);
}
}
Err(_) => Ok(false),
}
}
} }
pub async fn estabilish_connection() -> Result<(), sqlx::Error> { pub async fn estabilish_connection() -> Result<(), sqlx::Error> {

View File

@ -3,20 +3,23 @@ use std::{any::TypeId, ops::Deref};
use egui::TextBuffer; use egui::TextBuffer;
use sqlx::types::{BigDecimal, chrono::DateTime}; use sqlx::types::{BigDecimal, chrono::DateTime};
#[derive(Clone, Hash, sqlx::FromRow, PartialEq)] #[derive(Clone, Hash, sqlx::FromRow, PartialEq)]
pub struct Position{ pub struct Position {
pub id: i32, pub id: i32,
pub name: String, pub name: String,
pub wage: BigDecimal, pub wage: BigDecimal,
} }
impl Default for Position{ impl Default for Position {
fn default() -> Self { fn default() -> Self {
Self { id: 1, name: "".into(), wage: 0.into() } Self {
id: 1,
name: "".into(),
wage: 0.into(),
}
} }
} }
#[derive(Default, Clone, Hash)] #[derive(Default, Clone, Hash)]
pub struct Worker{ pub struct Worker {
pub id: i32, pub id: i32,
pub full_name: String, pub full_name: String,
pub hire_date: DateTime<chrono::Local>, pub hire_date: DateTime<chrono::Local>,
@ -24,14 +27,14 @@ pub struct Worker{
pub is_fired: bool, pub is_fired: bool,
} }
#[derive(sqlx::FromRow, sqlx::Decode)] #[derive(sqlx::FromRow, sqlx::Decode)]
pub struct WorkerRow{ pub struct WorkerRow {
pub id: i32, pub id: i32,
pub full_name: String, pub full_name: String,
pub hire_date: DateTime<chrono::Local>, pub hire_date: DateTime<chrono::Local>,
pub position_id: i32, pub position_id: i32,
pub is_fired: bool, pub is_fired: bool,
} }
pub struct Salary{ pub struct Salary {
id: i32, id: i32,
worker: Worker, worker: Worker,
salary_size: rust_decimal::Decimal, salary_size: rust_decimal::Decimal,
@ -39,7 +42,7 @@ pub struct Salary{
} }
#[derive(Default, Clone, Hash)] #[derive(Default, Clone, Hash)]
pub struct Equipment{ pub struct Equipment {
pub id: i32, pub id: i32,
pub name: String, pub name: String,
pub inv_number: String, pub inv_number: String,
@ -47,7 +50,7 @@ pub struct Equipment{
pub worker: Worker, pub worker: Worker,
} }
#[derive(sqlx::FromRow)] #[derive(sqlx::FromRow)]
pub struct EquipmentRow{ pub struct EquipmentRow {
pub id: i32, pub id: i32,
pub name: String, pub name: String,
pub inv_number: String, pub inv_number: String,
@ -55,72 +58,87 @@ pub struct EquipmentRow{
pub worker_id: i32, pub worker_id: i32,
} }
#[derive(Clone)] #[derive(Clone)]
pub struct Material{ pub struct Material {
pub id: i32, pub id: i32,
pub name: String, pub name: String,
pub quantity: i32, pub quantity: i32,
pub category: MaterialCategory pub category: MaterialCategory,
} }
#[derive(sqlx::FromRow)] #[derive(sqlx::FromRow)]
pub struct MaterialRow{ pub struct MaterialRow {
pub id: i32, pub id: i32,
pub name: String, pub name: String,
pub quantity: i32, pub quantity: i32,
pub category_id: i32, pub category_id: i32,
} }
#[derive(sqlx::FromRow, Default, Clone, PartialEq)] #[derive(sqlx::FromRow, Default, Clone, PartialEq)]
pub struct MaterialCategory{ pub struct MaterialCategory {
pub id: i32, pub id: i32,
pub name: String, pub name: String,
} }
pub struct RecipeElement{ pub struct RecipeElement {
id:i32, id: i32,
material: Material, material: Material,
equipment: Equipment, equipment: Equipment,
quantity: i32 quantity: i32,
} }
pub struct Recipe{ pub struct Recipe {
id: i32, id: i32,
name: String, name: String,
elements: std::vec::Vec<RecipeElement>, elements: std::vec::Vec<RecipeElement>,
} }
pub struct Client{ pub struct Client {
id: i32, id: i32,
name: String, name: String,
address: String address: String,
} }
pub struct Order<'a>{ pub struct Order<'a> {
id: i32, id: i32,
client: Client, client: Client,
order_date: chrono::DateTime<chrono::Local>, order_date: chrono::DateTime<chrono::Local>,
total_amount: rust_decimal::Decimal, total_amount: rust_decimal::Decimal,
elements: std::vec::Vec<OrderElement<'a>> elements: std::vec::Vec<OrderElement<'a>>,
} }
pub struct OrderElement<'a>{ pub struct OrderElement<'a> {
id: i32, id: i32,
product: Product<'a>, product: Product<'a>,
quantity: i32, quantity: i32,
total_amount: rust_decimal::Decimal total_amount: rust_decimal::Decimal,
} }
pub struct Product<'a>{ pub struct Product<'a> {
id: i32, id: i32,
recipe: &'a Recipe, recipe: &'a Recipe,
volume: f64, volume: f64,
price_per_unit: rust_decimal::Decimal, price_per_unit: rust_decimal::Decimal,
} }
#[derive(Default)] #[derive(Default)]
pub struct ModalWinState{ pub struct ModalWinState {
pub is_open: bool, pub is_open: bool,
pub can_finish: bool, pub can_finish: bool,
pub data: std::collections::HashMap<String,String>, pub data: std::collections::HashMap<String, String>,
pub status: ModalStatus, pub status: ModalStatus,
} }
#[derive(Default, PartialEq)] #[derive(Default, PartialEq)]
pub enum ModalStatus{ pub enum ModalStatus {
#[default] #[default]
Add, Add,
Edit, Edit,
Remove Remove,
}
#[derive(Default)]
pub struct LoginModalState<'a> {
pub is_open: bool,
pub data: std::collections::HashMap<&'a str, String>,
pub status: LoginStatus,
pub fail: bool,
pub fail_message: String,
}
#[derive(Default)]
pub enum LoginStatus {
#[default]
Login,
Finished,
} }

View File

@ -1,3 +1,5 @@
use crate::tab::{Tab, TabTypes};
struct RecipeTabViewer {} struct RecipeTabViewer {}
impl RecipeTabViewer { impl RecipeTabViewer {