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}