Search Apps Documentation Source Content File Folder Download Copy Actions Download

render.gno

2.95 Kb · 102 lines
  1package memba_nft_market_v2
  2
  3// Render — public read-only views.
  4//
  5// Routes:
  6//   ""       — home: active listings count + volume
  7//   "stats"  — platform fee, totals
  8//   "sales"  — recent sales (up to 20)
  9//   *        — 404
 10
 11import (
 12	"strings"
 13
 14	"gno.land/p/nt/ufmt/v0"
 15)
 16
 17func Render(path string) string {
 18	switch path {
 19	case "":
 20		return renderHome()
 21	case "stats":
 22		return renderStats()
 23	case "sales":
 24		return renderSales()
 25	default:
 26		return "# 404\nNot found: " + path
 27	}
 28}
 29
 30func renderHome() string {
 31	var sb strings.Builder
 32	sb.WriteString("# NFT Marketplace\n\n")
 33	sb.WriteString(ufmt.Sprintf("**Active Listings:** %d\n", listings.Size()))
 34	volGnot := ufmt.Sprintf("%d.%06d", totalVolume/1_000_000, totalVolume%1_000_000)
 35	sb.WriteString(ufmt.Sprintf("**Total Volume:** %s GNOT\n", volGnot))
 36
 37	if len(listingOrder) == 0 {
 38		sb.WriteString("\n*No active listings.*\n")
 39		return sb.String()
 40	}
 41
 42	const homePageCap = 50
 43
 44	sb.WriteString("\n| # | Collection | Token | Price | Seller |\n")
 45	sb.WriteString("|---|-----------|-------|-------|--------|\n")
 46	shown := 0
 47	for i, key := range listingOrder {
 48		if shown >= homePageCap {
 49			break
 50		}
 51		val, exists := listings.Get(key)
 52		if !exists {
 53			continue
 54		}
 55		l := val.(*Listing)
 56		priceGnot := ufmt.Sprintf("%d.%06d", l.Price/1_000_000, l.Price%1_000_000)
 57		sb.WriteString(ufmt.Sprintf("| %d | %s | %s | %s GNOT | %s |\n",
 58			i+1, truncPath(l.CollectionID), l.TokenID, priceGnot, truncAddr(l.Seller)))
 59		shown++
 60	}
 61	if len(listingOrder) > homePageCap {
 62		sb.WriteString(ufmt.Sprintf("\n*… showing first %d of %d listings.*\n", homePageCap, len(listingOrder)))
 63	}
 64	return sb.String()
 65}
 66
 67func renderStats() string {
 68	var sb strings.Builder
 69	sb.WriteString("# Marketplace Stats\n\n")
 70	sb.WriteString(ufmt.Sprintf("**Active Listings:** %d\n", listings.Size()))
 71	sb.WriteString(ufmt.Sprintf("**Total Sales:** %d\n", salesLog.Size()))
 72	volGnot := ufmt.Sprintf("%d.%06d", totalVolume/1_000_000, totalVolume%1_000_000)
 73	sb.WriteString(ufmt.Sprintf("**Total Volume:** %s GNOT\n", volGnot))
 74	sb.WriteString(ufmt.Sprintf("**Active Offers:** %d\n", offers.Size()))
 75	sb.WriteString("**Platform Fee:** 2.50%\n")
 76	sb.WriteString(ufmt.Sprintf("**Max Royalty:** %d%%\n", MaxRoyaltyBPS/100))
 77	return sb.String()
 78}
 79
 80func renderSales() string {
 81	var sb strings.Builder
 82	sb.WriteString("# Recent Sales\n\n")
 83	if salesLog.Size() == 0 {
 84		sb.WriteString("*No sales yet.*\n")
 85		return sb.String()
 86	}
 87
 88	sb.WriteString("| Sale | Collection | Token | Price | Seller | Buyer |\n")
 89	sb.WriteString("|------|-----------|-------|-------|--------|-------|\n")
 90
 91	count := 0
 92	salesLog.ReverseIterate("", "", func(key string, val interface{}) bool {
 93		s := val.(*Sale)
 94		priceGnot := ufmt.Sprintf("%d.%06d", s.Price/1_000_000, s.Price%1_000_000)
 95		sb.WriteString(ufmt.Sprintf("| %s | %s | %s | %s GNOT | %s | %s |\n",
 96			key, truncPath(s.CollectionID), s.TokenID, priceGnot,
 97			truncAddr(s.Seller), truncAddr(s.Buyer)))
 98		count++
 99		return count >= 20
100	})
101	return sb.String()
102}