204 lines
5.7 KiB
Go
204 lines
5.7 KiB
Go
package ui
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"strconv"
|
|
|
|
"fyne.io/fyne/v2"
|
|
"fyne.io/fyne/v2/container"
|
|
"fyne.io/fyne/v2/dialog"
|
|
"fyne.io/fyne/v2/theme"
|
|
"fyne.io/fyne/v2/widget"
|
|
"git.patanix.de/git/kettlebell-app/internal/data"
|
|
"git.patanix.de/git/kettlebell-app/internal/ui/utils"
|
|
)
|
|
|
|
func MakeHistoryScreen(db *data.DatabaseService, parent fyne.Window) fyne.CanvasObject {
|
|
var history []data.TrainingSession
|
|
|
|
placeholder := widget.NewLabel("Noch keine Trainingsdaten vorhanden.")
|
|
|
|
var showDetailDialog func(session *data.TrainingSession, id int)
|
|
var refreshData func()
|
|
|
|
list := widget.NewList(
|
|
func() int { return len(history) },
|
|
func() fyne.CanvasObject {
|
|
return container.NewGridWithColumns(4,
|
|
widget.NewLabel(""),
|
|
widget.NewLabel(""),
|
|
widget.NewLabel(""),
|
|
widget.NewLabel(""),
|
|
)
|
|
},
|
|
func(i widget.ListItemID, o fyne.CanvasObject) {
|
|
session := history[i]
|
|
row := o.(*fyne.Container)
|
|
row.Objects[0].(*widget.Label).SetText(session.Date.Format("02.01.2006"))
|
|
row.Objects[1].(*widget.Label).SetText(fmt.Sprintf("%d", session.Sets))
|
|
row.Objects[2].(*widget.Label).SetText(utils.FormatDuration(session.Duration))
|
|
row.Objects[3].(*widget.Label).SetText(fmt.Sprintf("%d", session.RepsPerSet))
|
|
},
|
|
)
|
|
|
|
list.OnSelected = func(id widget.ListItemID) {
|
|
session := &history[id]
|
|
showDetailDialog(session, id)
|
|
list.Unselect(id)
|
|
}
|
|
|
|
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 := 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)),
|
|
)
|
|
|
|
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 {
|
|
err := db.DeleteTraining(session.ID)
|
|
if err != nil {
|
|
dialog.ShowError(err, parent)
|
|
return
|
|
}
|
|
refreshData()
|
|
detailDialog.Hide()
|
|
}
|
|
}, parent)
|
|
})
|
|
|
|
cancelBtn := widget.NewButton("Abbrechen", func() {
|
|
detailDialog.Hide()
|
|
})
|
|
|
|
btns := container.NewHBox(saveBtn, deleteBtn, cancelBtn)
|
|
|
|
content := container.NewVBox(
|
|
info,
|
|
form,
|
|
btns,
|
|
)
|
|
|
|
detailDialog = dialog.NewCustom("Training bearbeiten/löschen", "Schließen", content, parent)
|
|
detailDialog.Show()
|
|
}
|
|
|
|
refreshData = func() {
|
|
var err error
|
|
history, err = db.GetHistory()
|
|
if err != nil {
|
|
log.Printf("Fehler beim Laden der Historie: %v", err)
|
|
dialog.ShowError(err, parent)
|
|
return
|
|
}
|
|
if len(history) == 0 {
|
|
placeholder.Show()
|
|
list.Hide()
|
|
} else {
|
|
placeholder.Hide()
|
|
list.Show()
|
|
}
|
|
list.Refresh()
|
|
}
|
|
|
|
header := container.NewGridWithColumns(4,
|
|
widget.NewLabelWithStyle("Datum", fyne.TextAlignCenter, fyne.TextStyle{Bold: true}),
|
|
widget.NewLabelWithStyle("Sätze", fyne.TextAlignCenter, fyne.TextStyle{Bold: true}),
|
|
widget.NewLabelWithStyle("Dauer", fyne.TextAlignCenter, fyne.TextStyle{Bold: true}),
|
|
widget.NewLabelWithStyle("Reps/Satz", fyne.TextAlignCenter, fyne.TextStyle{Bold: true}),
|
|
)
|
|
|
|
toolbar := widget.NewToolbar(widget.NewToolbarAction(theme.ViewRefreshIcon(), refreshData))
|
|
// content := container.NewVBox(header, container.NewStack(list, container.NewCenter(placeholder)))
|
|
// layout := container.NewBorder(toolbar, nil, nil, nil, content)
|
|
|
|
content := container.NewBorder(
|
|
header,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
container.NewVScroll(list),
|
|
)
|
|
|
|
layout := container.NewBorder(
|
|
toolbar,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
content,
|
|
)
|
|
if layout.Visible() {
|
|
refreshData()
|
|
}
|
|
return layout
|
|
}
|