diff --git a/Cargo.toml b/Cargo.toml
index 55a9725011bbef1cc34848cbd49d0d3540068ffb..edc4698f2cd37034ba03b7d64a61e3b7045e5e74 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -6,4 +6,7 @@ edition = "2021"
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
-cursive = "0.19.0"
\ No newline at end of file
+cursive = "0.19.0"
+serde = {version = "1.0.0", features = ["derive"]}
+serde_json = "1.0"
+
diff --git a/src/app.rs b/src/app.rs
index 71b86e9b72f12b8409e6aa812fcb12e7a8eb5b6d..c8a28724812f0fa1eb9f229f01f20bc6554096c8 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -25,14 +25,27 @@ pub fn run() {
         .child(Button::new("Add new", add_training)) // Bouton pour ajouter un nouvel entraînement
         .child(Button::new("Delete", delete_training)) // Bouton pour supprimer un entraînement
         .child(DummyView) // Vue fictive pour ajouter de l'espace
-        .child(Button::new("Quit", Cursive::quit)); // Bouton pour quitter l'application
+        .child(Button::new("Quit", application_close)); // Bouton pour quitter l'application
 
     // Ajout de la couche de dialogue principale à Cursive
     siv.add_layer(Dialog::around(LinearLayout::horizontal()
         .child(select) // Ajout de la vue de sélection
         .child(DummyView) // Ajout d'espace vide
         .child(buttons)) // Ajout des boutons
-        .title("Select a training")); // Titre de la couche de dialogue
+        .title("Training session")); // Titre de la couche de dialogue
+
+    // Rajouter les entraînements sauvegarder dans le json
+    let trainings = load_from_json("training_session.json");
+    match trainings {
+        Ok(training_list) => {
+            for training in training_list.iter() {
+                siv.call_on_name("select", |view: &mut SelectView<Training>| {
+                    view.add_item(training.name.clone(), training.clone());
+                });
+            }
+        }
+        Err(err) => eprintln!("Error loading from JSON: {}", err),
+    }
 
     // Exécution de la boucle principale de Cursive
     siv.run();
@@ -47,7 +60,7 @@ fn add_training(s: &mut Cursive) {
     fn ok(s: &mut Cursive, training: Training) {
         // Ajout de l'entraînement à la vue de sélection
         s.call_on_name("select", |view: &mut SelectView<Training>| {
-            view.add_item(training.name.clone(), training.clone()); // Using the cloned_training
+            view.add_item(training.name.clone(), training.clone());
         });
 
         s.pop_layer(); // Fermer la couche de dialogue
@@ -69,6 +82,7 @@ fn add_training(s: &mut Cursive) {
                         // Récupération des données saisies par l'utilisateur
                         let name = get_view_content(s, "name");
                         let description = get_view_content(s, "description");
+                        // TODO Vérifier format date
                         let date = get_view_content(s, "date");
                         let location = get_view_content(s, "location");
                         let duration = get_view_content(s, "duration").parse::<i32>().unwrap_or(0);
@@ -150,4 +164,25 @@ fn on_submit(s: &mut Cursive, training: &Training) {
                     })
                     .scrollable() // Permettre le défilement si le contenu dépasse
     );
+}
+
+fn application_close(s: &mut Cursive) {
+    let select = s.find_name::<SelectView<Training>>("select").unwrap();
+    let trainings = Training::extract_trainings_from_view(&select);
+    if let Err(err) = save_to_json(&trainings, "training_session.json") {
+        eprintln!("Error saving to JSON: {}", err);
+    }
+    s.quit();
+}
+
+fn save_to_json(trainings: &Vec<&Training>, file_path: &str) -> std::io::Result<()> {
+    let serialized = serde_json::to_string_pretty(trainings)?;
+    std::fs::write(file_path, serialized)?;
+    Ok(())
+}
+
+fn load_from_json(file_path: &str) -> std::io::Result<Vec<Training>> {
+    let contents = std::fs::read_to_string(file_path)?;
+    let data: Vec<Training> = serde_json::from_str(&contents)?;
+    Ok(data)
 }
\ No newline at end of file
diff --git a/src/training.rs b/src/training.rs
index 90631e0271587766e47b6dc11e4cef4fb392756f..a04a1eb915ece4bde0082ff2269e9a10c389cfbe 100644
--- a/src/training.rs
+++ b/src/training.rs
@@ -1,5 +1,10 @@
+extern crate serde;
+extern crate serde_json;
+
+use cursive::views::SelectView;
+
 /// Structure représentant un entraînement
-#[derive(Clone)]
+#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
 pub struct Training {
     /// Nom de l'entraînement
     pub name: String,
@@ -52,4 +57,17 @@ impl Training {
         format!("Name: {}\nDescription: {}\nDate: {}\nLocation: {}\nDuration: {}\nParticipants: {}",
                 self.name, self.description, self.date, self.location, self.duration.to_string(), self.participants.join(","))
     }
+
+    pub fn extract_trainings_from_view(select_view: &SelectView<Training>) -> Vec<&Training> {
+        let items = select_view.len();
+        let mut trainings = Vec::with_capacity(items);
+
+        for i in 0..items {
+            if let Some(training) = select_view.get_item(i) {
+                trainings.push(training.clone().1);
+            }
+        }
+
+        trainings
+    }
 }
\ No newline at end of file
diff --git a/training_session.json b/training_session.json
new file mode 100644
index 0000000000000000000000000000000000000000..898ff8fa5f018f52ad38f1d2f40a403545804191
--- /dev/null
+++ b/training_session.json
@@ -0,0 +1,22 @@
+[
+  {
+    "name": "daiwdji",
+    "description": "jiijo",
+    "date": "ijo",
+    "location": "jio",
+    "duration": 0,
+    "participants": [
+      "jio"
+    ]
+  },
+  {
+    "name": "Foot",
+    "description": "fandn",
+    "date": "nn",
+    "location": "awd",
+    "duration": 0,
+    "participants": [
+      "nsda"
+    ]
+  }
+]
\ No newline at end of file