@@ -33,7 +33,8 @@ func (m Model) generateCartContent() string {
|
||||
Align(lipgloss.Center).
|
||||
Width(m.widthContent).
|
||||
Padding(2, 0)
|
||||
return emptyStyle.Render("Your cart is empty\n\nPress s to go back to shop")
|
||||
render := emptyStyle.Render("Your cart is empty\n\nPress s to go back to shop")
|
||||
return render
|
||||
}
|
||||
|
||||
cartItems := ""
|
||||
@@ -148,7 +149,8 @@ func (m Model) CartUpdate(msg tea.Msg) (Model, tea.Cmd) {
|
||||
cartItems := m.GetCartItemsSlice()
|
||||
if m.cart.cursor >= 0 && m.cart.cursor < len(cartItems) {
|
||||
cartItems[m.cart.cursor].Quantity++
|
||||
return m, m.syncCartItemCmd(cartItems[m.cart.cursor].CoffeeID, cartItems[m.cart.cursor].Quantity)
|
||||
m, cmd := m.syncCartItemCmd(cartItems[m.cart.cursor].CoffeeID, cartItems[m.cart.cursor].Quantity)
|
||||
return m, cmd
|
||||
}
|
||||
case "-", "_":
|
||||
cartItems := m.GetCartItemsSlice()
|
||||
@@ -165,7 +167,8 @@ func (m Model) CartUpdate(msg tea.Msg) (Model, tea.Cmd) {
|
||||
}
|
||||
newQty = 0
|
||||
}
|
||||
return m, m.syncCartItemCmd(coffeeID, newQty)
|
||||
m, cmd := m.syncCartItemCmd(coffeeID, newQty)
|
||||
return m, cmd
|
||||
}
|
||||
case "p", "enter":
|
||||
if !m.IsCartEmpty() {
|
||||
|
||||
@@ -346,7 +346,7 @@ func (m Model) checkoutStep() int {
|
||||
|
||||
// updateLayout recalculates all layout variables from the raw viewport dimensions.
|
||||
// This should be called whenever the terminal is resized.
|
||||
func (m *Model) updateLayout(width, height int) {
|
||||
func (m Model) updateLayout(width, height int) Model {
|
||||
m.viewportWidth = width
|
||||
m.viewportHeight = height
|
||||
switch {
|
||||
@@ -369,6 +369,7 @@ func (m *Model) updateLayout(width, height int) {
|
||||
}
|
||||
|
||||
m.widthContent = m.widthContainer - 2
|
||||
return m
|
||||
}
|
||||
|
||||
// ProductsMsg is sent when products are fetched from API
|
||||
@@ -646,15 +647,15 @@ func (m Model) checkoutWithSavedCard() tea.Cmd {
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Model) syncCartItemCmd(coffeeID uint, quantity int) tea.Cmd {
|
||||
func (m Model) syncCartItemCmd(coffeeID uint, quantity int) (Model, tea.Cmd) {
|
||||
if m.APIClient == nil || m.User == nil {
|
||||
return nil
|
||||
return m, nil
|
||||
}
|
||||
|
||||
updateID := time.Now().UTC().UnixMilli()
|
||||
m.lastCartUpdateID = updateID
|
||||
|
||||
return func() tea.Msg {
|
||||
return m, func() tea.Msg {
|
||||
cart, err := m.APIClient.SetCartItem(coffeeID, quantity)
|
||||
return CartSyncedMsg{
|
||||
UpdateID: updateID,
|
||||
@@ -748,10 +749,10 @@ func (m Model) saveCardOnlyCmd(form PaymentFormCompleteMsg) tea.Cmd {
|
||||
|
||||
// loadCartFromAPI populates the in-memory cart map from an API CartData response
|
||||
// It matches cart items to local Coffees by ID so the Coffee struct is populated
|
||||
func (m *Model) loadCartFromAPI(cartData *api.CartData) {
|
||||
func (m Model) loadCartFromAPI(cartData *api.CartData) Model {
|
||||
m.Cart = make(map[uint]*models.CartItem)
|
||||
if cartData == nil {
|
||||
return
|
||||
return m
|
||||
}
|
||||
|
||||
for _, item := range cartData.Items {
|
||||
@@ -765,14 +766,15 @@ func (m *Model) loadCartFromAPI(cartData *api.CartData) {
|
||||
if m.cart.cursor >= len(m.Cart) {
|
||||
m.cart.cursor = 0
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// GetCartItemsSlice converts the cart map to a sorted slice for consistent iteration.
|
||||
func (m Model) GetCartItemsSlice() []*models.CartItem {
|
||||
// Get keys and sort them for stable ordering
|
||||
keys := make([]uint, 0, len(m.Cart))
|
||||
for key := range m.Cart {
|
||||
keys = append(keys, key)
|
||||
for cartKey := range m.Cart {
|
||||
keys = append(keys, cartKey)
|
||||
}
|
||||
|
||||
// Sort keys to ensure consistent order
|
||||
@@ -780,8 +782,8 @@ func (m Model) GetCartItemsSlice() []*models.CartItem {
|
||||
|
||||
// Build items slice in sorted order
|
||||
items := make([]*models.CartItem, 0, len(m.Cart))
|
||||
for _, key := range keys {
|
||||
items = append(items, m.Cart[key])
|
||||
for _, cartKey := range keys {
|
||||
items = append(items, m.Cart[cartKey])
|
||||
}
|
||||
return items
|
||||
}
|
||||
@@ -890,7 +892,7 @@ func newModelWithRenderer(username string, renderer *lipgloss.Renderer) Model {
|
||||
APIClient: api.NewClient("http://localhost:8080", ""),
|
||||
FAQs: LoadFaqs(),
|
||||
}
|
||||
m.updateLayout(120, 30)
|
||||
m = m.updateLayout(120, 30)
|
||||
return m
|
||||
}
|
||||
|
||||
|
||||
@@ -370,7 +370,7 @@ func (m Model) renderPaymentHttpsView() string {
|
||||
return baseStyle.Render(" generating payment link...")
|
||||
}
|
||||
|
||||
qr, qrSize, err := qrfefe.Generate(0, *m.payment.collectURL)
|
||||
qr, qrSize, err := qrfefe.Generate(*m.payment.collectURL)
|
||||
if err != nil || qrSize > m.widthContent {
|
||||
// QR too wide for the terminal — just show the URL.
|
||||
return baseStyle.Render("open in browser to add payment information:") + "\n\n" +
|
||||
|
||||
@@ -180,7 +180,8 @@ func (m Model) ShopUpdate(msg tea.Msg) (Model, tea.Cmd) {
|
||||
} else {
|
||||
m.Cart[coffeeID] = &models.CartItem{CoffeeID: coffeeID, Coffee: coffee, Quantity: 1}
|
||||
}
|
||||
return m, m.syncCartItemCmd(coffeeID, m.Cart[coffeeID].Quantity)
|
||||
m, cmd := m.syncCartItemCmd(coffeeID, m.Cart[coffeeID].Quantity)
|
||||
return m, cmd
|
||||
case "-", "_":
|
||||
coffeeID := coffee.ID
|
||||
if item, exists := m.Cart[coffeeID]; exists {
|
||||
@@ -190,7 +191,8 @@ func (m Model) ShopUpdate(msg tea.Msg) (Model, tea.Cmd) {
|
||||
delete(m.Cart, coffeeID)
|
||||
newQty = 0
|
||||
}
|
||||
return m, m.syncCartItemCmd(coffeeID, newQty)
|
||||
m, cmd := m.syncCartItemCmd(coffeeID, newQty)
|
||||
return m, cmd
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
// Resize debounce tick, must fire before page dispatch
|
||||
if tick, ok := msg.(resizeTickMsg); ok {
|
||||
if tick.seq == m.resizeSeq {
|
||||
m.updateLayout(m.pendingWidth, m.pendingHeight)
|
||||
m = m.updateLayout(m.pendingWidth, m.pendingHeight)
|
||||
switch m.currentPage {
|
||||
case shopPage:
|
||||
m = m.updateShopViewports()
|
||||
@@ -97,7 +97,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
m.Username = u.Name
|
||||
}
|
||||
cart := &api.CartData{Items: msg.Data.Cart}
|
||||
m.loadCartFromAPI(cart)
|
||||
m = m.loadCartFromAPI(cart)
|
||||
m.SavedAddresses = msg.Data.Addresses
|
||||
m.SavedCards = msg.Data.Cards
|
||||
m.Orders = msg.Data.Orders
|
||||
@@ -112,7 +112,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
return m, m.fetchCartCmd
|
||||
}
|
||||
if msg.UpdateID == m.lastCartUpdateID {
|
||||
m.loadCartFromAPI(msg.Cart)
|
||||
m = m.loadCartFromAPI(msg.Cart)
|
||||
}
|
||||
return m, nil
|
||||
case tokenRefreshTickMsg:
|
||||
|
||||
Reference in New Issue
Block a user