From 519daeec40b150b326191e755e42a4da4bb16fc2 Mon Sep 17 00:00:00 2001 From: Patryk Hegenberg Date: Fri, 4 Jul 2025 18:40:47 +0200 Subject: [PATCH] refactor: update edit functionality to be less confusing --- cmd/FyneApp.toml | 2 +- cmd/build.sh | 3 +- internal/data/database.go | 27 +++- internal/ui/history.go | 279 +++++++++++++++++++++++++++----------- 4 files changed, 224 insertions(+), 87 deletions(-) diff --git a/cmd/FyneApp.toml b/cmd/FyneApp.toml index d8806a7..160f95e 100644 --- a/cmd/FyneApp.toml +++ b/cmd/FyneApp.toml @@ -5,4 +5,4 @@ Website = "https://patanix.de" Name = "kettlebell_tracker" ID = "de.patanix.kettlebell_tracker" Version = "1.0.0" - Build = 5 + Build = 9 diff --git a/cmd/build.sh b/cmd/build.sh index 7f29a05..a9b4b72 100755 --- a/cmd/build.sh +++ b/cmd/build.sh @@ -1 +1,2 @@ -fyne package -os android -release --tags -ldflags="-s -w" +# fyne package -os android -release --tags -ldflags="-s -w" +fyne package -os android/arm64 -release --tags -ldflags="-s -w" -certificate my-release-key.keystore diff --git a/internal/data/database.go b/internal/data/database.go index d0781b3..d4ad757 100644 --- a/internal/data/database.go +++ b/internal/data/database.go @@ -2,6 +2,7 @@ package data import ( "database/sql" + "fmt" "log" "time" @@ -132,10 +133,24 @@ func (s *DatabaseService) DeleteTraining(id int64) error { func (s *DatabaseService) UpdateTraining(session *TrainingSession) error { dateStr := session.Date.Format(time.RFC3339) query := ` - UPDATE training - SET date = ?, sets = ?, weightLeft = ?, weightRight = ?, repsPerSet = ?, duration = ?, program = ?, blockDay = ? - WHERE id = ?; - ` - _, err := s.DB.Exec(query, dateStr, session.Sets, session.WeightLeft, session.WeightRight, session.RepsPerSet, session.Duration, session.Program, session.BlockDay, session.ID) - return err + UPDATE training + SET date = ?, sets = ?, weightLeft = ?, weightRight = ?, repsPerSet = ?, duration = ?, program = ?, blockDay = ? + WHERE id = ?; + ` + res, err := s.DB.Exec(query, dateStr, session.Sets, session.WeightLeft, session.WeightRight, session.RepsPerSet, session.Duration, session.Program, session.BlockDay, session.ID) + if err != nil { + log.Printf("UpdateTraining Fehler: %v", err) + return err + } + rowsAffected, err := res.RowsAffected() + if err != nil { + log.Printf("UpdateTraining RowsAffected Fehler: %v", err) + return err + } + if rowsAffected == 0 { + log.Printf("UpdateTraining: Kein Datensatz mit ID %d gefunden", session.ID) + return fmt.Errorf("kein Datensatz mit ID %d gefunden", session.ID) + } + log.Printf("UpdateTraining erfolgreich für ID %d", session.ID) + return nil } diff --git a/internal/ui/history.go b/internal/ui/history.go index 1da74ea..6706efe 100644 --- a/internal/ui/history.go +++ b/internal/ui/history.go @@ -19,7 +19,7 @@ func MakeHistoryScreen(db *data.DatabaseService, parent fyne.Window) fyne.Canvas placeholder := widget.NewLabel("Noch keine Trainingsdaten vorhanden.") - var showDetailDialog func(session data.TrainingSession, id int) + var showDetailDialog func(session *data.TrainingSession, id int) var refreshData func() list := widget.NewList( @@ -43,23 +43,87 @@ func MakeHistoryScreen(db *data.DatabaseService, parent fyne.Window) fyne.Canvas ) list.OnSelected = func(id widget.ListItemID) { - session := history[id] + session := &history[id] showDetailDialog(session, id) list.Unselect(id) } - showDetailDialog = func(session data.TrainingSession, id int) { - details := container.NewVBox( + showDetailDialog = func(session *data.TrainingSession, id int) { + setsEntry := widget.NewEntry() + setsEntry.SetText(fmt.Sprintf("%d", session.Sets)) + + durationEntry := widget.NewEntry() + durationEntry.SetText(fmt.Sprintf("%d", session.Duration)) + + repsEntry := widget.NewEntry() + repsEntry.SetText(fmt.Sprintf("%d", session.RepsPerSet)) + + weightLeftEntry := widget.NewEntry() + weightLeftEntry.SetText(fmt.Sprintf("%.1f", session.WeightLeft)) + + weightRightEntry := widget.NewEntry() + weightRightEntry.SetText(fmt.Sprintf("%.1f", session.WeightRight)) + + // Info-Header + info := container.NewVBox( widget.NewLabel(fmt.Sprintf("Datum: %s", session.Date.Format("02.01.2006 15:04"))), widget.NewLabel(fmt.Sprintf("Programm: %s", session.Program)), widget.NewLabel(fmt.Sprintf("Block-Tag: %d", session.BlockDay)), - widget.NewLabel(fmt.Sprintf("Sätze: %d", session.Sets)), - widget.NewLabel(fmt.Sprintf("Dauer: %s", utils.FormatDuration(session.Duration))), - widget.NewLabel(fmt.Sprintf("Reps/Satz: %d", session.RepsPerSet)), - widget.NewLabel(fmt.Sprintf("Gewicht links: %.1f kg", session.WeightLeft)), - widget.NewLabel(fmt.Sprintf("Gewicht rechts: %.1f kg", session.WeightRight)), ) + form := widget.NewForm( + &widget.FormItem{Text: "Sätze", Widget: setsEntry}, + &widget.FormItem{Text: "Dauer (Sekunden)", Widget: durationEntry}, + &widget.FormItem{Text: "Reps/Satz", Widget: repsEntry}, + &widget.FormItem{Text: "Gewicht links (kg)", Widget: weightLeftEntry}, + &widget.FormItem{Text: "Gewicht rechts (kg)", Widget: weightRightEntry}, + ) + + // Lokale Dialog-Referenz deklarieren + var detailDialog dialog.Dialog + + saveBtn := widget.NewButtonWithIcon("Speichern", theme.ConfirmIcon(), func() { + sets, err := strconv.Atoi(setsEntry.Text) + if err != nil { + dialog.ShowError(fmt.Errorf("Ungültige Sätze-Zahl"), parent) + return + } + duration, err := strconv.Atoi(durationEntry.Text) + if err != nil { + dialog.ShowError(fmt.Errorf("Ungültige Dauer"), parent) + return + } + reps, err := strconv.Atoi(repsEntry.Text) + if err != nil { + dialog.ShowError(fmt.Errorf("Ungültige Wiederholungszahl"), parent) + return + } + weightLeft, err := strconv.ParseFloat(weightLeftEntry.Text, 64) + if err != nil { + dialog.ShowError(fmt.Errorf("Ungültiges Gewicht links"), parent) + return + } + weightRight, err := strconv.ParseFloat(weightRightEntry.Text, 64) + if err != nil { + dialog.ShowError(fmt.Errorf("Ungültiges Gewicht rechts"), parent) + return + } + + session.Sets = int64(sets) + session.Duration = int64(duration) + session.RepsPerSet = int64(reps) + session.WeightLeft = weightLeft + session.WeightRight = weightRight + + if err := db.UpdateTraining(session); err != nil { + dialog.ShowError(err, parent) + return + } + dialog.ShowInformation("Erfolg", "Trainingseintrag aktualisiert.", parent) + refreshData() + detailDialog.Hide() + }) + deleteBtn := widget.NewButtonWithIcon("Löschen", theme.DeleteIcon(), func() { dialog.ShowConfirm("Eintrag löschen", "Möchtest du diesen Eintrag wirklich löschen?", func(ok bool) { if ok { @@ -69,85 +133,142 @@ func MakeHistoryScreen(db *data.DatabaseService, parent fyne.Window) fyne.Canvas return } refreshData() + detailDialog.Hide() } }, parent) }) - editBtn := widget.NewButtonWithIcon("Bearbeiten", theme.DocumentCreateIcon(), func() { - setsEntry := widget.NewEntry() - setsEntry.SetText(fmt.Sprintf("%d", session.Sets)) - - durationEntry := widget.NewEntry() - durationEntry.SetText(fmt.Sprintf("%d", session.Duration)) // Dauer in Sekunden - - repsEntry := widget.NewEntry() - repsEntry.SetText(fmt.Sprintf("%d", session.RepsPerSet)) - - weightLeftEntry := widget.NewEntry() - weightLeftEntry.SetText(fmt.Sprintf("%.1f", session.WeightLeft)) - - weightRightEntry := widget.NewEntry() - weightRightEntry.SetText(fmt.Sprintf("%.1f", session.WeightRight)) - - form := &widget.Form{ - Items: []*widget.FormItem{ - {Text: "Sätze", Widget: setsEntry}, - {Text: "Dauer (Sekunden)", Widget: durationEntry}, - {Text: "Reps/Satz", Widget: repsEntry}, - {Text: "Gewicht links (kg)", Widget: weightLeftEntry}, - {Text: "Gewicht rechts (kg)", Widget: weightRightEntry}, - }, - OnSubmit: func() { - var ( - sets, reps, duration int - weightLeft, weightRight float64 - err error - ) - if sets, err = strconv.Atoi(setsEntry.Text); err != nil { - dialog.ShowError(fmt.Errorf("Ungültige Sätze-Zahl"), parent) - return - } - if duration, err = strconv.Atoi(durationEntry.Text); err != nil { - dialog.ShowError(fmt.Errorf("Ungültige Dauer"), parent) - return - } - if reps, err = strconv.Atoi(repsEntry.Text); err != nil { - dialog.ShowError(fmt.Errorf("Ungültige Wiederholungszahl"), parent) - return - } - if weightLeft, err = strconv.ParseFloat(weightLeftEntry.Text, 64); err != nil { - dialog.ShowError(fmt.Errorf("Ungültiges Gewicht links"), parent) - return - } - if weightRight, err = strconv.ParseFloat(weightRightEntry.Text, 64); err != nil { - dialog.ShowError(fmt.Errorf("Ungültiges Gewicht rechts"), parent) - return - } - - session.Sets = int64(sets) - session.Duration = int64(duration) - session.RepsPerSet = int64(reps) - session.WeightLeft = weightLeft - session.WeightRight = weightRight - - if err := db.UpdateTraining(&session); err != nil { - dialog.ShowError(err, parent) - return - } - dialog.ShowInformation("Erfolg", "Trainingseintrag aktualisiert.", parent) - refreshData() - }, - } - - dialog.ShowForm("Training bearbeiten", "Speichern", "Abbrechen", form.Items, func(ok bool) { - }, parent) + cancelBtn := widget.NewButton("Abbrechen", func() { + detailDialog.Hide() }) - btns := container.NewHBox(editBtn, deleteBtn) + btns := container.NewHBox(saveBtn, deleteBtn, cancelBtn) - dialog.ShowCustom("Training Details", "Schließen", container.NewVBox(details, btns), parent) + content := container.NewVBox( + info, + form, + btns, + ) + + // Hier wird der Dialog erzeugt und die lokale Variable gesetzt + detailDialog = dialog.NewCustom("Training bearbeiten/löschen", "Schließen", content, parent) + detailDialog.Show() } + // showDetailDialog = func(session *data.TrainingSession, id int) { + // details := container.NewVBox( + // widget.NewLabel(fmt.Sprintf("Datum: %s", session.Date.Format("02.01.2006 15:04"))), + // widget.NewLabel(fmt.Sprintf("Programm: %s", session.Program)), + // widget.NewLabel(fmt.Sprintf("Block-Tag: %d", session.BlockDay)), + // widget.NewLabel(fmt.Sprintf("Sätze: %d", session.Sets)), + // widget.NewLabel(fmt.Sprintf("Dauer: %s", utils.FormatDuration(session.Duration))), + // widget.NewLabel(fmt.Sprintf("Reps/Satz: %d", session.RepsPerSet)), + // widget.NewLabel(fmt.Sprintf("Gewicht links: %.1f kg", session.WeightLeft)), + // widget.NewLabel(fmt.Sprintf("Gewicht rechts: %.1f kg", session.WeightRight)), + // ) + + // deleteBtn := widget.NewButtonWithIcon("Löschen", theme.DeleteIcon(), func() { + // dialog.ShowConfirm("Eintrag löschen", "Möchtest du diesen Eintrag wirklich löschen?", func(ok bool) { + // if ok { + // err := db.DeleteTraining(session.ID) + // if err != nil { + // dialog.ShowError(err, parent) + // return + // } + // refreshData() + // } + // }, parent) + // }) + + // editBtn := widget.NewButtonWithIcon("Bearbeiten", theme.DocumentCreateIcon(), func() { + // setsEntry := widget.NewEntry() + // setsEntry.SetText(fmt.Sprintf("%d", session.Sets)) + + // durationEntry := widget.NewEntry() + // durationEntry.SetText(fmt.Sprintf("%d", session.Duration)) + + // repsEntry := widget.NewEntry() + // repsEntry.SetText(fmt.Sprintf("%d", session.RepsPerSet)) + + // weightLeftEntry := widget.NewEntry() + // weightLeftEntry.SetText(fmt.Sprintf("%.1f", session.WeightLeft)) + + // weightRightEntry := widget.NewEntry() + // weightRightEntry.SetText(fmt.Sprintf("%.1f", session.WeightRight)) + + // items := []*widget.FormItem{ + // {Text: "Sätze", Widget: setsEntry}, + // {Text: "Dauer (Sekunden)", Widget: durationEntry}, + // {Text: "Reps/Satz", Widget: repsEntry}, + // {Text: "Gewicht links (kg)", Widget: weightLeftEntry}, + // {Text: "Gewicht rechts (kg)", Widget: weightRightEntry}, + // } + + // var editDialog dialog.Dialog + // editDialog = dialog.NewForm( + // "Training bearbeiten", + // "Speichern", + // "Abbrechen", + // items, + // func(ok bool) { + // if !ok { + // log.Printf("Bearbeiten abgebrochen für Session-ID %d", session.ID) + // return + // } + // // AB HIER: Das ist der Submit-Handler! + // log.Printf("Bearbeiten gespeichert für Session-ID %d", session.ID) + + // sets, err := strconv.Atoi(setsEntry.Text) + // if err != nil { + // dialog.ShowError(fmt.Errorf("Ungültige Sätze-Zahl"), parent) + // return + // } + // duration, err := strconv.Atoi(durationEntry.Text) + // if err != nil { + // dialog.ShowError(fmt.Errorf("Ungültige Dauer"), parent) + // return + // } + // reps, err := strconv.Atoi(repsEntry.Text) + // if err != nil { + // dialog.ShowError(fmt.Errorf("Ungültige Wiederholungszahl"), parent) + // return + // } + // weightLeft, err := strconv.ParseFloat(weightLeftEntry.Text, 64) + // if err != nil { + // dialog.ShowError(fmt.Errorf("Ungültiges Gewicht links"), parent) + // return + // } + // weightRight, err := strconv.ParseFloat(weightRightEntry.Text, 64) + // if err != nil { + // dialog.ShowError(fmt.Errorf("Ungültiges Gewicht rechts"), parent) + // return + // } + + // session.Sets = int64(sets) + // session.Duration = int64(duration) + // session.RepsPerSet = int64(reps) + // session.WeightLeft = weightLeft + // session.WeightRight = weightRight + + // log.Printf("UpdateTraining wird aufgerufen für Session-ID %d", session.ID) + // if err := db.UpdateTraining(session); err != nil { + // dialog.ShowError(err, parent) + // return + // } + // log.Printf("UpdateTraining erfolgreich für Session-ID %d", session.ID) + // dialog.ShowInformation("Erfolg", "Trainingseintrag aktualisiert.", parent) + // refreshData() + // }, + // parent, + // ) + // editDialog.Show() + // }) + + // btns := container.NewHBox(editBtn, deleteBtn) + + // dialog.ShowCustom("Training Details", "Schließen", container.NewVBox(details, btns), parent) + // } + refreshData = func() { var err error history, err = db.GetHistory()