Search Apps Documentation Source Content File Folder Download Copy Actions Download

render.gno

3.20 Kb · 147 lines
  1package user
  2
  3import (
  4	"net/url"
  5
  6	"gno.land/p/jeronimoalbi/pager"
  7	"gno.land/p/nt/ufmt"
  8	"gno.land/r/akkadia/admin"
  9)
 10
 11// Render handles RESTful routing and returns Markdown responses
 12func Render(iUrl string) string {
 13	u, err := url.Parse(iUrl)
 14	if err != nil {
 15		return "404\n"
 16	}
 17
 18	query := u.Query()
 19
 20	switch u.Path {
 21	case "":
 22		return renderHome()
 23	case "users":
 24		return renderUsersList(iUrl)
 25	case "user":
 26		addr := address(query.Get("address"))
 27		return renderUser(iUrl, addr)
 28	default:
 29		return renderError("Not found")
 30	}
 31}
 32
 33// renderHome renders the home page
 34func renderHome() string {
 35	output := `# AKKADIA User
 36
 37## Introduction
 38
 39User realm manages user profiles for AKKADIA.
 40
 41- **properties**: Admin-managed user attributes
 42- **metadatas**: User-managed personal data
 43
 44## Stats
 45
 46`
 47	output += ufmt.Sprintf("* **Total Users**: %d\n", GetTotalUserSize())
 48	output += `
 49## Quick Links
 50
 51* [Browse Users](/r/akkadia/user:users)
 52
 53## User Lookup
 54
 55<gno-form path="user">
 56  <gno-input name="address" placeholder="Enter the address" />
 57</gno-form>
 58`
 59	return output
 60}
 61
 62// renderUsersList renders a list of all users with pagination
 63func renderUsersList(iUrl string) string {
 64	output := "# Users\n\n"
 65	output += "[← Home](/r/akkadia/user:)\n\n"
 66
 67	if properties.Size() == 0 {
 68		output += "*No users registered yet.*\n"
 69		return output
 70	}
 71
 72	pages, err := pager.New(iUrl, properties.Size(), pager.WithPageSize(20))
 73	if err != nil {
 74		return renderError("Invalid page")
 75	}
 76
 77	// Get current page number for back links
 78	currentPage := (pages.Offset() / pages.PageSize()) + 1
 79
 80	properties.IterateByOffset(pages.Offset(), pages.PageSize(), func(key string, _ interface{}) bool {
 81		output += ufmt.Sprintf("* [%s](/r/akkadia/user:user?address=%s&page=%d)\n", key, key, currentPage)
 82		return false
 83	})
 84
 85	if pages.HasPages() {
 86		output += "\n" + pager.Picker(pages)
 87	}
 88
 89	return output
 90}
 91
 92// renderUser renders a single user detail
 93func renderUser(iUrl string, addr address) string {
 94	if !addr.IsValid() {
 95		return renderError("Invalid address")
 96	}
 97
 98	u, _ := url.Parse(iUrl)
 99	page := u.Query().Get("page")
100
101	addrStr := addr.String()
102	props, propsFound := properties.Get(addrStr)
103	metas, metasFound := metadatas.Get(addrStr)
104
105	if !propsFound && !metasFound {
106		return renderError("User not found")
107	}
108
109	output := "# User Detail\n\n"
110	if page != "" {
111		output += ufmt.Sprintf("[← Back to List](/r/akkadia/user:users?page=%s)\n\n", page)
112	} else {
113		output += "[← Home](/r/akkadia/user:)\n\n"
114	}
115	output += ufmt.Sprintf("* **Address**: %s [[View on Explorer](%s/m/explorer/player?address=%s)]\n\n", addrStr, admin.GetExplorerURL(), addrStr)
116
117	if propsFound {
118		output += "## Properties\n\n"
119		for k, v := range props.(map[string]string) {
120			if k == "address" {
121				continue
122			}
123			output += ufmt.Sprintf("* **%s**: %s\n", k, v)
124		}
125		output += "\n"
126	}
127
128	if metasFound {
129		output += "## Metadata\n\n"
130		for k, v := range metas.(map[string]string) {
131			if k == "address" {
132				continue
133			}
134			output += ufmt.Sprintf("* **%s**: %s\n", k, v)
135		}
136	}
137
138	return output
139}
140
141// renderError renders an error page
142func renderError(message string) string {
143	output := "# Error\n\n"
144	output += ufmt.Sprintf("> %s\n\n", message)
145	output += "[← Back to Home](/r/akkadia/user:)\n"
146	return output
147}