Show user orders
This commit is contained in:
parent
fb7fbae699
commit
c96eeb7668
21
db/market.go
21
db/market.go
|
@ -111,3 +111,24 @@ func (db *DB) CreateOrder(tx *sql.Tx, ctx context.Context, order *Order) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (db *DB) FetchUserOrders(pubkey string, orders *[]Order) error {
|
||||||
|
query := "" +
|
||||||
|
"SELECT o.id, share_id, o.pubkey, o.side, o.quantity, o.price, o.invoice_id, o.created_at, s.description, s.market_id, i.confirmed_at " +
|
||||||
|
"FROM orders o " +
|
||||||
|
"JOIN invoices i ON o.invoice_id = i.id " +
|
||||||
|
"JOIN shares s ON o.share_id = s.id " +
|
||||||
|
"WHERE o.pubkey = $1 AND i.confirmed_at IS NOT NULL " +
|
||||||
|
"ORDER BY o.created_at DESC"
|
||||||
|
rows, err := db.Query(query, pubkey)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
for rows.Next() {
|
||||||
|
var order Order
|
||||||
|
rows.Scan(&order.Id, &order.ShareId, &order.Pubkey, &order.Side, &order.Quantity, &order.Price, &order.InvoiceId, &order.CreatedAt, &order.ShareDescription, &order.Share.MarketId, &order.Invoice.ConfirmedAt)
|
||||||
|
*orders = append(*orders, order)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -50,9 +50,10 @@ type (
|
||||||
Status string
|
Status string
|
||||||
}
|
}
|
||||||
Order struct {
|
Order struct {
|
||||||
Id UUID
|
Id UUID
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
ShareId string `json:"sid"`
|
ShareId string `json:"sid"`
|
||||||
|
ShareDescription string
|
||||||
Share
|
Share
|
||||||
Pubkey string
|
Pubkey string
|
||||||
Side string `json:"side"`
|
Side string `json:"side"`
|
||||||
|
|
|
@ -196,3 +196,18 @@ func HandleOrder(sc context.ServerContext) echo.HandlerFunc {
|
||||||
return c.JSON(http.StatusPaymentRequired, data)
|
return c.JSON(http.StatusPaymentRequired, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func HandleOrders(sc context.ServerContext) echo.HandlerFunc {
|
||||||
|
return func(c echo.Context) error {
|
||||||
|
var (
|
||||||
|
u db.User
|
||||||
|
orders []db.Order
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
u = c.Get("session").(db.User)
|
||||||
|
if err = sc.Db.FetchUserOrders(u.Pubkey, &orders); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return c.JSON(http.StatusOK, orders)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -50,6 +50,9 @@ func addBackendRoutes(e *echo.Echo, sc ServerContext) {
|
||||||
handler.HandleOrder,
|
handler.HandleOrder,
|
||||||
middleware.SessionGuard,
|
middleware.SessionGuard,
|
||||||
middleware.LNDGuard)
|
middleware.LNDGuard)
|
||||||
|
GET(e, sc, "/api/orders",
|
||||||
|
handler.HandleOrders,
|
||||||
|
middleware.SessionGuard)
|
||||||
GET(e, sc, "/api/login", handler.HandleLogin)
|
GET(e, sc, "/api/login", handler.HandleLogin)
|
||||||
GET(e, sc, "/api/login/callback", handler.HandleLoginCallback)
|
GET(e, sc, "/api/login/callback", handler.HandleLoginCallback)
|
||||||
POST(e, sc, "/api/logout", handler.HandleLogout)
|
POST(e, sc, "/api/logout", handler.HandleLogout)
|
||||||
|
|
|
@ -45,10 +45,14 @@ table {
|
||||||
}
|
}
|
||||||
|
|
||||||
th {
|
th {
|
||||||
padding: 0 1rem;
|
padding: 0 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 600px) {
|
@media only screen and (max-width: 600px) {
|
||||||
|
th {
|
||||||
|
padding: 0 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
.hidden-sm {
|
.hidden-sm {
|
||||||
display: none
|
display: none
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
<template>
|
||||||
|
<div class="text w-auto">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<th>market</th>
|
||||||
|
<th>description</th>
|
||||||
|
<th class="hidden-sm">created at</th>
|
||||||
|
<th>status</th>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="o in orders " :key="o.id">
|
||||||
|
<td><router-link :to="/market/ + o.MarketId">{{ o.MarketId }}</router-link></td>
|
||||||
|
<td>{{ o.side }} {{ o.quantity }} {{ o.ShareDescription }} @ {{ o.price }} sats</td>
|
||||||
|
<td class="hidden-sm">{{ ago(new Date(o.CreatedAt)) }}</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import ago from 's-ago'
|
||||||
|
|
||||||
|
const orders = ref(null)
|
||||||
|
|
||||||
|
const url = '/api/orders'
|
||||||
|
await fetch(url)
|
||||||
|
.then(r => r.json())
|
||||||
|
.then(body => {
|
||||||
|
console.log(body)
|
||||||
|
orders.value = body
|
||||||
|
})
|
||||||
|
.catch(console.error)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
table {
|
||||||
|
width: fit-content;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
padding: 0 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 600px) {
|
||||||
|
th {
|
||||||
|
padding: 0 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden-sm {
|
||||||
|
display: none
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -12,6 +12,7 @@ import MarketView from '@/views/MarketView'
|
||||||
import InvoiceView from '@/views/InvoiceView'
|
import InvoiceView from '@/views/InvoiceView'
|
||||||
import UserSettings from '@/components/UserSettings'
|
import UserSettings from '@/components/UserSettings'
|
||||||
import UserInvoices from '@/components/UserInvoices'
|
import UserInvoices from '@/components/UserInvoices'
|
||||||
|
import UserOrders from '@/components/UserOrders'
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
|
@ -25,7 +26,8 @@ const routes = [
|
||||||
component: UserView,
|
component: UserView,
|
||||||
children: [
|
children: [
|
||||||
{ path: 'settings', name: 'user', component: UserSettings },
|
{ path: 'settings', name: 'user', component: UserSettings },
|
||||||
{ path: 'invoices', name: 'invoices', component: UserInvoices }
|
{ path: 'invoices', name: 'invoices', component: UserInvoices },
|
||||||
|
{ path: 'orders', name: 'orders', component: UserOrders }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
<nav>
|
<nav>
|
||||||
<StyledLink to="/user/settings">settings</StyledLink>
|
<StyledLink to="/user/settings">settings</StyledLink>
|
||||||
<StyledLink to="/user/invoices">invoices</StyledLink>
|
<StyledLink to="/user/invoices">invoices</StyledLink>
|
||||||
|
<StyledLink to="/user/orders">orders</StyledLink>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
<Suspense>
|
<Suspense>
|
||||||
|
|
Loading…
Reference in New Issue