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" ) type TableData struct { ID int name string price float32 currency string returned_price float32 returned_currency string category string seller string note string } func initDB(dbPath string) *sql.DB { db, err := sql.Open("sqlite3", dbPath) if err != nil { log.Fatal(err) } createTableSQL := ` CREATE TABLE IF NOT EXISTS music ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, price FLOAT, currency TEXT, returned_price FLOAT, returned_currency TEXT, category TEXT, seller TEXT, note TEXT );` _, err = db.Exec(createTableSQL) if err != nil { log.Fatal(err) } return db } func getItemsForCategory(db *sql.DB, category string) []TableData { rows, err := db.Query("SELECT * FROM music WHERE category = ?", category) 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.price, &item.currency, &item.returned_price, &item.returned_currency, &item.category, &item.seller, &item.note, ) 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 music SET name = ?, price = ?, currency = ?, returned_price = ?, returned_currency = ?, category = ?, seller = ?, note = ? WHERE id = ?`, item.name, item.price, item.currency, item.returned_price, item.returned_currency, item.category, item.seller, item.note, item.ID, ) if err != nil { log.Printf("Update error: %v", err) } return err } func createSectionView(db *sql.DB, category string, onBack func()) *fyne.Container { data := getItemsForCategory(db, category) // Create edit panel widgets var currentItem TableData // Store the currently selected item nameEntry := widget.NewEntry() priceEntry := widget.NewEntry() currencyEntry := widget.NewEntry() returnedPriceEntry := widget.NewEntry() returnedCurrencyEntry := widget.NewEntry() sellerEntry := widget.NewEntry() noteEntry := widget.NewMultiLineEntry() refreshData := func() { data = getItemsForCategory(db, category) } // Set up column headers headers := []string{"Name", "Seller", "Price"} columnWidths := []float32{300, 200, 150} table := widget.NewTable( func() (int, int) { return len(data) + 1, len(headers) // +1 for header row }, func() fyne.CanvasObject { label := widget.NewLabel("") label.Wrapping = fyne.TextWrapWord return label }, func(i widget.TableCellID, o fyne.CanvasObject) { label := o.(*widget.Label) label.TextStyle = fyne.TextStyle{} // Reset text style // Header row if i.Row == 0 { label.TextStyle = fyne.TextStyle{Bold: true} if i.Col < len(headers) { label.SetText(headers[i.Col]) } return } // Data rows dataRow := i.Row - 1 // Adjust for header row if dataRow < len(data) { item := data[dataRow] switch i.Col { case 0: label.SetText(item.name) case 1: label.SetText(item.seller) case 2: label.SetText(fmt.Sprintf("%.2f %s", item.price, item.currency)) } } }, ) // Set column widths for i, width := range columnWidths { table.SetColumnWidth(i, width) } editPanel := container.NewVBox( widget.NewLabel("Edit Item"), widget.NewLabel("Name:"), nameEntry, widget.NewLabel("Price:"), priceEntry, widget.NewLabel("Currency:"), currencyEntry, widget.NewLabel("Returned Price:"), returnedPriceEntry, widget.NewLabel("Returned Currency:"), returnedCurrencyEntry, widget.NewLabel("Seller:"), sellerEntry, widget.NewLabel("Note:"), noteEntry, widget.NewButton("Save", func() { var price, returnedPrice float32 fmt.Sscanf(priceEntry.Text, "%f", &price) fmt.Sscanf(returnedPriceEntry.Text, "%f", &returnedPrice) item := TableData{ ID: currentItem.ID, name: nameEntry.Text, price: price, currency: currencyEntry.Text, returned_price: returnedPrice, returned_currency: returnedCurrencyEntry.Text, category: category, seller: sellerEntry.Text, note: noteEntry.Text, } err := updateItem(db, item) if err != nil { log.Printf("Error updating item: %v", err) } else { refreshData() table.Refresh() } }), ) table.OnSelected = func(id widget.TableCellID) { if id.Row > 0 && (id.Row-1) < len(data) { currentItem = data[id.Row-1] // Store the currently selected item nameEntry.SetText(currentItem.name) priceEntry.SetText(fmt.Sprintf("%.2f", currentItem.price)) currencyEntry.SetText(currentItem.currency) returnedPriceEntry.SetText(fmt.Sprintf("%.2f", currentItem.returned_price)) returnedCurrencyEntry.SetText(currentItem.returned_currency) sellerEntry.SetText(currentItem.seller) noteEntry.SetText(currentItem.note) } } header := container.NewHBox( widget.NewButton("Back", onBack), widget.NewLabel(fmt.Sprintf("Category: %s", category)), ) split := container.NewHSplit(table, editPanel) split.SetOffset(0.7) // Give table 70% of the width return container.NewBorder(header, nil, nil, nil, split) } func main() { myApp := app.New() window := myApp.NewWindow("walletdrain") db := initDB("./app.db") defer db.Close() var count int err := db.QueryRow("SELECT COUNT(*) FROM music").Scan(&count) if err != nil { log.Fatal(err) } if count == 0 { sampleData := []TableData{ {name: "Sample Album 1", price: 29.99, currency: "USD", returned_price: 0, returned_currency: "", category: "vinyl", seller: "Record Store", note: "New condition"}, {name: "Sample Album 2", price: 19.99, currency: "EUR", returned_price: 15.00, returned_currency: "EUR", category: "cd", seller: "Online Shop", note: "Used"}, } for _, item := range sampleData { _, err := db.Exec( "INSERT INTO music (name, price, currency, returned_price, returned_currency, category, seller, note) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", item.name, item.price, item.currency, item.returned_price, item.returned_currency, item.category, item.seller, item.note, ) if err != nil { log.Printf("Error inserting sample data: %v", err) } } } content := container.NewStack() var categorySelect *fyne.Container categorySelect = container.NewVBox( widget.NewLabel("Select a Category"), widget.NewButton("Vinyl", func() { content.Objects = []fyne.CanvasObject{ createSectionView(db, "vinyl", func() { content.Objects = []fyne.CanvasObject{categorySelect} content.Refresh() }), } content.Refresh() }), widget.NewButton("CD", func() { content.Objects = []fyne.CanvasObject{ createSectionView(db, "cd", func() { content.Objects = []fyne.CanvasObject{categorySelect} content.Refresh() }), } content.Refresh() }), widget.NewButton("Cassette", func() { content.Objects = []fyne.CanvasObject{ createSectionView(db, "cassette", func() { content.Objects = []fyne.CanvasObject{categorySelect} content.Refresh() }), } content.Refresh() }), ) content.Objects = []fyne.CanvasObject{categorySelect} window.SetContent(content) window.Resize(fyne.NewSize(1024, 768)) window.ShowAndRun() }