package main import ( "database/sql" "fmt" "log" "fyne.io/fyne/v2" "fyne.io/fyne/v2/app" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/widget" _ "github.com/mattn/go-sqlite3" ) // Data structures for our tables type TableData struct { ID string Name string Value string Section int } // Database functions func initDB(dbPath string) *sql.DB { db, err := sql.Open("sqlite3", dbPath) if err != nil { log.Fatal(err) } // Create table if it doesn't exist createTableSQL := ` CREATE TABLE IF NOT EXISTS items ( id TEXT PRIMARY KEY, name TEXT, value TEXT, section INTEGER );` _, err = db.Exec(createTableSQL) if err != nil { log.Fatal(err) } return db } func getItemsForSection(db *sql.DB, section int) []TableData { rows, err := db.Query("SELECT id, name, value, section FROM items WHERE section = ?", section) if err != nil { log.Printf("Query error: %v", err) return nil } defer rows.Close() var items []TableData for rows.Next() { var item TableData err := rows.Scan(&item.ID, &item.Name, &item.Value, &item.Section) if err != nil { log.Printf("Row scan error: %v", err) continue } items = append(items, item) } return items } func updateItem(db *sql.DB, item TableData) error { _, err := db.Exec( "UPDATE items SET name = ?, value = ? WHERE id = ? AND section = ?", item.Name, item.Value, item.ID, item.Section, ) return err } func main() { myApp := app.New() window := myApp.NewWindow("walletdrain") // Initialize database db := initDB("./app.db") defer db.Close() // Insert some sample data if the database is empty var count int err := db.QueryRow("SELECT COUNT(*) FROM items").Scan(&count) if err != nil { log.Fatal(err) } if count == 0 { sampleData := []TableData{ {"1", "Item 1", "Value 1", 1}, {"2", "Item 2", "Value 2", 1}, {"3", "Section 2 Item 1", "Value 1", 2}, {"4", "Section 2 Item 2", "Value 2", 2}, {"5", "Section 3 Item 1", "Value 1", 3}, {"6", "Section 3 Item 2", "Value 2", 3}, } for _, item := range sampleData { _, err := db.Exec( "INSERT INTO items (id, name, value, section) VALUES (?, ?, ?, ?)", item.ID, item.Name, item.Value, item.Section, ) if err != nil { log.Printf("Error inserting sample data: %v", err) } } } // Function to create a section view with table and side panel createSectionView := func(sectionNum int, onBack func()) *fyne.Container { // Get initial data for this section data := getItemsForSection(db, sectionNum) // Create edit panel widgets idEntry := widget.NewEntry() nameEntry := widget.NewEntry() valueEntry := widget.NewEntry() // Function to refresh data and update table refreshData := func() { data = getItemsForSection(db, sectionNum) } // Create table table := widget.NewTable( func() (int, int) { return len(data), 3 // Rows and columns }, func() fyne.CanvasObject { return widget.NewLabel("Cell") }, func(i widget.TableCellID, o fyne.CanvasObject) { label := o.(*widget.Label) if i.Row < len(data) { switch i.Col { case 0: label.SetText(data[i.Row].ID) case 1: label.SetText(data[i.Row].Name) case 2: label.SetText(data[i.Row].Value) } } }, ) // Create the side panel editPanel := container.NewVBox( widget.NewLabel("Edit Item"), widget.NewLabel("ID:"), idEntry, widget.NewLabel("Name:"), nameEntry, widget.NewLabel("Value:"), valueEntry, widget.NewButton("Save", func() { item := TableData{ ID: idEntry.Text, Name: nameEntry.Text, Value: valueEntry.Text, Section: sectionNum, } err := updateItem(db, item) if err != nil { log.Printf("Error updating item: %v", err) } else { refreshData() table.Refresh() } }), ) editPanel.Hide() // Handle table selection table.OnSelected = func(id widget.TableCellID) { editPanel.Show() if id.Row < len(data) { idEntry.SetText(data[id.Row].ID) nameEntry.SetText(data[id.Row].Name) valueEntry.SetText(data[id.Row].Value) } } // Create header with back button header := container.NewHBox( widget.NewButton("Back", onBack), widget.NewLabel(fmt.Sprintf("Section %d", sectionNum)), ) // Create split container for table and edit panel split := container.NewHSplit(table, editPanel) // Arrange everything vertically return container.NewBorder(header, nil, nil, nil, split) } // Create the main content container that will hold our views content := container.NewStack() // Declare sectionSelect before using it in closures var sectionSelect *fyne.Container sectionSelect = container.NewVBox( widget.NewLabel("Select a Section"), widget.NewButton("Section 1", func() { content.Objects = []fyne.CanvasObject{ createSectionView(1, func() { content.Objects = []fyne.CanvasObject{sectionSelect} content.Refresh() }), } content.Refresh() }), widget.NewButton("Section 2", func() { content.Objects = []fyne.CanvasObject{ createSectionView(2, func() { content.Objects = []fyne.CanvasObject{sectionSelect} content.Refresh() }), } content.Refresh() }), widget.NewButton("Section 3", func() { content.Objects = []fyne.CanvasObject{ createSectionView(3, func() { content.Objects = []fyne.CanvasObject{sectionSelect} content.Refresh() }), } content.Refresh() }), ) // Initialize with section selection screen content.Objects = []fyne.CanvasObject{sectionSelect} // Set up the window window.SetContent(content) window.Resize(fyne.NewSize(800, 600)) window.ShowAndRun() }