refactor: update edit functionality to be less confusing

This commit is contained in:
Patryk Hegenberg 2025-07-04 18:40:47 +02:00
parent 4f8e353d48
commit 519daeec40
4 changed files with 224 additions and 87 deletions

View file

@ -5,4 +5,4 @@ Website = "https://patanix.de"
Name = "kettlebell_tracker" Name = "kettlebell_tracker"
ID = "de.patanix.kettlebell_tracker" ID = "de.patanix.kettlebell_tracker"
Version = "1.0.0" Version = "1.0.0"
Build = 5 Build = 9

View file

@ -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

View file

@ -2,6 +2,7 @@ package data
import ( import (
"database/sql" "database/sql"
"fmt"
"log" "log"
"time" "time"
@ -136,6 +137,20 @@ func (s *DatabaseService) UpdateTraining(session *TrainingSession) error {
SET date = ?, sets = ?, weightLeft = ?, weightRight = ?, repsPerSet = ?, duration = ?, program = ?, blockDay = ? SET date = ?, sets = ?, weightLeft = ?, weightRight = ?, repsPerSet = ?, duration = ?, program = ?, blockDay = ?
WHERE id = ?; WHERE id = ?;
` `
_, err := s.DB.Exec(query, dateStr, session.Sets, session.WeightLeft, session.WeightRight, session.RepsPerSet, session.Duration, session.Program, session.BlockDay, session.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 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
} }

View file

@ -19,7 +19,7 @@ func MakeHistoryScreen(db *data.DatabaseService, parent fyne.Window) fyne.Canvas
placeholder := widget.NewLabel("Noch keine Trainingsdaten vorhanden.") 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() var refreshData func()
list := widget.NewList( list := widget.NewList(
@ -43,42 +43,17 @@ func MakeHistoryScreen(db *data.DatabaseService, parent fyne.Window) fyne.Canvas
) )
list.OnSelected = func(id widget.ListItemID) { list.OnSelected = func(id widget.ListItemID) {
session := history[id] session := &history[id]
showDetailDialog(session, id) showDetailDialog(session, id)
list.Unselect(id) list.Unselect(id)
} }
showDetailDialog = func(session data.TrainingSession, id int) { 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 := widget.NewEntry()
setsEntry.SetText(fmt.Sprintf("%d", session.Sets)) setsEntry.SetText(fmt.Sprintf("%d", session.Sets))
durationEntry := widget.NewEntry() durationEntry := widget.NewEntry()
durationEntry.SetText(fmt.Sprintf("%d", session.Duration)) // Dauer in Sekunden durationEntry.SetText(fmt.Sprintf("%d", session.Duration))
repsEntry := widget.NewEntry() repsEntry := widget.NewEntry()
repsEntry.SetText(fmt.Sprintf("%d", session.RepsPerSet)) repsEntry.SetText(fmt.Sprintf("%d", session.RepsPerSet))
@ -89,37 +64,47 @@ func MakeHistoryScreen(db *data.DatabaseService, parent fyne.Window) fyne.Canvas
weightRightEntry := widget.NewEntry() weightRightEntry := widget.NewEntry()
weightRightEntry.SetText(fmt.Sprintf("%.1f", session.WeightRight)) weightRightEntry.SetText(fmt.Sprintf("%.1f", session.WeightRight))
form := &widget.Form{ // Info-Header
Items: []*widget.FormItem{ info := container.NewVBox(
{Text: "Sätze", Widget: setsEntry}, widget.NewLabel(fmt.Sprintf("Datum: %s", session.Date.Format("02.01.2006 15:04"))),
{Text: "Dauer (Sekunden)", Widget: durationEntry}, widget.NewLabel(fmt.Sprintf("Programm: %s", session.Program)),
{Text: "Reps/Satz", Widget: repsEntry}, widget.NewLabel(fmt.Sprintf("Block-Tag: %d", session.BlockDay)),
{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 {
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) dialog.ShowError(fmt.Errorf("Ungültige Sätze-Zahl"), parent)
return return
} }
if duration, err = strconv.Atoi(durationEntry.Text); err != nil { duration, err := strconv.Atoi(durationEntry.Text)
if err != nil {
dialog.ShowError(fmt.Errorf("Ungültige Dauer"), parent) dialog.ShowError(fmt.Errorf("Ungültige Dauer"), parent)
return return
} }
if reps, err = strconv.Atoi(repsEntry.Text); err != nil { reps, err := strconv.Atoi(repsEntry.Text)
if err != nil {
dialog.ShowError(fmt.Errorf("Ungültige Wiederholungszahl"), parent) dialog.ShowError(fmt.Errorf("Ungültige Wiederholungszahl"), parent)
return return
} }
if weightLeft, err = strconv.ParseFloat(weightLeftEntry.Text, 64); err != nil { weightLeft, err := strconv.ParseFloat(weightLeftEntry.Text, 64)
if err != nil {
dialog.ShowError(fmt.Errorf("Ungültiges Gewicht links"), parent) dialog.ShowError(fmt.Errorf("Ungültiges Gewicht links"), parent)
return return
} }
if weightRight, err = strconv.ParseFloat(weightRightEntry.Text, 64); err != nil { weightRight, err := strconv.ParseFloat(weightRightEntry.Text, 64)
if err != nil {
dialog.ShowError(fmt.Errorf("Ungültiges Gewicht rechts"), parent) dialog.ShowError(fmt.Errorf("Ungültiges Gewicht rechts"), parent)
return return
} }
@ -130,24 +115,160 @@ func MakeHistoryScreen(db *data.DatabaseService, parent fyne.Window) fyne.Canvas
session.WeightLeft = weightLeft session.WeightLeft = weightLeft
session.WeightRight = weightRight session.WeightRight = weightRight
if err := db.UpdateTraining(&session); err != nil { if err := db.UpdateTraining(session); err != nil {
dialog.ShowError(err, parent) dialog.ShowError(err, parent)
return return
} }
dialog.ShowInformation("Erfolg", "Trainingseintrag aktualisiert.", parent) dialog.ShowInformation("Erfolg", "Trainingseintrag aktualisiert.", parent)
refreshData() refreshData()
}, detailDialog.Hide()
} })
dialog.ShowForm("Training bearbeiten", "Speichern", "Abbrechen", form.Items, func(ok bool) { 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()
detailDialog.Hide()
}
}, parent) }, parent)
}) })
btns := container.NewHBox(editBtn, deleteBtn) cancelBtn := widget.NewButton("Abbrechen", func() {
detailDialog.Hide()
})
dialog.ShowCustom("Training Details", "Schließen", container.NewVBox(details, btns), parent) btns := container.NewHBox(saveBtn, deleteBtn, cancelBtn)
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() { refreshData = func() {
var err error var err error
history, err = db.GetHistory() history, err = db.GetHistory()