tag claim flow: scanned code auto-fills Add Tag field (?code=), unclaimed tag page shows 'Add this tag to my account' when logged in, login honors next= so code survives the login step
This commit is contained in:
@@ -64,7 +64,11 @@ func (a *App) Register(w http.ResponseWriter, r *http.Request) {
|
|||||||
http.Error(w, "internal error", http.StatusInternalServerError)
|
http.Error(w, "internal error", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
http.Redirect(w, r, "/account", http.StatusSeeOther)
|
next := r.FormValue("next")
|
||||||
|
if next == "" || !strings.HasPrefix(next, "/") || strings.HasPrefix(next, "//") {
|
||||||
|
next = "/account"
|
||||||
|
}
|
||||||
|
http.Redirect(w, r, next, http.StatusSeeOther)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) LoginPage(w http.ResponseWriter, r *http.Request) {
|
func (a *App) LoginPage(w http.ResponseWriter, r *http.Request) {
|
||||||
@@ -93,7 +97,11 @@ func (a *App) Login(w http.ResponseWriter, r *http.Request) {
|
|||||||
http.Error(w, "internal error", http.StatusInternalServerError)
|
http.Error(w, "internal error", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
http.Redirect(w, r, "/account", http.StatusSeeOther)
|
next := r.FormValue("next")
|
||||||
|
if next == "" || !strings.HasPrefix(next, "/") || strings.HasPrefix(next, "//") {
|
||||||
|
next = "/account"
|
||||||
|
}
|
||||||
|
http.Redirect(w, r, next, http.StatusSeeOther)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) Logout(w http.ResponseWriter, r *http.Request) {
|
func (a *App) Logout(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import (
|
|||||||
type publicData struct {
|
type publicData struct {
|
||||||
UpdatedAt pgtype.Timestamptz
|
UpdatedAt pgtype.Timestamptz
|
||||||
Preview bool
|
Preview bool
|
||||||
|
Authed bool
|
||||||
ID int64
|
ID int64
|
||||||
TagCode string
|
TagCode string
|
||||||
Status string
|
Status string
|
||||||
@@ -48,8 +49,10 @@ func (a *App) PublicTag(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_, authed := auth.GetUserID(r)
|
||||||
pd := publicData{
|
pd := publicData{
|
||||||
Preview: r.URL.Query().Get("preview") == "1",
|
Preview: r.URL.Query().Get("preview") == "1",
|
||||||
|
Authed: authed,
|
||||||
UpdatedAt: tag.UpdatedAt,
|
UpdatedAt: tag.UpdatedAt,
|
||||||
ID: tag.ID,
|
ID: tag.ID,
|
||||||
TagCode: tag.TagCode,
|
TagCode: tag.TagCode,
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ const maxTagsPerAccount = 20
|
|||||||
type accountData struct {
|
type accountData struct {
|
||||||
Tags []db.Tag
|
Tags []db.Tag
|
||||||
AddError string
|
AddError string
|
||||||
|
AddTagCode string
|
||||||
}
|
}
|
||||||
|
|
||||||
func ownerID(uid int64) pgtype.Int8 {
|
func ownerID(uid int64) pgtype.Int8 {
|
||||||
@@ -33,7 +34,7 @@ func (a *App) Account(w http.ResponseWriter, r *http.Request) {
|
|||||||
http.Error(w, "internal error", http.StatusInternalServerError)
|
http.Error(w, "internal error", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
a.render(w, r, "account", "My Tags", accountData{Tags: tags}, "")
|
a.render(w, r, "account", "My Tags", accountData{Tags: tags, AddTagCode: r.URL.Query().Get("code")}, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddTag binds a tag code to the current account (HTMX: returns account-panel).
|
// AddTag binds a tag code to the current account (HTMX: returns account-panel).
|
||||||
@@ -44,6 +45,7 @@ func (a *App) AddTag(w http.ResponseWriter, r *http.Request) {
|
|||||||
oid := ownerID(uid)
|
oid := ownerID(uid)
|
||||||
data := accountData{}
|
data := accountData{}
|
||||||
|
|
||||||
|
data.AddTagCode = code
|
||||||
if code == "" {
|
if code == "" {
|
||||||
data.AddError = "Enter a tag code."
|
data.AddError = "Enter a tag code."
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
<div class="mt-4 rounded-xl border border-stone-200 bg-white p-4 shadow-sm">
|
<div class="mt-4 rounded-xl border border-stone-200 bg-white p-4 shadow-sm">
|
||||||
<form hx-post="/account/tags" hx-target="#account-panel" hx-swap="outerHTML" class="flex gap-2">
|
<form hx-post="/account/tags" hx-target="#account-panel" hx-swap="outerHTML" class="flex gap-2">
|
||||||
<input name="tag_code" type="text" placeholder="Enter tag code (e.g. TEST000001)" class="flex-1 rounded border border-stone-300 px-3 py-2 text-sm" required>
|
<input name="tag_code" type="text" value="{{.AddTagCode}}" placeholder="Enter tag code (e.g. TEST000001)" class="flex-1 rounded border border-stone-300 px-3 py-2 text-sm" required autofocus>
|
||||||
<button type="submit" class="rounded bg-stone-900 px-4 py-2 text-sm font-semibold text-white hover:bg-stone-700">Add tag</button>
|
<button type="submit" class="rounded bg-stone-900 px-4 py-2 text-sm font-semibold text-white hover:bg-stone-700">Add tag</button>
|
||||||
<span class="htmx-indicator self-center text-xs text-stone-400">Adding…</span>
|
<span class="htmx-indicator self-center text-xs text-stone-400">Adding…</span>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -6,8 +6,12 @@
|
|||||||
<h1 class="mt-4 text-2xl font-bold">This tag isn't set up yet</h1>
|
<h1 class="mt-4 text-2xl font-bold">This tag isn't set up yet</h1>
|
||||||
<p class="mt-2 text-stone-600">This Where Woof tag hasn't been claimed. If this is your tag, log in and add it to your account to set up the return details.</p>
|
<p class="mt-2 text-stone-600">This Where Woof tag hasn't been claimed. If this is your tag, log in and add it to your account to set up the return details.</p>
|
||||||
<div class="mt-6 flex justify-center gap-3">
|
<div class="mt-6 flex justify-center gap-3">
|
||||||
<a href="/login" class="rounded bg-stone-900 px-4 py-2 text-sm font-semibold text-white hover:bg-stone-700">Log in</a>
|
{{if .Data.Authed}}
|
||||||
|
<a href="/account?code={{.Data.TagCode}}" class="rounded bg-stone-900 px-4 py-2 text-sm font-semibold text-white hover:bg-stone-700">➕ Add this tag to my account</a>
|
||||||
|
{{else}}
|
||||||
|
<a href="/login?next=/account?code={{.Data.TagCode}}" class="rounded bg-stone-900 px-4 py-2 text-sm font-semibold text-white hover:bg-stone-700">Log in</a>
|
||||||
<a href="/register" class="rounded bg-amber-500 px-4 py-2 text-sm font-semibold text-stone-900 hover:bg-amber-400">Create account</a>
|
<a href="/register" class="rounded bg-amber-500 px-4 py-2 text-sm font-semibold text-stone-900 hover:bg-amber-400">Create account</a>
|
||||||
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{else if eq .Data.Status "suspended"}}
|
{{else if eq .Data.Status "suspended"}}
|
||||||
|
|||||||
Reference in New Issue
Block a user