first drafts for inventory sync page

This commit is contained in:
2026-01-09 18:03:54 -07:00
parent 846f56e50b
commit a7c8fe4d64
40 changed files with 1310 additions and 121 deletions
@@ -0,0 +1,65 @@
{{/* .Identity.Account.AccountID | .PathParams.acctID | .AccountID */}}
{{- $dot := or .dot . }}
{{- .Auth.ByMatchingAccountID 2 }}
{{- $acctID := 0 }}
{{- if $dot.Identity }}
{{- $acctID = $dot.Identity.Account.AccountID }}
{{- else if .PathParams }}
{{- $acctID = $dot.PathParams.acctID | parseInt64 }}
{{- else }}
{{- $acctID = $dot.AccountID }}
{{- end }}
{{- $stores := $dot.Accounts.GetShops $acctID -}}
<table id="inventory-table-2" class="max-w-full overflow-x-scroll">
<thead>
<tr>
<th>
Shop
</th>
<th>
Listing
</th>
<th>
SKU
</th>
<th>
Description
</th>
<th>
</th>
</tr>
</thead>
<tbody>
{{/* TODO: list existing row */}}
{{- componentBody "accounts/{acctID}/inventory/sync-table-v2/new-row" "dot" $dot }}
{{/* TODO: save the saved rows */}}
</tbody>
<tfoot>
<tr>
<th>
Shop
</th>
<th>
Listing
</th>
<th>
SKU
</th>
<th>
Description
</th>
<th>
</th>
</tr>
</tfoot>
</table>
@@ -0,0 +1,64 @@
{{/* .Identity.Account.AccountID, .Accounts */}}
{{- $dot := or .dot . -}}
{{- $acctID := $dot.Identity.Account.AccountID }}
{{- $shops := $dot.Accounts.GetShops $acctID -}}
<tr _="
on setListing(listing)
set the innerHTML of (the last <td[data-id=sku]/> in me) to listing.sku
set the innerHTML of (the last <td[data-id=description]/> in me) to listing.description
-- TODO: only remove if there isn't already a 'new row'
remove @disabled from (the <button/> in last <td[data-id=save]/> in me)
on resetListing
set the innerHTML of (the last <td[data-id=sku]/> in me) to '-'
set the innerHTML of (the last <td[data-id=description]/> in me) to '-'
add @disabled to (the <button/> in last <td[data-id=save]/> in me)
"
>
<td>
<select
class="min-w-fit cursor-pointer"
hx-get="/accounts/{{$acctID}}/platforms/{platform}/shops/{shopID}/listing-select"
hx-vals='js:{
platform: event.target.value.replace(/-[^ ]*/, ""),
shopID: event.target.value.replace(/[^ ]*-/, "")
}'
hx-target="next td"
_="
on change
log event.target.value
send resetListing() to closest <tr/>
"
>
<option disabled selected>- Shops -</option>
{{- range $shop := $shops }}
<option value="{{$shop.Platform}}-{{$shop.ShopID}}">
{{ $shop.Name }} - {{$shop.Platform}} - {{$shop.ShopID}}
</option>
{{- end }}
</select>
</td>
<td>
-
</td>
<td data-id="sku">
-
</td>
<td data-id="description">
-
</td>
<td data-id="save">
<button
disabled
hx-get="/accounts/{{$acctID}}/inventory/sync-table-v2/new-row"
hx-target="closest tr"
hx-swap="afterend"
>
Save
</button>
</td>
</tr>
@@ -0,0 +1,46 @@
{{- $dot := or .dot . }}
{{- $dot.Auth.ByMatchingAccountID 2 }}
{{- $acctID := $dot.Identity.Account.AccountID }}
{{- $stores := $dot.Accounts.GetShops $acctID -}}
<table id="inventory-table" class="max-w-full overflow-x-scroll">
<thead>
<tr>
{{- range $store := $stores }}
<th class="text-nowrap">
{{ $store.Platform }}: {{ $store.Name }}
</th>
<th class="text-nowrap">
Count
</th>
{{- end }}
<th>
</th>
</tr>
</thead>
<tbody>
{{- componentBody "accounts/{acctID}/inventory/sync-table/new-row" "dot" $dot }}
</tbody>
<tfoot>
<tr>
{{- range $store := $stores }}
<th class="text-nowrap">
{{ $store.Platform }}: {{ $store.Name }}
</th>
<th class="text-nowrap">
Count
</th>
{{- end }}
<th>
</th>
</tr>
</tfoot>
</table>
@@ -0,0 +1,54 @@
{{- $dot := or .dot .}}
{{- $dot.Auth.ByMatchingAccountID 2 }}
{{- $acctID := $dot.Identity.Account.AccountID }}
{{- $shops := $dot.Accounts.GetShops $acctID -}}
<tr>
{{- range $shop := $shops }}
{{- $listings := $dot.Accounts.GetListingsForShop $acctID $shop.ShopID }}
<td>
<select
class="min-w-fit cursor-pointer"
_="
on change
set dataset to the dataset of the first of my selectedOptions
set listingShowcase to the <#listing-showcase/>
if <#listing-showcase/> then
send displayListing(
id: dataset.id,
name: dataset.name,
description: dataset.description,
count: dataset.count
) to listingShowcase
end
set the innerHTML of the next <td/> to the dataset.count
"
>
<option disabled selected>- Listings -</option>
{{- range $listing := $listings }}
<option
value="{{$listing.ListingID}}"
data-id="{{$listing.ListingID}}"
data-name="{{$listing.Name}}"
data-description="{{$listing.Description}}"
data-count="{{$listing.Count}}"
>
{{ $listing.Name }}
</option>
{{- end }}
</select>
</td>
<td>
</td>
{{- end }}
<td>
<button class="cursor-pointer underline w-full">
Save
</button>
</td>
</tr>
@@ -0,0 +1,40 @@
<table class="max-w-full"
id="listing-showcase"
_="
on displayListing(id, name, description, count)
set innerHTML of <#listing-showcase-id/> to id
set innerHTML of <#listing-showcase-name/> to name
set innerHTML of <#listing-showcase-description/> to description
set innerHTML of <#listing-showcase-count/> to count
"
>
<thead>
<th>
ID
</th>
<th>
Name
</th>
<th>
Description
</th>
<th>
Count
</th>
</thead>
<tbody>
<th id="listing-showcase-id">
-
</th>
<th id="listing-showcase-name">
-
</th>
<th id="listing-showcase-description">
-
</th>
<th id="listing-showcase-count">
-
</th>
</tbody>
</table>
@@ -0,0 +1,29 @@
{{/* .ShopID: default to path param "shopID" */}}
{{- $shopID := or (and .PathParams .PathParams.shopID) .ShopID }}
{{ $acctID := .Identity.Account.AccountID }}
<select
class="min-w-fit cursor-pointer"
_="
on input
set dataset to (my selectedOptions)[0].dataset
send setListing(listing: dataset) to the closest <tr/>
"
>
{{- $listings := .Accounts.GetListingsForShop $acctID $shopID }}
{{- $dot := . }}
<option disabled selected>- Listings -</option>
{{- range $listing := $listings }}
<option
value="{{$listing.SKU}}"
data-name="{{ $listing.Name }}"
data-sku="{{ $listing.SKU }}"
data-description="{{ $listing.Description }}"
data-count="{{ $listing.Count }}"
>
{{ $listing.Name }}
</option>
{{- end }}
</select>
@@ -27,7 +27,7 @@
{{- $acct := .dot.Identity.Account }}
{{- $acctID := 0 }}
{{- if $acct }}
{{- $acctID = $acct.ID }}
{{- $acctID = $acct.AccountID }}
{{- end }}
{{- if not $userID }}
+7 -6
View File
@@ -11,12 +11,13 @@
<script src="/scripts/htmx.min.js.gz"></script>
<script src="/scripts/_hyperscript.min.js.gz"></script>
<script src="https://unpkg.com/htmx-ext-path-params@2.0.0/path-params.js"></script>
{{/* This is where the page_head template will be inserted into the page */}}
{{- block "head" . }}{{ end }}
</head>
<body class="basis-full grow bg-background flex flex-col items-stretch">
<body class="basis-full grow bg-background flex flex-col items-stretch" hx-ext="path-params">
<header>
<nav class="flex flex-col items-center text-xl overflow-x-scroll overflow-y-hidden ">
{{- $path := or .Request.URL.Path "/" }}
@@ -33,7 +34,7 @@
{{- $acct := .Identity.Account }}
{{- $acctID := 0 }}
{{- if $acct }}
{{- $acctID = $acct.ID }}
{{- $acctID = $acct.AccountID }}
{{- end }}
{{- if not $userID }}
@@ -53,14 +54,14 @@
</li>
<li class="pt-[1em] pb-[1em]">
<a href="/accounts/{{$acctID}}/reports" class="p-[1em] font-bold {{ if eq $path (printf "/accounts/%d/reports" $acctID) }}selected{{ end }}">
Reports
<a href="/accounts/{{$acctID}}/inventory" class="p-[1em] font-bold {{ if eq $path (printf "/accounts/%d/inventory" $acctID) }}selected{{ end }}">
Inventory
</a>
</li>
<li class="pt-[1em] pb-[1em]">
<a href="/accounts/{{$acctID}}/inventory" class="p-[1em] font-bold {{ if eq $path (printf "/accounts/%d/inventory" $acctID) }}selected{{ end }}">
Inventory
<a href="/accounts/{{$acctID}}/reports" class="p-[1em] font-bold {{ if eq $path (printf "/accounts/%d/reports" $acctID) }}selected{{ end }}">
Reports
</a>
</li>
@@ -6,15 +6,15 @@
<h1>Account: {{ $acctID.Email }}</h1>
{{- $etsyUser := .Etsy.GetUserPointerByAccountID $acctID.ID }}
{{- $etsyUser := .Etsy.GetUserPointerByAccountID $acctID.AccountID }}
{{- if $etsyUser }}
<h3>Etsy User: {{ $etsyUser.UserID }}; Shop ID: {{ $etsyUser.ShopID }}</h3>
{{- else }}
<h3>
{{/* TODO: create this link dynamically, not EVERYTIME THE PAGE IS LOADED */}}
<a href="{{ printf "/webhooks/etsy/%d/new-account-link" $acctID.ID }}">
<a href="{{ printf "/webhooks/etsy/%d/new-account-link" $acctID.AccountID }}">
Link Your Etsy Store!
</a>
</h3>
{{- end }}
<h2><a href="/accounts/{{$acctID.ID}}/reports">View Reports</a></h2>
<h2><a href="/accounts/{{$acctID.AccountID}}/reports">View Reports</a></h2>
@@ -2,4 +2,38 @@
{{- define "title" }} Inventory++ {{ end }}
<h1>Inventory management page: WIP</h1>
<h1 class="text-center mb-[0.5em]">Inventory</h1>
<h2 class="text-center mb-[0.5em]">Sync Stores</h2>
{{ $acctID := .Identity.Account.AccountID }}
{{ $stores := .Accounts.GetShops $acctID }}
<section class="w-full flex flex-col items-center">
<h3>
Draft 2
</h3>
{{ componentBody "accounts/{acctID}/inventory/sync-table-v2" "dot" . }}
</section>
<section class="w-full flex flex-col items-center">
<h3>
Draft 1
</h3>
{{ componentBody "accounts/{acctID}/inventory/sync-table" "dot" . }}
</section>
<section class="flex justify-center mt-[1em]">
{{ componentBody "accounts/{acctID}/inventory/sync-table/showcase-table" "dot" . }}
</section>
<section class="w-full flex justify-center mt-[1em]">
<button
class="border-thin bg-card rounded-sm p-[0.5em] font-semibold cursor-pointer hover:underline hover:bg-accent"
hx-get="/accounts/{{$acctID}}/inventory/sync-table/new-row"
hx-target="#inventory-table > tbody"
hx-swap="beforeend"
>
Add Row
</button>
</section>
@@ -6,6 +6,7 @@
</section>
{{- if and .Identity.User.UserID (not .Identity.Account) }}
{{/* TODO: make account creation automatic as part of the user creation process */}}
<h2><a href="/account-creation">New Account</a></h2>
{{- end }}