move shops to new page; live vs mock navbar

This commit is contained in:
2026-02-06 16:37:55 -07:00
parent 548f72d9a4
commit e3b2dd3377
11 changed files with 265 additions and 345 deletions
+1 -1
View File
@@ -196,7 +196,7 @@ func (s *accountSubrouter) setOrderOfPlatformOnAccountPage(c *gin.Context) (resp
) )
err := param.Path("platform", param.Platform(&platform)). err := param.Path("platform", param.Platform(&platform)).
Form("orderIndex", param.Int(&orderIndex)). Form("order-index", param.Int(&orderIndex)).
Unmarshal(c) Unmarshal(c)
if err != nil { if err != nil {
return nil, err return nil, err
+3
View File
@@ -84,6 +84,9 @@ func Routes(
} }
return strings.Join(us, " ") return strings.Join(us, " ")
}, },
"hasPrefix": func(s, prefix string) bool {
return strings.HasPrefix(s, prefix)
},
// arithmetic // arithmetic
"addInt": func(a, b int) int { "addInt": func(a, b int) int {
@@ -1,182 +0,0 @@
{{- $acctID := .PathParams.acctID }}
{{- $platform := .PathParams.platform }}
{{- $parsedPlatform := parsePlatform $platform }}
<details
name={{$platform}}
class="
flex flex-col items-center
open:pb-[1em]
open:border-b-[1px]
open:border-b-background
open:mb-[1em]
group/create-mock-shop
details-content:opacity-[0]
open:details-content:opacity-[1]
details-content:transform-[translate(0px,-2em)]
open:details-content:transform-[translate(0px,0px)]
details-content:border-transparent
open:details-content:border-dotted
open:details-content:border-x-[0px]
open:details-content:border-x-transparent
open:details-content:border-b-[0px]
open:details-content:border-b-transparent
open:details-content:border-t-background
open:details-content:border-t-[0.225rem]
details-content:outline-transparent
details-content:transition-[opacity_transform]
"
>
<summary
class="
flex-grow
p-[0.5em]
grid
grid-cols-[2fr_8fr_2fr]
gap-[1em]
list-none
after:content-['+']
group-open/create-mock-shop:after:content-['-']
after:font-bold
after:text-[2em]
after:leading-[1em]
cursor-pointer
"
>
<h4 class="inline-block col-2 content-center">
Mock Shops
</h4>
</summary>
<ul class="flex flex-col items-center my-[0.5em]">
{{- $shops := .Accounts.ListMockShopsForPlatform $acctID $parsedPlatform }}
{{- range $shop := $shops }}
<li>
<a
href={{ printf "/ui/accounts/%d/platforms/%s/shops/mocks/%s" $acctID $platform $shop.ShopID }}
hx-boost="false"
class="
border-foreground
border-solid
border-thin
bg-card
font-semibold
rounded-md
p-[0.5em]
m-[0.25em]
block
"
>
{{ $shop.Name }}
</a>
</li>
{{- end }}
</ul>
<form
class="px-[2em] py-[0.5em]"
hx-post={{printf "/api/accounts/%d/platforms/%s/shops/mocks" $acctID $platform}}
>
<div
class="
grid grid-cols-[max-content_max-content]
gap-[0.25em]
p-[0.5em]
"
>
<label>
Name:
</label>
<input
type="text"
name="name"
class="
ml-[1em]
bg-card
border-input border-[1px] rounded
"
required
minlength="5"
/>
<!--label>
TODO:
</label>
<input
type="text"
name="name"
class="
ml-[1em]
bg-card
border-input border-[1px] rounded
"
/-->
</div>
{{ component "button"
"Text" "Create"
"Class" ""
}}
</form>
</details>
<details
name={{$platform}}
class="
flex flex-col items-center
group/link-shops
details-content:opacity-[0]
open:details-content:opacity-[1]
details-content:transform-[translate(0px,-2em)]
open:details-content:transform-[translate(0px,0px)]
details-content:border-transparent
open:details-content:border-dotted
open:details-content:border-x-[0px]
open:details-content:border-x-transparent
open:details-content:border-b-[0px]
open:details-content:border-b-transparent
open:details-content:border-t-background
open:details-content:border-t-[0.225rem]
details-content:outline-transparent
details-content:transition-[opacity_transform]
"
>
<summary
class="
flex-grow
p-[0.5em]
grid
grid-cols-[2fr_8fr_2fr]
gap-[1em]
list-none
after:content-['+']
group-open/link-shops:after:content-['-']
after:font-bold
after:text-[2em]
after:leading-[1em]
cursor-pointer
"
>
<h4 class="inline-block col-2 content-center">
Link Shops
</h4>
</summary>
{{ component ( printf "/accounts/%d/platform-links/%s" $acctID $platform ) }}
</details>
@@ -0,0 +1,85 @@
{{/* [Mock: bool] */}}
{{- $acctID := .PathParams.acctID }}
{{- $platform := .PathParams.platform }}
{{- $parsedPlatform := parsePlatform $platform }}
{{- if .Mock }}
{{- $idPrefix := "mock-" }}
<div
name={{$platform}}
class="flex flex-col items-center"
>
{{- $shops := .Accounts.ListMockShopsForPlatform $acctID $parsedPlatform }}
{{- if $shops }}
<ul class="flex flex-col items-center my-[0.5em]">
{{- range $shop := $shops }}
<li>
<a
href={{ printf "/ui/accounts/%d/platforms/%s/shops/mocks/%s" $acctID $platform $shop.ShopID }}
hx-boost="false"
class="
border-foreground
border-solid
border-thin
bg-card
font-semibold
rounded-md
p-[0.5em]
m-[0.25em]
block
"
>
{{ $shop.Name }}
</a>
</li>
{{- end }}
</ul>
{{- end }}
<form
class="px-[2em] py-[0.5em]"
hx-post={{printf "/api/accounts/%d/platforms/%s/shops/mocks" $acctID $platform}}
>
<div
class="
grid grid-cols-[max-content_max-content]
gap-[0.25em]
p-[0.5em]
"
>
<label>
Name:
</label>
<input
type="text"
name="name"
class="
ml-[1em]
bg-card
border-input border-[1px] rounded
"
required
minlength="5"
/>
</div>
{{ component "button"
"Text" "Create"
"Class" ""
}}
</form>
</div>
{{- else -}}
<div
name={{$platform}}
class="flex flex-col items-center"
>
{{ component ( printf "/accounts/%d/platform-links/%s" $acctID $platform ) }}
</div>
{{- end }}
@@ -1,3 +1,5 @@
{{/* [Mock: bool] */}}
{{- $acctID := .Identity.Account.AccountID }} {{- $acctID := .Identity.Account.AccountID }}
{{- $platform := parsePlatform .PathParams.platform -}} {{- $platform := parsePlatform .PathParams.platform -}}
{{- $orderIndex := .OrderIndex }} {{- $orderIndex := .OrderIndex }}
@@ -6,10 +8,13 @@
{{- end }} {{- end }}
{{- $idPrefix := "" }}
{{- if .Mock }}
{{- $idPrefix = "mock-" }}
{{- end }}
{{- $platformSegment := lowerSnakeCase (printf "%s" $platform) }} {{- $platformSegment := lowerSnakeCase (printf "%s" $platform) }}
{{- $updatePath := printf "/accounts/%d/platforms/%s/order-index" $acctID $platformSegment }}
<li <li
id="{{$platformSegment}}" id="{{$idPrefix}}{{$platformSegment}}"
class="my-[1rem] rounded-lg bg-accent" class="my-[1rem] rounded-lg bg-accent"
{{/* the dragged <li> will be NOT be updated by the response (204 response), but instead the following sse events */}} {{/* the dragged <li> will be NOT be updated by the response (204 response), but instead the following sse events */}}
@@ -47,7 +52,7 @@
" "
> >
<details <details
id="{{$platformSegment}}-details" id="{{$idPrefix}}{{$platformSegment}}-details"
class=" class="
group group
@@ -94,11 +99,11 @@
</summary> </summary>
<div <div
id="{{$platform}}-tab" id="{{$idPrefix}}{{$platform}}-tab"
class="p-[1em] text-center" class="p-[1em] text-center"
> >
{{- $pathSegment := lowerSnakeCase (printf "%s" $platform) }} {{- $pathSegment := lowerSnakeCase (printf "%s" $platform) }}
{{- component (printf "/accounts/%d/platforms/%s/link-section" $acctID $pathSegment) }} {{- component (printf "/accounts/%d/platforms/%s/shops/link-section" $acctID $pathSegment) "Mock" .Mock }}
</div> </div>
</details> </details>
</li> </li>
+96 -32
View File
@@ -1,5 +1,6 @@
{{- $loggedIn := and (and .Identity .Identity.AccessToken) true -}} {{- $loggedIn := and (and .Identity .Identity.AccessToken) true -}}
{{- $hasAccount := and (and .Identity .Identity.Account) true -}} {{- $hasAccount := and (and .Identity .Identity.Account) true -}}
{{- $acctID := 0 }}
<!DOCTYPE html> <!DOCTYPE html>
@@ -47,8 +48,9 @@
{{- end }} {{- end }}
> >
<header> <header>
<nav {{- $path := or .Request.URL.Path "/" }}
class="
{{ define "navbar-class" }}class="
w-full w-full
text-xl text-xl
overflow-x-hidden overflow-x-hidden
@@ -56,13 +58,9 @@
flex flex
justify-center justify-center
" "{{ end }}
>
{{- $path := or .Request.URL.Path "/" }}
<ul {{ define "navbar-ul-class" }}class="
hx-swap="morph:innerHTML"
class="
max-w-full max-w-full
overflow-x-auto overflow-x-auto
overflow-y-hidden overflow-y-hidden
@@ -70,42 +68,108 @@
flex flex
basis-[fit-content] basis-[fit-content]
" "}}
style=" {{ end }}
"
{{ define "navbar-link" }}
{{/* Href, NoHXBoost, Selected, Content */}}
<li class="pt-[1em] pb-[1em]">
<a
href={{.Href}}
{{if .NoHXBoost}}hx-boost="false"{{end}}
class="p-[1em] font-display {{if .Selected}}selected{{ end }}"
>
{{.Content}}
</a>
</li>
{{ end }}
<nav {{ template "navbar-class" . }}>
<ul
hx-swap="morph:innerHTML"
{{ template "navbar-ul-class" }}
> >
{{- if not $loggedIn }} {{- if not $loggedIn }}
<li class="pt-[1em] pb-[1em]"> {{ template "navbar-link" (props
<a href="/api/auth/login" hx-boost="false" class="p-[1em] font-display {{ if eq $path "/auth/login" }}selected{{ end }}"> "Href" "/api/auth/login"
Log In "NoHXBoost" true
</a> "Selected" (eq $path "/auth/login")
</li> "Content" "Log In"
)}}
{{- else if $hasAccount }} {{- else if $hasAccount }}
{{- $acctID := .Identity.Account.AccountID }} {{- $acctID = .Identity.Account.AccountID }}
<li class="pt-[1em] pb-[1em]"> {{ template "navbar-link" (props
<a href="/ui/accounts/{{$acctID}}" class="p-[1em] font-display {{ if eq $path (printf "/accounts/%d" $acctID) }}selected{{ end }}"> "Href" (printf "/ui/accounts/%d" $acctID)
Account "Selected" (eq $path (printf "/accounts/%d" $acctID))
</a> "Content" "Account"
</li> )}}
<li class="pt-[1em] pb-[1em]"> {{ template "navbar-link" (props
<a href="/ui/accounts/{{$acctID}}/inventory" class="p-[1em] font-display {{ if eq $path (printf "/accounts/%d/inventory" $acctID) }}selected{{ end }}"> "Href" (printf "/ui/accounts/%d/shops" $acctID)
Inventory "Selected" (hasPrefix $path (printf "/accounts/%d/shops" $acctID))
</a> "Content" "Shops"
</li> )}}
<li class="pt-[1em] pb-[1em]"> {{ template "navbar-link" (props
<a href="/ui/accounts/{{$acctID}}/reports" class="p-[1em] font-display {{ if eq $path (printf "/accounts/%d/reports" $acctID) }}selected{{ end }}"> "Href" (printf "/ui/accounts/%d/inventory" $acctID)
Reports "Selected" (hasPrefix $path (printf "/accounts/%d/inventory" $acctID))
</a> "Content" "Inventory"
</li> )}}
{{ template "navbar-link" (props
"Href" (printf "/ui/accounts/%d/reports" $acctID)
"Selected" (hasPrefix $path (printf "/accounts/%d/reports" $acctID))
"Content" "Reports"
)}}
{{- end }} {{- end }}
</ul> </ul>
</nav> </nav>
{{- if hasPrefix $path (printf "/accounts/%d/shops" $acctID) }}
<nav {{ template "navbar-class" . }}>
<ul
hx-swap="morph:innerHTML"
{{ template "navbar-ul-class" }}
>
{{ template "navbar-link" (props
"Href" (printf "/ui/accounts/%d/shops" $acctID)
"Selected" (eq $path (printf "/accounts/%d/shops" $acctID))
"Content" "Live"
)}}
{{ template "navbar-link" (props
"Href" (printf "/ui/accounts/%d/shops/mocks" $acctID)
"Selected" (eq $path (printf "/accounts/%d/shops/mocks" $acctID))
"Content" "Mock"
)}}
</ul>
</nav>
{{- end }}
{{- if hasPrefix $path (printf "/accounts/%d/inventory" $acctID) }}
<nav {{ template "navbar-class" . }}>
<ul
hx-swap="morph:innerHTML"
{{ template "navbar-ul-class" }}
>
{{ template "navbar-link" (props
"Href" (printf "/ui/accounts/%d/inventory" $acctID)
"Selected" (eq $path (printf "/accounts/%d/inventory" $acctID))
"Content" "Live"
)}}
{{ template "navbar-link" (props
"Href" (printf "/ui/accounts/%d/inventory/mock" $acctID)
"Selected" (eq $path (printf "/accounts/%d/inventory/mock" $acctID))
"Content" "Mock"
)}}
</ul>
</nav>
{{- end }}
</header> </header>
<main class="basis-full grow max-w-full"> <main class="basis-full grow max-w-full">
@@ -47,128 +47,3 @@
</div> </div>
</h2> </h2>
</section> </section>
<section
id="shops-section"
class="
m-[1rem]
pb-[1rem]
border-b-[2px]
border-sidebar-border
"
>
<details class="flex flex-col items-stretch" open>
<summary class="list-none cursor-pointer self-center">
{{-
component "tutorial-tooltip"
"AnchorTag" "h2"
"AnchorID" "shops-button"
"AnchorClickedEventName" "anchorClicked"
"AnchorContent" "Shops"
"AnchorClass" "bg-card my-[0.5em] px-[2em] py-[0.5em] rounded-lg"
"PopoverID" "shops-popover"
"PopoverContentIDPrefix" "shops-popover-content"
"PopoverContents" (
newHTMLSlice
"Click <span class=\"font-bold italic\">Shops</span> to display all shops and platforms available"
"Click <span class=\"font-bold italic\">Shops</span> to hide them again"
"There you go!"
)
}}
<!--h2
class="bg-card my-[0.5em] px-[2em] py-[0.5em] rounded-lg"
style="anchor-name: --shops-button;"
_="
on click
set popover to the #shops-popover
send shopsButtonClicked to #shops-popover
"
>
Shops
</h2-->
<!--div
popover="manual"
id="shops-popover"
class="
border-[1px] border-sidebar-border rounded-lg
bg-card
p-[1em]
animate-pulse
max-w-[80vw]
mt-[1.5em]
open:grid
cursor-default
"
style="
position: fixed;
position-anchor: --shops-button;
position-area: bottom;
grid-template-columns: 1fr max-content;
grid-template-rows: max-content;
gap: 1em;
box-shadow: 2px 2px 2px 1px rgb(0 0 0 / 20%);
transition-behavior: allow-discrete;
"
_="
init
call me.showPopover()
set :shopButtonClicks to 0
on click
event.preventDefault()
on shopsButtonClicked
set :shopButtonClicks to :shopButtonClicks + 1
if :shopButtonClicks is 1 then
hide #shop-popover-msg-1
show #shop-popover-msg-2
else if :shopButtonClicks is 2 then
hide #shop-popover-msg-2
show #shop-popover-msg-3
else if :shopButtonClicks is 3 then
call me.hidePopover()
end
"
>
<span id="shop-popover-msg-1" style="grid-column: 1;">
Click <span class="font-bold italic">Shops</span> to display all shops and platforms available
</span>
<span id="shop-popover-msg-2" style="grid-column: 1; display: none;">
Click <span class="font-bold italic">Shops</span> to hide them again
</span>
<span id="shop-popover-msg-3" style="grid-column: 1; display: none;">
There you go!
</span>
<button
class="cursor-pointer"
style="
grid-column: 2;
font-size: 2em;
line-height: 0.5em;
"
_="
on click
set parent to the closest #shops-popover
call parent.hidePopover()
"
>
&#x00d7;
</button>
</div-->
</summary>
<ul class="list-none" hx-swap="morph">
{{- range $i, $platform := .Accounts.GetOrderOfPlatformsOnAccountPage $acctID }}
{{ component (printf "/accounts/%d/platforms/%s/list-item" $acctID $platform) "OrderIndex" $i }}
{{- end }}
</ul>
</details>
</section>
@@ -0,0 +1,25 @@
{{- .Auth.ByMatchingAccountID 2 }}
{{- $acctID := .Identity.Account.AccountID }}
{{- $stores := .Accounts.GetShops $acctID -}}
{{- define "title" }} Inventory++ {{ end }}
<h1 class="text-center mb-[0.5em]">Inventory</h1>
<h2 class="text-center mb-[0.5em]">Synced Listings</h2>
<section class="w-full flex flex-col items-center">
<h3 class="mb-[1.25rem]">
Create a Sync Group
</h3>
{{/*
{{ component (printf "accounts/%d/inventory/sync-groups/draft/table" $acctID) }}
<div>
{{ component (printf "accounts/%d/inventory/sync-groups/draft/table/add-listing-button" $acctID) }}
{{ component (printf "accounts/%d/inventory/sync-groups/draft/table/save-sync-group-button" $acctID) }}
</div>
*/}}
</section>
@@ -0,0 +1,22 @@
{{- .Auth.ByMatchingAccountID 2 }}
{{- define "title" }} Inventory++ Shops {{ end }}
{{- $acctID := .Identity.Account.AccountID }}
<section
id="shops-section"
class="
m-[1rem]
pb-[1rem]
"
>
<ul class="list-none" hx-swap="morph">
{{- range $i, $platform := .Accounts.GetOrderOfPlatformsOnAccountPage $acctID }}
{{ component (printf "/accounts/%d/platforms/%s/shops/list-item" $acctID $platform)
"OrderIndex" $i
}}
{{- end }}
</ul>
</section>
@@ -0,0 +1,23 @@
{{- .Auth.ByMatchingAccountID 2 }}
{{- define "title" }} Inventory++ Mock Shops {{ end }}
{{- $acctID := .Identity.Account.AccountID }}
<section
id="mock-shops-section"
class="
m-[1rem]
pb-[1rem]
"
>
<ul class="list-none" hx-swap="morph">
{{- range $i, $platform := .Accounts.GetOrderOfPlatformsOnAccountPage $acctID }}
{{ component (printf "/accounts/%d/platforms/%s/shops/list-item" $acctID $platform)
"OrderIndex" $i
"Mock" true
}}
{{- end }}
</ul>
</section>