mod repetition; use gtk4 as gtk; use gtk::glib; use gtk::prelude::*; use crate::{ db, gui::{update, update::Msg, App}, model::{event, event::Event}, }; pub async fn show(app: &App, event: Event, is_new: bool) { let dialog = gtk::Dialog::builder() .transient_for(&*app.window) .modal(true) .title(if is_new { "Ajouter" } else { "Modifier" }) .css_classes(vec!["g-Form".to_string()]) .build(); let content_area = dialog.content_area(); let lines = gtk::Box::builder() .orientation(gtk::Orientation::Vertical) .build(); content_area.append(&lines); let columns = gtk::Box::builder() .orientation(gtk::Orientation::Horizontal) .build(); columns.add_css_class("g-Form__Columns"); lines.append(&columns); // First column let column1 = gtk::Box::builder() .orientation(gtk::Orientation::Vertical) .build(); column1.add_css_class("g-Form__Inputs"); columns.append(&column1); let name = entry(&event.name); column1.append(&label("Événement")); column1.append(&name); let date = entry(&event.date.format(event::DATE_FORMAT).to_string()); column1.append(&label("Jour")); column1.append(&date); let start = entry( &event .start .map(event::pprint_time) .unwrap_or_else(|| "".to_string()), ); column1.append(&label("Début")); column1.append(&start); let end = entry( &event .end .map(event::pprint_time) .unwrap_or_else(|| "".to_string()), ); column1.append(&label("Fin")); column1.append(&end); // Second column let repetition_model = repetition::view(&event); columns.append(&repetition_model.view); // Buttons let button = gtk::Button::builder() .label(if is_new { "Créer" } else { "Modifier" }) .margin_bottom(10) .build(); lines.append(&button); let conn = app.conn.clone(); let tx = app.tx.clone(); button.connect_clicked(glib::clone!(@weak dialog, @strong event => move |_| { match repetition::validate(&repetition_model) { Ok(repetition) => { match event::validate(event.id, date.buffer().text(), name.buffer().text(), start.buffer().text(), end.buffer().text(), repetition) { Some(new) => { match if is_new { db::insert(&conn, &new) } else { db::update(&conn, &new) } { Ok(_) => { let msg = if is_new { Msg::AddEvent { new } } else { Msg::UpdateEvent { old: event.clone(), new } }; update::send(tx.clone(), msg); dialog.close() }, Err(err) => eprintln!("Error when upserting event: {err}") } } None => eprintln!("Event is not valid: {event:?}") } }, Err(message) => eprintln!("{message}") } })); if !is_new { let button = gtk::Button::builder().label("Supprimer").build(); lines.append(&button); let conn = app.conn.clone(); let tx = app.tx.clone(); button.connect_clicked(glib::clone!(@weak dialog => move |_| { if db::delete(&conn, &event.id).is_ok() { update::send(tx.clone(), Msg::DeleteEvent { event: event.clone() }); dialog.close() } })); } dialog.run_future().await; } fn entry(text: &str) -> gtk::Entry { gtk::Entry::builder().text(text).margin_bottom(10).build() } fn label(text: &str) -> gtk::Label { gtk::Label::builder() .label(text) .halign(gtk::Align::Start) .margin_bottom(5) .build() }