Compare commits
1 Commits
accountVie
...
footer
| Author | SHA1 | Date | |
|---|---|---|---|
| d66b41eed3 |
@@ -356,55 +356,110 @@ func (m Model) AccountUpdate(msg tea.Msg) (Model, tea.Cmd) {
|
||||
m.account.orderViewState = 1
|
||||
m.account.orderCursor = 0
|
||||
m.account.scrollOffset = 0
|
||||
m.footer = []footerCommand{
|
||||
{key: "j/k", value: "orders"},
|
||||
{key: "enter", value: "details"},
|
||||
{key: "esc", value: "back"},
|
||||
{key: "q", value: "quit"},
|
||||
}
|
||||
} else if m.account.orderViewState == 1 {
|
||||
m.account.orderViewState = 2
|
||||
m.account.scrollOffset = 0
|
||||
m.footer = []footerCommand{
|
||||
{key: "esc", value: "back"},
|
||||
{key: "s", value: "shop"},
|
||||
{key: "q", value: "quit"},
|
||||
}
|
||||
}
|
||||
}
|
||||
case "ssh keys":
|
||||
if !m.account.sshKeyListFocused {
|
||||
m.account.sshKeyListFocused = true
|
||||
m.account.sshKeyCursor = 0
|
||||
m.footer = []footerCommand{
|
||||
{key: "j/k", value: "keys"},
|
||||
{key: "x", value: "delete"},
|
||||
{key: "esc", value: "back"},
|
||||
}
|
||||
}
|
||||
case "addresses":
|
||||
if !m.account.addressListFocused {
|
||||
m.account.addressListFocused = true
|
||||
m.account.addressCursor = 0
|
||||
m.footer = []footerCommand{
|
||||
{key: "j/k", value: "addresses"},
|
||||
{key: "x", value: "delete"},
|
||||
{key: "esc", value: "back"},
|
||||
}
|
||||
}
|
||||
case "cards":
|
||||
if !m.account.cardListFocused {
|
||||
m.account.cardListFocused = true
|
||||
m.account.cardCursor = 0
|
||||
m.footer = []footerCommand{
|
||||
{key: "j/k", value: "cards"},
|
||||
{key: "x", value: "delete"},
|
||||
{key: "esc", value: "back"},
|
||||
}
|
||||
}
|
||||
case "faq":
|
||||
if !m.account.faqFocused {
|
||||
m.account.faqFocused = true
|
||||
m.account.scrollOffset = 0
|
||||
m.footer = []footerCommand{
|
||||
{key: "j/k", value: "scroll"},
|
||||
{key: "esc", value: "back"},
|
||||
{key: "s", value: "shop"},
|
||||
{key: "c", value: "cart"},
|
||||
{key: "q", value: "quit"},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case "esc":
|
||||
accountDefaultFooter := []footerCommand{
|
||||
{key: "j/k", value: "navigate"},
|
||||
{key: "enter", value: "select"},
|
||||
{key: "s", value: "shop"},
|
||||
{key: "c", value: "cart"},
|
||||
{key: "?", value: "help"},
|
||||
{key: "q", value: "quit"},
|
||||
}
|
||||
if m.account.addressDeleting != nil {
|
||||
m.account.addressDeleting = nil
|
||||
} else if m.account.addressListFocused {
|
||||
m.account.addressListFocused = false
|
||||
m.account.addressCursor = 0
|
||||
m.footer = accountDefaultFooter
|
||||
} else if m.account.cardDeleting != nil {
|
||||
m.account.cardDeleting = nil
|
||||
} else if m.account.cardListFocused {
|
||||
m.account.cardListFocused = false
|
||||
m.account.cardCursor = 0
|
||||
m.footer = accountDefaultFooter
|
||||
} else if m.account.sshKeyDeleting != nil {
|
||||
m.account.sshKeyDeleting = nil
|
||||
} else if m.account.sshKeyListFocused {
|
||||
m.account.sshKeyListFocused = false
|
||||
m.account.sshKeyCursor = 0
|
||||
m.footer = accountDefaultFooter
|
||||
} else if m.account.faqFocused {
|
||||
m.account.faqFocused = false
|
||||
m.account.scrollOffset = 0
|
||||
m.footer = accountDefaultFooter
|
||||
} else if m.account.orderViewState > 0 {
|
||||
m.account.orderViewState--
|
||||
m.account.scrollOffset = 0
|
||||
if m.account.orderViewState == 1 {
|
||||
m.footer = []footerCommand{
|
||||
{key: "j/k", value: "orders"},
|
||||
{key: "enter", value: "details"},
|
||||
{key: "esc", value: "back"},
|
||||
{key: "q", value: "quit"},
|
||||
}
|
||||
} else {
|
||||
m.footer = accountDefaultFooter
|
||||
}
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
|
||||
@@ -1,194 +1,25 @@
|
||||
package tui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
)
|
||||
|
||||
func (m Model) BuildFooter() string {
|
||||
// Style for keybinds (bold)
|
||||
keybindStyle := m.theme.TextDim().Bold(true)
|
||||
|
||||
// Style for descriptions (normal)
|
||||
descStyle := m.theme.TextDim()
|
||||
|
||||
// On small terminals, only show the menu hint
|
||||
if m.size == small {
|
||||
footerText := keybindStyle.Render("m") + " " + descStyle.Render("menu")
|
||||
return lipgloss.NewStyle().Align(lipgloss.Center).Width(m.widthContainer).Render(footerText)
|
||||
}
|
||||
|
||||
var footerText string
|
||||
if m.account.faqFocused {
|
||||
footerText = fmt.Sprintf("%s %s %s %s %s %s %s %s %s %s",
|
||||
keybindStyle.Render("j/k"),
|
||||
descStyle.Render("scroll"),
|
||||
keybindStyle.Render("esc"),
|
||||
descStyle.Render("back"),
|
||||
keybindStyle.Render("s"),
|
||||
descStyle.Render("shop"),
|
||||
keybindStyle.Render("c"),
|
||||
descStyle.Render("cart"),
|
||||
keybindStyle.Render("q"),
|
||||
descStyle.Render("quit"),
|
||||
)
|
||||
} else if m.currentPage == accountPage {
|
||||
switch m.account.orderViewState {
|
||||
case 2:
|
||||
// Viewing single order detail
|
||||
footerText = fmt.Sprintf("%s %s %s %s %s %s",
|
||||
keybindStyle.Render("esc"),
|
||||
descStyle.Render("back"),
|
||||
keybindStyle.Render("s"),
|
||||
descStyle.Render("shop"),
|
||||
keybindStyle.Render("q"),
|
||||
descStyle.Render("quit"),
|
||||
)
|
||||
case 1:
|
||||
// Browsing order list
|
||||
footerText = fmt.Sprintf("%s %s %s %s %s %s %s %s",
|
||||
keybindStyle.Render("j/k"),
|
||||
descStyle.Render("orders"),
|
||||
keybindStyle.Render("enter"),
|
||||
descStyle.Render("details"),
|
||||
keybindStyle.Render("esc"),
|
||||
descStyle.Render("back"),
|
||||
keybindStyle.Render("q"),
|
||||
descStyle.Render("quit"),
|
||||
)
|
||||
default:
|
||||
// Account tabs
|
||||
footerText = fmt.Sprintf("%s %s %s %s %s %s %s %s %s %s %s %s",
|
||||
keybindStyle.Render("j/k"),
|
||||
descStyle.Render("navigate"),
|
||||
keybindStyle.Render("enter"),
|
||||
descStyle.Render("select"),
|
||||
keybindStyle.Render("s"),
|
||||
descStyle.Render("shop"),
|
||||
keybindStyle.Render("c"),
|
||||
descStyle.Render("cart"),
|
||||
keybindStyle.Render("?"),
|
||||
descStyle.Render("help"),
|
||||
keybindStyle.Render("q"),
|
||||
descStyle.Render("quit"),
|
||||
)
|
||||
}
|
||||
} else if m.currentPage == confirmPage {
|
||||
// Confirmation screen
|
||||
footerText = fmt.Sprintf("%s %s %s %s",
|
||||
keybindStyle.Render("esc"),
|
||||
descStyle.Render("back to shop"),
|
||||
keybindStyle.Render("q"),
|
||||
descStyle.Render("quit"),
|
||||
)
|
||||
} else if m.currentPage == shippingPage {
|
||||
if m.shipping.view == 0 && m.shipping.form == nil {
|
||||
// Address list
|
||||
footerText = fmt.Sprintf("%s %s %s %s %s %s %s %s",
|
||||
keybindStyle.Render("j/k"),
|
||||
descStyle.Render("addresses"),
|
||||
keybindStyle.Render("enter"),
|
||||
descStyle.Render("select"),
|
||||
keybindStyle.Render("d/x"),
|
||||
descStyle.Render("delete"),
|
||||
keybindStyle.Render("esc"),
|
||||
descStyle.Render("back"),
|
||||
)
|
||||
} else {
|
||||
// Shipping form
|
||||
footerText = fmt.Sprintf("%s %s %s %s %s %s",
|
||||
keybindStyle.Render("tab"),
|
||||
descStyle.Render("next"),
|
||||
keybindStyle.Render("enter"),
|
||||
descStyle.Render("submit"),
|
||||
keybindStyle.Render("esc"),
|
||||
descStyle.Render("back"),
|
||||
)
|
||||
}
|
||||
} else if m.currentPage == paymentPage {
|
||||
if m.payment.view == 0 && m.payment.form == nil {
|
||||
// Card list
|
||||
footerText = fmt.Sprintf("%s %s %s %s %s %s %s %s",
|
||||
keybindStyle.Render("j/k"),
|
||||
descStyle.Render("cards"),
|
||||
keybindStyle.Render("enter"),
|
||||
descStyle.Render("select"),
|
||||
keybindStyle.Render("d/x"),
|
||||
descStyle.Render("delete"),
|
||||
keybindStyle.Render("esc"),
|
||||
descStyle.Render("back"),
|
||||
)
|
||||
} else if m.CheckingOut {
|
||||
// Submitting order
|
||||
footerText = descStyle.Render("submitting order...")
|
||||
} else {
|
||||
// Payment form
|
||||
footerText = fmt.Sprintf("%s %s %s %s %s %s",
|
||||
keybindStyle.Render("tab"),
|
||||
descStyle.Render("next"),
|
||||
keybindStyle.Render("enter"),
|
||||
descStyle.Render("submit"),
|
||||
keybindStyle.Render("esc"),
|
||||
descStyle.Render("back"),
|
||||
)
|
||||
}
|
||||
} else if m.currentPage == cartPage {
|
||||
// In cart view, show proceed option
|
||||
if !m.IsCartEmpty() {
|
||||
footerText = fmt.Sprintf("%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s",
|
||||
keybindStyle.Render("j/k"),
|
||||
descStyle.Render("items"),
|
||||
keybindStyle.Render("+/-"),
|
||||
descStyle.Render("qty"),
|
||||
keybindStyle.Render("p/enter"),
|
||||
descStyle.Render("checkout"),
|
||||
keybindStyle.Render("s"),
|
||||
descStyle.Render("shop"),
|
||||
keybindStyle.Render("a"),
|
||||
descStyle.Render("account"),
|
||||
keybindStyle.Render("pgup/pgdn"),
|
||||
descStyle.Render("scroll"),
|
||||
keybindStyle.Render("?"),
|
||||
descStyle.Render("help"),
|
||||
keybindStyle.Render("q"),
|
||||
descStyle.Render("quit"),
|
||||
)
|
||||
} else {
|
||||
footerText = fmt.Sprintf("%s %s %s %s %s %s %s %s %s %s %s %s",
|
||||
keybindStyle.Render("j/k"),
|
||||
descStyle.Render("items"),
|
||||
keybindStyle.Render("+/-"),
|
||||
descStyle.Render("qty"),
|
||||
keybindStyle.Render("s"),
|
||||
descStyle.Render("shop"),
|
||||
keybindStyle.Render("a"),
|
||||
descStyle.Render("account"),
|
||||
keybindStyle.Render("?"),
|
||||
descStyle.Render("help"),
|
||||
keybindStyle.Render("q"),
|
||||
descStyle.Render("quit"),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
footerText = fmt.Sprintf("%s %s %s %s %s %s %s %s %s %s %s %s",
|
||||
keybindStyle.Render("j/k"),
|
||||
descStyle.Render("products"),
|
||||
keybindStyle.Render("+/-"),
|
||||
descStyle.Render("qty"),
|
||||
keybindStyle.Render("c"),
|
||||
descStyle.Render("cart"),
|
||||
keybindStyle.Render("a"),
|
||||
descStyle.Render("account"),
|
||||
keybindStyle.Render("?"),
|
||||
descStyle.Render("help"),
|
||||
keybindStyle.Render("q"),
|
||||
descStyle.Render("quit"),
|
||||
)
|
||||
parts := []string{}
|
||||
for _, cmd := range m.footer {
|
||||
parts = append(parts, keybindStyle.Render(cmd.key)+" "+descStyle.Render(cmd.value))
|
||||
}
|
||||
footerText := strings.Join(parts, " ")
|
||||
|
||||
return lipgloss.NewStyle().
|
||||
Align(lipgloss.Center).
|
||||
Width(m.widthContainer).
|
||||
Render(footerText)
|
||||
return lipgloss.NewStyle().Align(lipgloss.Center).Width(m.widthContainer).Render(footerText)
|
||||
}
|
||||
|
||||
@@ -53,6 +53,11 @@ type resizeTickMsg struct {
|
||||
// this prevents flickering when resizing the terminal
|
||||
const resizeDebounce = 50 * time.Millisecond
|
||||
|
||||
type footerCommand struct {
|
||||
key string
|
||||
value string
|
||||
}
|
||||
|
||||
type Model struct {
|
||||
// User authentication
|
||||
User *models.User
|
||||
@@ -121,6 +126,9 @@ type Model struct {
|
||||
account accountState
|
||||
review reviewState
|
||||
confirm confirmState
|
||||
|
||||
// Footer
|
||||
footer []footerCommand
|
||||
}
|
||||
|
||||
type shopState struct {
|
||||
@@ -208,18 +216,55 @@ func (m Model) SwitchPage(p page) Model {
|
||||
func (m Model) ShopSwitch() (Model, tea.Cmd) {
|
||||
m = m.SwitchPage(shopPage)
|
||||
m = m.updateShopViewports()
|
||||
m.footer = []footerCommand{
|
||||
{key: "j/k", value: "products"},
|
||||
{key: "+/-", value: "qty"},
|
||||
{key: "c", value: "cart"},
|
||||
{key: "a", value: "account"},
|
||||
{key: "?", value: "help"},
|
||||
{key: "q", value: "quit"},
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (m Model) CartSwitch() (Model, tea.Cmd) {
|
||||
m = m.SwitchPage(cartPage)
|
||||
m = m.updateCartViewport()
|
||||
if m.IsCartEmpty() {
|
||||
|
||||
m.footer = []footerCommand{
|
||||
{key: "j/k", value: "items"},
|
||||
{key: "+/-", value: "qty"},
|
||||
{key: "s", value: "shop"},
|
||||
{key: "a", value: "account"},
|
||||
{key: "?", value: "help"},
|
||||
{key: "q", value: "quit"},
|
||||
}
|
||||
} else {
|
||||
m.footer = []footerCommand{
|
||||
{key: "j/k", value: "items"},
|
||||
{key: "+/-", value: "qty"},
|
||||
{key: "p/enter", value: "checkout"},
|
||||
{key: "s", value: "shop"},
|
||||
{key: "a", value: "account"},
|
||||
{key: "pgup/pgdn", value: "scroll"},
|
||||
{key: "?", value: "help"},
|
||||
{key: "q", value: "quit"},
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (m Model) AccountSwitch() (Model, tea.Cmd) {
|
||||
m = m.SwitchPage(accountPage)
|
||||
m.account = accountState{}
|
||||
m.footer = []footerCommand{
|
||||
{key: "j/k", value: "navigate"},
|
||||
{key: "enter", value: "select"},
|
||||
{key: "s", value: "shop"},
|
||||
{key: "?", value: "help"},
|
||||
{key: "q", value: "quit"},
|
||||
}
|
||||
if !m.OrdersLoaded {
|
||||
return m, m.fetchOrdersCmd()
|
||||
}
|
||||
@@ -230,6 +275,12 @@ func (m Model) ShippingSwitch() (Model, tea.Cmd) {
|
||||
m = m.SwitchPage(shippingPage)
|
||||
m.shipping = shippingState{}
|
||||
m = m.updateShippingViewport()
|
||||
m.footer = []footerCommand{
|
||||
{key: "j/k", value: "addresses"},
|
||||
{key: "enter", value: "select"},
|
||||
{key: "d/x", value: "delete"},
|
||||
{key: "esc", value: "back"},
|
||||
}
|
||||
return m, m.fetchAddressesCmd()
|
||||
}
|
||||
|
||||
@@ -237,11 +288,21 @@ func (m Model) PaymentSwitch() (Model, tea.Cmd) {
|
||||
m = m.SwitchPage(paymentPage)
|
||||
m.payment = paymentState{}
|
||||
m.SelectedCard = nil
|
||||
m.footer = []footerCommand{
|
||||
{key: "j/k", value: "cards"},
|
||||
{key: "enter", value: "select"},
|
||||
{key: "d/x", value: "delete"},
|
||||
{key: "esc", value: "back"},
|
||||
}
|
||||
return m, m.fetchCardsCmd()
|
||||
}
|
||||
|
||||
func (m Model) ReviewSwitch() (Model, tea.Cmd) {
|
||||
m = m.SwitchPage(reviewPage)
|
||||
m.footer = []footerCommand{
|
||||
{key: "enter", value: "confirm"},
|
||||
{key: "esc", value: "back"},
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
@@ -249,6 +310,10 @@ func (m Model) ConfirmSwitch() (Model, tea.Cmd) {
|
||||
m = m.SwitchPage(confirmPage)
|
||||
m.confirm = confirmState{}
|
||||
m = m.updateConfirmViewport()
|
||||
m.footer = []footerCommand{
|
||||
{key: "esc", value: "back to shop"},
|
||||
{key: "q", value: "quit"},
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -434,6 +434,11 @@ func (m Model) PaymentUpdate(msg tea.Msg) (Model, tea.Cmd) {
|
||||
m.ErrorMsg = fmt.Sprintf("failed to save card: %v", msg.Err)
|
||||
m.payment.view = 1
|
||||
m.payment.form = m.InitPaymentForm()
|
||||
m.footer = []footerCommand{
|
||||
{key: "tab", value: "next"},
|
||||
{key: "enter", value: "submit"},
|
||||
{key: "esc", value: "back"},
|
||||
}
|
||||
return m, m.payment.form.form.Init()
|
||||
}
|
||||
m.SavedCards = append(m.SavedCards, msg.Card)
|
||||
@@ -495,12 +500,20 @@ func (m Model) PaymentUpdate(msg tea.Msg) (Model, tea.Cmd) {
|
||||
if m.payment.cardCursor == len(m.SavedCards) {
|
||||
m.payment.view = 1
|
||||
m.payment.form = m.InitPaymentForm()
|
||||
m.footer = []footerCommand{
|
||||
{key: "tab", value: "next"},
|
||||
{key: "enter", value: "submit"},
|
||||
{key: "esc", value: "back"},
|
||||
}
|
||||
return m, m.payment.form.form.Init()
|
||||
}
|
||||
// Browser payment
|
||||
m.payment.view = 2
|
||||
m.payment.collectURL = nil
|
||||
m.payment.collectCardCount = len(m.SavedCards)
|
||||
m.footer = []footerCommand{
|
||||
{key: "esc", value: "back"},
|
||||
}
|
||||
return m, m.collectCardCmd()
|
||||
|
||||
case "d", "x":
|
||||
@@ -513,6 +526,11 @@ func (m Model) PaymentUpdate(msg tea.Msg) (Model, tea.Cmd) {
|
||||
if len(m.SavedCards) == 0 {
|
||||
m.payment.view = 1
|
||||
m.payment.form = m.InitPaymentForm()
|
||||
m.footer = []footerCommand{
|
||||
{key: "tab", value: "next"},
|
||||
{key: "enter", value: "submit"},
|
||||
{key: "esc", value: "back"},
|
||||
}
|
||||
return m, tea.Batch(m.payment.form.form.Init(), m.deleteCardCmd(card.ID))
|
||||
}
|
||||
return m, m.deleteCardCmd(card.ID)
|
||||
@@ -526,6 +544,12 @@ func (m Model) PaymentUpdate(msg tea.Msg) (Model, tea.Cmd) {
|
||||
if keyMsg, ok := msg.(tea.KeyMsg); ok && keyMsg.String() == "esc" {
|
||||
m.payment.view = 0
|
||||
m.payment.collectURL = nil
|
||||
m.footer = []footerCommand{
|
||||
{key: "j/k", value: "cards"},
|
||||
{key: "enter", value: "select"},
|
||||
{key: "d/x", value: "delete"},
|
||||
{key: "esc", value: "back"},
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
return m, nil
|
||||
@@ -539,6 +563,12 @@ func (m Model) PaymentUpdate(msg tea.Msg) (Model, tea.Cmd) {
|
||||
if len(m.SavedCards) > 0 {
|
||||
m.payment.view = 0
|
||||
m.payment.form = nil
|
||||
m.footer = []footerCommand{
|
||||
{key: "j/k", value: "cards"},
|
||||
{key: "enter", value: "select"},
|
||||
{key: "d/x", value: "delete"},
|
||||
{key: "esc", value: "back"},
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
m.payment.form = nil
|
||||
|
||||
@@ -362,6 +362,11 @@ func (m Model) ShippingUpdate(msg tea.Msg) (Model, tea.Cmd) {
|
||||
m.SavedAddresses = nil
|
||||
m.shipping.view = 1
|
||||
m.shipping.form = m.InitShippingForm()
|
||||
m.footer = []footerCommand{
|
||||
{key: "tab", value: "next"},
|
||||
{key: "enter", value: "submit"},
|
||||
{key: "esc", value: "back"},
|
||||
}
|
||||
return m, m.shipping.form.form.Init()
|
||||
}
|
||||
m.SavedAddresses = msg.Addresses
|
||||
@@ -412,6 +417,11 @@ func (m Model) ShippingUpdate(msg tea.Msg) (Model, tea.Cmd) {
|
||||
}
|
||||
m.shipping.view = 1
|
||||
m.shipping.form = m.InitShippingForm()
|
||||
m.footer = []footerCommand{
|
||||
{key: "tab", value: "next"},
|
||||
{key: "enter", value: "submit"},
|
||||
{key: "esc", value: "back"},
|
||||
}
|
||||
return m, m.shipping.form.form.Init()
|
||||
case "d", "x":
|
||||
if m.shipping.addressCursor < len(m.SavedAddresses) {
|
||||
@@ -423,6 +433,11 @@ func (m Model) ShippingUpdate(msg tea.Msg) (Model, tea.Cmd) {
|
||||
if len(m.SavedAddresses) == 0 {
|
||||
m.shipping.view = 1
|
||||
m.shipping.form = m.InitShippingForm()
|
||||
m.footer = []footerCommand{
|
||||
{key: "tab", value: "next"},
|
||||
{key: "enter", value: "submit"},
|
||||
{key: "esc", value: "back"},
|
||||
}
|
||||
return m, tea.Batch(m.shipping.form.form.Init(), m.deleteAddressCmd(addr.ID))
|
||||
}
|
||||
return m, m.deleteAddressCmd(addr.ID)
|
||||
@@ -439,6 +454,12 @@ func (m Model) ShippingUpdate(msg tea.Msg) (Model, tea.Cmd) {
|
||||
if len(m.SavedAddresses) > 0 {
|
||||
m.shipping.view = 0
|
||||
m.shipping.form = nil
|
||||
m.footer = []footerCommand{
|
||||
{key: "j/k", value: "addresses"},
|
||||
{key: "enter", value: "select"},
|
||||
{key: "d/x", value: "delete"},
|
||||
{key: "esc", value: "back"},
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
m.shipping.form = nil
|
||||
|
||||
Reference in New Issue
Block a user