Compare commits
1 Commits
docs/packa
...
feat/roast
| Author | SHA1 | Date | |
|---|---|---|---|
| 1c891cebe6 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
docs/sca-psd2-compliance.md
|
docs/sca-psd2-compliance.md
|
||||||
accept-a-payment/
|
accept-a-payment/
|
||||||
codemap/
|
|
||||||
|
|
||||||
|
|
||||||
FULFILLMENT.md
|
FULFILLMENT.md
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
// Command api is the HTTP backend: it boots the router, bolts on all the
|
|
||||||
// middleware, and answers the requests the TUI throws at it.
|
|
||||||
package main
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
// Package handlers is where the real work happens, one function per endpoint:
|
|
||||||
// carts, orders, products, addresses, cards, webhooks, and the rest.
|
|
||||||
package handlers
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
// Package middleware holds the stuff that runs on every request before a
|
|
||||||
// handler ever sees it: auth, CORS, logging, rate limiting, metrics, and a
|
|
||||||
// recovery net for panics.
|
|
||||||
package middleware
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
// Package routes is the switchboard: it maps every URL to the handler that
|
|
||||||
// knows what to do with it.
|
|
||||||
package routes
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
// Command reconcile-cards hunts down saved cards that Stripe no longer knows
|
|
||||||
// about and detaches them. Run it with -dry-run first if you're nervous.
|
|
||||||
package main
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
// Package api is the client side of the house: it talks to our HTTP backend
|
|
||||||
// so other Go code doesn't have to hand-roll requests.
|
|
||||||
package api
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
// Package auth sorts out who you are: logging in with an SSH key and minting
|
|
||||||
// the JWT you carry around afterwards.
|
|
||||||
package auth
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
// Package bring talks to Bring, the Norwegian postal service, for booking
|
|
||||||
// shipments and printing labels.
|
|
||||||
package bring
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
// Package config reads everything out of the environment so secrets and
|
|
||||||
// settings stay out of the source code.
|
|
||||||
package config
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
// Package database opens the SQLite connection, runs the migrations, and
|
|
||||||
// drops in some seed data so the shop isn't empty on a fresh boot.
|
|
||||||
package database
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
// Package models is the shared vocabulary of the app: coffee, carts, orders,
|
|
||||||
// addresses, cards, users, and the other nouns everything passes around.
|
|
||||||
package models
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
// Package observability sets up tracing and structured logs so that when
|
|
||||||
// something breaks at 3am you stand a chance of figuring out why.
|
|
||||||
package observability
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
// Package shipping holds the plain shipping types that the rest of the app
|
|
||||||
// passes back and forth.
|
|
||||||
package shipping
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
// Package shippo talks to the Shippo API for shipping rates and labels.
|
|
||||||
package shippo
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
// Package stripeclient wires up the Stripe SDK once at startup (with tracing
|
|
||||||
// baked in) so everyone else can just make calls.
|
|
||||||
package stripeclient
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
// Package tui is the terminal UI you see over SSH: the shop, the cart, your
|
|
||||||
// account, and the checkout flow, all drawn with Bubbletea.
|
|
||||||
package tui
|
|
||||||
@@ -276,7 +276,9 @@ func (m Model) updatePaymentViewport() Model {
|
|||||||
breadH := lipgloss.Height(m.BuildBreadcrumbs())
|
breadH := lipgloss.Height(m.BuildBreadcrumbs())
|
||||||
footerH := lipgloss.Height(m.BuildFooter())
|
footerH := lipgloss.Height(m.BuildFooter())
|
||||||
availH := m.heightContainer - headerH - footerH - breadH
|
availH := m.heightContainer - headerH - footerH - breadH
|
||||||
availH = max(availH, 1)
|
if availH < 1 {
|
||||||
|
availH = 1
|
||||||
|
}
|
||||||
if !m.payment.viewportReady {
|
if !m.payment.viewportReady {
|
||||||
m.payment.viewport = viewport.New(viewport.WithWidth(m.widthContent), viewport.WithHeight(availH))
|
m.payment.viewport = viewport.New(viewport.WithWidth(m.widthContent), viewport.WithHeight(availH))
|
||||||
m.payment.viewport.KeyMap = viewport.KeyMap{}
|
m.payment.viewport.KeyMap = viewport.KeyMap{}
|
||||||
@@ -301,7 +303,7 @@ func (m Model) PaymentPageView() string {
|
|||||||
m.widthContainer,
|
m.widthContainer,
|
||||||
m.payment.viewport.Height(),
|
m.payment.viewport.Height(),
|
||||||
lipgloss.Center, lipgloss.Center,
|
lipgloss.Center, lipgloss.Center,
|
||||||
m.renderPaymentHTTPSView(),
|
m.renderPaymentHttpsView(),
|
||||||
)
|
)
|
||||||
} else if m.payment.view == 0 && m.payment.form == nil {
|
} else if m.payment.view == 0 && m.payment.form == nil {
|
||||||
content = m.RenderCardList()
|
content = m.RenderCardList()
|
||||||
@@ -372,7 +374,7 @@ func (m Model) RenderCardList() string {
|
|||||||
return lipgloss.JoinVertical(lipgloss.Left, parts...)
|
return lipgloss.JoinVertical(lipgloss.Left, parts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m Model) renderPaymentHTTPSView() string {
|
func (m Model) renderPaymentHttpsView() string {
|
||||||
baseStyle := m.theme.TextLabel()
|
baseStyle := m.theme.TextLabel()
|
||||||
accentStyle := m.theme.TextHighlight()
|
accentStyle := m.theme.TextHighlight()
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
// Package qrfefe turns text into a QR code drawn with terminal block
|
|
||||||
// characters, handy for showing links you can scan right off the screen.
|
|
||||||
package qrfefe
|
|
||||||
@@ -24,7 +24,9 @@ const (
|
|||||||
// menu(menuW+4) + gap(1) + detail(detailW+4) = contentW = wideW + 4.
|
// menu(menuW+4) + gap(1) + detail(detailW+4) = contentW = wideW + 4.
|
||||||
func (m Model) shopLayout() (contentW, menuW, detailW, wideW int) {
|
func (m Model) shopLayout() (contentW, menuW, detailW, wideW int) {
|
||||||
contentW = m.widthContent
|
contentW = m.widthContent
|
||||||
contentW = min(contentW, 74)
|
if contentW > 74 {
|
||||||
|
contentW = 74
|
||||||
|
}
|
||||||
wideW = contentW - 4
|
wideW = contentW - 4
|
||||||
if m.size < large {
|
if m.size < large {
|
||||||
// Stacked layout: both panels span the full content width.
|
// Stacked layout: both panels span the full content width.
|
||||||
@@ -64,7 +66,6 @@ func clampLines(s string, n int) string {
|
|||||||
|
|
||||||
// roastMeter renders the strength dots, e.g. ● ● ● ○ ○
|
// roastMeter renders the strength dots, e.g. ● ● ● ○ ○
|
||||||
func roastMeter(n int) string {
|
func roastMeter(n int) string {
|
||||||
n = max(0, min(n, 5))
|
|
||||||
on := lipgloss.NewStyle().Foreground(cGold).Render(strings.Repeat("● ", n))
|
on := lipgloss.NewStyle().Foreground(cGold).Render(strings.Repeat("● ", n))
|
||||||
off := pDim.Render(strings.Repeat("○ ", 5-n))
|
off := pDim.Render(strings.Repeat("○ ", 5-n))
|
||||||
return strings.TrimRight(on+off, " ")
|
return strings.TrimRight(on+off, " ")
|
||||||
@@ -217,8 +218,12 @@ func (m Model) shopMoveSelected(previous bool) Model {
|
|||||||
} else {
|
} else {
|
||||||
next++
|
next++
|
||||||
}
|
}
|
||||||
next = max(next, 0)
|
if next < 0 {
|
||||||
next = min(next, len(m.Coffees)-1)
|
next = 0
|
||||||
|
}
|
||||||
|
if next >= len(m.Coffees) {
|
||||||
|
next = len(m.Coffees) - 1
|
||||||
|
}
|
||||||
m.shop.selected = next
|
m.shop.selected = next
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
// Package theme keeps the colors and styles in one spot so the whole UI
|
|
||||||
// looks like it was built by the same person.
|
|
||||||
package theme
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
// Package utils is the catch-all drawer for tiny HTTP helpers that didn't
|
|
||||||
// earn a package of their own.
|
|
||||||
package utils
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
// Package validate gives user input a once-over before the rest of the app
|
|
||||||
// trusts it.
|
|
||||||
package validate
|
|
||||||
Reference in New Issue
Block a user