Allow users to edit their name
This commit is contained in:
parent
867971b20c
commit
5788d5b509
|
@ -23,6 +23,10 @@
|
||||||
transition: background-color 150ms ease-in;
|
transition: background-color 150ms ease-in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
transition: background-color 150ms ease-in, color 150ms ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
#content {
|
#content {
|
||||||
min-height: 85svh;
|
min-height: 85svh;
|
||||||
}
|
}
|
||||||
|
@ -97,9 +101,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
|
padding: 0 0.2em;
|
||||||
color: var(--black);
|
color: var(--black);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.text-muted {
|
.text-muted {
|
||||||
color: var(--muted);
|
color: var(--muted);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"git.ekzyis.com/ekzyis/delphi.market/server/router/context"
|
"git.ekzyis.com/ekzyis/delphi.market/server/router/context"
|
||||||
"git.ekzyis.com/ekzyis/delphi.market/server/router/pages"
|
"git.ekzyis.com/ekzyis/delphi.market/server/router/pages"
|
||||||
"git.ekzyis.com/ekzyis/delphi.market/types"
|
"git.ekzyis.com/ekzyis/delphi.market/types"
|
||||||
|
@ -13,3 +16,33 @@ func HandleUser(sc context.Context) echo.HandlerFunc {
|
||||||
return pages.User(&u).Render(context.RenderContext(sc, c), c.Response().Writer)
|
return pages.User(&u).Render(context.RenderContext(sc, c), c.Response().Writer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func HandleUserEdit(sc context.Context) echo.HandlerFunc {
|
||||||
|
return func(c echo.Context) error {
|
||||||
|
var (
|
||||||
|
db = sc.Db
|
||||||
|
ctx = c.Request().Context()
|
||||||
|
u = c.Get("session").(types.User)
|
||||||
|
name = c.FormValue("name")
|
||||||
|
|
||||||
|
maxLength = 16
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
if name == "" {
|
||||||
|
return echo.NewHTTPError(http.StatusBadRequest, "name is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(name) > maxLength {
|
||||||
|
echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("name cannot be longer than %d characters", maxLength))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = db.QueryRowContext(ctx,
|
||||||
|
"UPDATE users SET name = $1 WHERE id = $2 RETURNING name",
|
||||||
|
name, u.Id).Scan(&u.Name); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return pages.User(&u).Render(context.RenderContext(sc, c), c.Response().Writer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ templ User(user *types.User) {
|
||||||
<div id="content" class="flex flex-col">
|
<div id="content" class="flex flex-col">
|
||||||
@components.Figlet("random", "user")
|
@components.Figlet("random", "user")
|
||||||
<div
|
<div
|
||||||
class="grid grid-cols-2 gap-4 my-3 mx-auto"
|
class="grid grid-cols-[1fr_3fr] gap-4 my-3 mx-auto"
|
||||||
hx-target="#content"
|
hx-target="#content"
|
||||||
hx-swap="outerHTML"
|
hx-swap="outerHTML"
|
||||||
hx-select="#content"
|
hx-select="#content"
|
||||||
|
@ -25,15 +25,52 @@ templ User(user *types.User) {
|
||||||
<div class="font-bold">id</div>
|
<div class="font-bold">id</div>
|
||||||
<div>{ strconv.Itoa(user.Id) }</div>
|
<div>{ strconv.Itoa(user.Id) }</div>
|
||||||
<div class="font-bold">name</div>
|
<div class="font-bold">name</div>
|
||||||
<div>{ user.Name }</div>
|
<div class="flex">
|
||||||
|
<span id="name">{ user.Name }</span>
|
||||||
|
<form
|
||||||
|
class="hidden flex mb-0"
|
||||||
|
hx-put="/user"
|
||||||
|
hx-push-url="false"
|
||||||
|
hx-target="#name"
|
||||||
|
hx-select="#name"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
name="name"
|
||||||
|
type="text"
|
||||||
|
value={ user.Name }
|
||||||
|
required
|
||||||
|
maxlength="16"
|
||||||
|
class="font-mono w-[160px]"
|
||||||
|
/>
|
||||||
|
<button class="ms-1 px-1" type="submit">save</button>
|
||||||
|
</form>
|
||||||
|
<button id="cancel" class="hidden flex text-muted hover:text-reset text-xs items-center ms-1">cancel</button>
|
||||||
|
<button id="edit" class="flex text-muted hover:text-reset text-xs items-center ms-1" hx-preserve>edit</button>
|
||||||
|
</div>
|
||||||
<div class="font-bold">joined</div>
|
<div class="font-bold">joined</div>
|
||||||
<div>{ user.CreatedAt.Format(time.DateOnly) }</div>
|
<div>{ user.CreatedAt.Format(time.DateOnly) }</div>
|
||||||
<div class="font-bold">sats</div>
|
<div class="font-bold">sats</div>
|
||||||
<!-- TODO: implement withdrawal of sats -->
|
<!-- TODO: implement withdrawal of sats -->
|
||||||
<div>{ strconv.Itoa(int(user.Msats) / 1000) }</div>
|
<div class="flex">
|
||||||
|
<span>{ strconv.Itoa(int(user.Msats) / 1000) }</span>
|
||||||
|
<button class="flex text-muted hover:text-reset text-xs items-center ms-3">withdraw</button>
|
||||||
|
</div>
|
||||||
<!-- TODO: add WebLN and NWC for send+recv -->
|
<!-- TODO: add WebLN and NWC for send+recv -->
|
||||||
<button hx-post="/logout" class="col-span-2">logout</button>
|
<button hx-post="/logout" class="col-span-2">logout</button>
|
||||||
</div>
|
</div>
|
||||||
|
<script>
|
||||||
|
function toggleForm () {
|
||||||
|
htmx.toggleClass("#name", "hidden")
|
||||||
|
htmx.toggleClass("#name+form", "hidden")
|
||||||
|
htmx.toggleClass("#cancel", "hidden")
|
||||||
|
htmx.toggleClass("#edit", "hidden")
|
||||||
|
$("#name+form>input").focus()
|
||||||
|
}
|
||||||
|
|
||||||
|
htmx.on("#edit", "click", toggleForm)
|
||||||
|
htmx.on("#cancel", "click", toggleForm)
|
||||||
|
htmx.on("form", "htmx:afterRequest", toggleForm)
|
||||||
|
</script>
|
||||||
</div>
|
</div>
|
||||||
@components.Footer()
|
@components.Footer()
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -28,6 +28,7 @@ func Init(e *echo.Echo, sc Context) {
|
||||||
e.GET("/session", handler.HandleSessionCheck(sc))
|
e.GET("/session", handler.HandleSessionCheck(sc))
|
||||||
|
|
||||||
e.GET("/user", handler.HandleUser(sc), middleware.SessionGuard(sc))
|
e.GET("/user", handler.HandleUser(sc), middleware.SessionGuard(sc))
|
||||||
|
e.PUT("/user", handler.HandleUserEdit(sc), middleware.SessionGuard(sc))
|
||||||
e.POST("/logout", handler.HandleLogout(sc), middleware.SessionGuard(sc))
|
e.POST("/logout", handler.HandleLogout(sc), middleware.SessionGuard(sc))
|
||||||
|
|
||||||
e.GET("/invoice/:hash", handler.HandleInvoice(sc), middleware.SessionGuard(sc))
|
e.GET("/invoice/:hash", handler.HandleInvoice(sc), middleware.SessionGuard(sc))
|
||||||
|
|
Loading…
Reference in New Issue