updated accounts page: display user info and list shops

This commit is contained in:
2026-01-25 01:23:52 -07:00
parent 1c305cd494
commit 2b1cc7af75
17 changed files with 469 additions and 18 deletions
+5
View File
@@ -65,6 +65,11 @@ func Routes(
return accounts.NewPlatform(s)
},
// strings
"lowerCamelCase": func(s string) string {
return strings.ToLower(strings.Join(strings.Split(s, " "), "_"))
},
// arithmetic
"addInt": func(a, b int) int {
return a + b
+322
View File
@@ -7,6 +7,7 @@
"Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
"Courier New", monospace;
--color-sky-400: oklch(74.6% 0.16 232.661);
--color-black: #000;
--color-white: #fff;
--text-sm: 0.875rem;
@@ -213,9 +214,21 @@
.m-\[1em\] {
margin: 1em;
}
.m-\[1rem\] {
margin: 1rem;
}
.m-\[2em\] {
margin: 2em;
}
.my-\[0\.5em\] {
margin-block: 0.5em;
}
.my-\[1rem\] {
margin-block: 1rem;
}
.my-\[2rem\] {
margin-block: 2rem;
}
.mt-\[0\.25em\] {
margin-top: 0.25em;
}
@@ -228,12 +241,18 @@
.mb-\[0\.5em\] {
margin-bottom: 0.5em;
}
.mb-\[0\.5rem\] {
margin-bottom: 0.5rem;
}
.mb-\[1\.25rem\] {
margin-bottom: 1.25rem;
}
.mb-\[1em\] {
margin-bottom: 1em;
}
.mb-\[1rem\] {
margin-bottom: 1rem;
}
.mb-\[3em\] {
margin-bottom: 3em;
}
@@ -252,9 +271,21 @@
.hidden {
display: none;
}
.inline {
display: inline;
}
.inline-block {
display: inline-block;
}
.table {
display: table;
}
.h-\[1em\] {
height: 1em;
}
.h-\[2em\] {
height: 2em;
}
.h-\[2rem\] {
height: 2rem;
}
@@ -300,6 +331,9 @@
.resize {
resize: both;
}
.list-none {
list-style-type: none;
}
.grid-cols-\[6rem_10fr_6rem\] {
grid-template-columns: 6rem 10fr 6rem;
}
@@ -324,6 +358,9 @@
.gap-y-\[2em\] {
row-gap: 2em;
}
.self-center {
align-self: center;
}
.overflow-x-auto {
overflow-x: auto;
}
@@ -333,6 +370,9 @@
.overflow-y-hidden {
overflow-y: hidden;
}
.rounded {
border-radius: 0.25rem;
}
.rounded-\[50\%\] {
border-radius: 50%;
}
@@ -354,6 +394,10 @@
border-bottom-style: var(--tw-border-style);
border-bottom-width: 2px;
}
.border-dotted {
--tw-border-style: dotted;
border-style: dotted;
}
.border-sidebar-border {
border-color: var(--sidebar-border);
}
@@ -378,15 +422,42 @@
.p-\[1em\] {
padding: 1em;
}
.p-\[1rem\] {
padding: 1rem;
}
.px-\[0\.5em\] {
padding-inline: 0.5em;
}
.px-\[0\.75em\] {
padding-inline: 0.75em;
}
.px-\[2em\] {
padding-inline: 2em;
}
.py-\[0\.5em\] {
padding-block: 0.5em;
}
.py-\[1em\] {
padding-block: 1em;
}
.py-\[1rem\] {
padding-block: 1rem;
}
.pt-\[1em\] {
padding-top: 1em;
}
.pr-\[2em\] {
padding-right: 2em;
}
.pb-\[0\.5em\] {
padding-bottom: 0.5em;
}
.pb-\[1em\] {
padding-bottom: 1em;
}
.pb-\[1rem\] {
padding-bottom: 1rem;
}
.text-center {
text-align: center;
}
@@ -460,6 +531,50 @@
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
transition-duration: var(--tw-duration, var(--default-transition-duration));
}
.group-open\:border-b-\[0\.5rem\] {
&:is(:where(.group):is([open], :popover-open, :open) *) {
border-bottom-style: var(--tw-border-style);
border-bottom-width: 0.5rem;
}
}
.group-open\:border-b-\[0\.25rem\] {
&:is(:where(.group):is([open], :popover-open, :open) *) {
border-bottom-style: var(--tw-border-style);
border-bottom-width: 0.25rem;
}
}
.group-open\:border-b-\[1px\] {
&:is(:where(.group):is([open], :popover-open, :open) *) {
border-bottom-style: var(--tw-border-style);
border-bottom-width: 1px;
}
}
.group-open\:border-b-\[1rem\] {
&:is(:where(.group):is([open], :popover-open, :open) *) {
border-bottom-style: var(--tw-border-style);
border-bottom-width: 1rem;
}
}
.group-open\:border-b-accent {
&:is(:where(.group):is([open], :popover-open, :open) *) {
border-bottom-color: var(--accent);
}
}
.group-open\:border-b-background {
&:is(:where(.group):is([open], :popover-open, :open) *) {
border-bottom-color: var(--background);
}
}
.group-open\:border-b-black {
&:is(:where(.group):is([open], :popover-open, :open) *) {
border-bottom-color: var(--color-black);
}
}
.group-open\:bg-background {
&:is(:where(.group):is([open], :popover-open, :open) *) {
background-color: var(--background);
}
}
.group-hover\:scale-120 {
&:is(:where(.group):hover *) {
@media (hover: hover) {
@@ -470,6 +585,197 @@
}
}
}
.marker\:inline {
& *::marker {
display: inline;
}
&::marker {
display: inline;
}
& *::-webkit-details-marker {
display: inline;
}
&::-webkit-details-marker {
display: inline;
}
}
.marker\:inline-block {
& *::marker {
display: inline-block;
}
&::marker {
display: inline-block;
}
& *::-webkit-details-marker {
display: inline-block;
}
&::-webkit-details-marker {
display: inline-block;
}
}
.marker\:list-none {
& *::marker {
list-style-type: none;
}
&::marker {
list-style-type: none;
}
& *::-webkit-details-marker {
list-style-type: none;
}
&::-webkit-details-marker {
list-style-type: none;
}
}
.marker\:bg-accent {
& *::marker {
background-color: var(--accent);
}
&::marker {
background-color: var(--accent);
}
& *::-webkit-details-marker {
background-color: var(--accent);
}
&::-webkit-details-marker {
background-color: var(--accent);
}
}
.marker\:text-sky-400 {
& *::marker {
color: var(--color-sky-400);
}
&::marker {
color: var(--color-sky-400);
}
& *::-webkit-details-marker {
color: var(--color-sky-400);
}
&::-webkit-details-marker {
color: var(--color-sky-400);
}
}
.after\:float-right {
&::after {
content: var(--tw-content);
float: right;
}
}
.after\:text-\[1em\] {
&::after {
content: var(--tw-content);
font-size: 1em;
}
}
.after\:text-\[2em\] {
&::after {
content: var(--tw-content);
font-size: 2em;
}
}
.after\:text-\[3em\] {
&::after {
content: var(--tw-content);
font-size: 3em;
}
}
.after\:leading-\[1em\] {
&::after {
content: var(--tw-content);
--tw-leading: 1em;
line-height: 1em;
}
}
.after\:font-\[2em\] {
&::after {
content: var(--tw-content);
--tw-font-weight: 2em;
font-weight: 2em;
}
}
.after\:font-\[3em\] {
&::after {
content: var(--tw-content);
--tw-font-weight: 3em;
font-weight: 3em;
}
}
.after\:font-bold {
&::after {
content: var(--tw-content);
--tw-font-weight: var(--font-weight-bold);
font-weight: var(--font-weight-bold);
}
}
.after\:content-\[\'\&\#9654\'\] {
&::after {
--tw-content: '&#9654';
content: var(--tw-content);
}
}
.after\:content-\[\'\&\#9655\'\] {
&::after {
--tw-content: '&#9655';
content: var(--tw-content);
}
}
.after\:content-\[\'\&\#9656\'\] {
&::after {
--tw-content: '&#9656';
content: var(--tw-content);
}
}
.after\:content-\[\'\&\#x25B6\'\] {
&::after {
--tw-content: '&#x25B6';
content: var(--tw-content);
}
}
.after\:content-\[\'\+\'\] {
&::after {
--tw-content: '+';
content: var(--tw-content);
}
}
.after\:content-\[\'\>\'\] {
&::after {
--tw-content: '>';
content: var(--tw-content);
}
}
.after\:content-\[\'▷\'\] {
&::after {
--tw-content: '';
content: var(--tw-content);
}
}
.after\:content-\[\>\] {
&::after {
--tw-content: >;
content: var(--tw-content);
}
}
.group-open\:after\:content-\[\'\+\'\] {
&:is(:where(.group):is([open], :popover-open, :open) *) {
&::after {
--tw-content: '+';
content: var(--tw-content);
}
}
}
.group-open\:after\:content-\[\'-\'\] {
&:is(:where(.group):is([open], :popover-open, :open) *) {
&::after {
--tw-content: '-';
content: var(--tw-content);
}
}
}
.open\:bg-background {
&:is([open], :popover-open, :open) {
background-color: var(--background);
}
}
.hover\:scale-110 {
&:hover {
@media (hover: hover) {
@@ -558,6 +864,11 @@
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
}
}
.\[open\]\:bg-background {
&:is(open) {
background-color: var(--background);
}
}
}
@layer base {
select {
@@ -947,6 +1258,15 @@
inherits: false;
initial-value: 1;
}
@property --tw-content {
syntax: "*";
initial-value: "";
inherits: false;
}
@property --tw-leading {
syntax: "*";
inherits: false;
}
@layer properties {
@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {
*, ::before, ::after, ::backdrop {
@@ -968,6 +1288,8 @@
--tw-scale-x: 1;
--tw-scale-y: 1;
--tw-scale-z: 1;
--tw-content: "";
--tw-leading: initial;
}
}
}
@@ -0,0 +1 @@
<em>Coming soon!</em>
@@ -0,0 +1 @@
<em>Coming soon!</em>
@@ -0,0 +1,2 @@
<em>Coming soon!</em>
@@ -0,0 +1,2 @@
<em>Coming soon!</em>
@@ -0,0 +1,13 @@
{{- $acctID := .Identity.Account }}
{{- $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.AccountID }}">
Link Your Etsy Store!
</a>
</h3>
{{- end }}
@@ -0,0 +1,2 @@
<em>Coming soon!</em>
@@ -0,0 +1,2 @@
<em>Coming soon!</em>
@@ -0,0 +1,2 @@
<em>Coming soon!</em>
@@ -0,0 +1 @@
<em>Coming soon!</em>
@@ -0,0 +1,2 @@
<em>Coming soon!</em>
@@ -0,0 +1 @@
<em>Coming soon!</em>
@@ -0,0 +1,2 @@
<em>Coming soon!</em>
@@ -0,0 +1,2 @@
<em>Coming soon!</em>
+2 -2
View File
@@ -107,7 +107,7 @@
</nav>
</header>
<main class="basis-full grow p-[1em] max-w-full">
<main class="basis-full grow max-w-full">
{{/* This is where the page_body template will be inserted into the page */}}
{{- block "body" . }}{{ end }}
</main>
@@ -132,9 +132,9 @@
>
<img
src="{{ .Identity.Claims.Picture }}"
class="rounded-[50%]"
style="
max-height: 3rem;
border-radius: 50%;
margin: 1rem 0;
"
/>
@@ -2,22 +2,113 @@
{{- define "title" }} Inventory++ Account {{ end }}
{{- $acctID := .Identity.Account }}
{{- $acctID := .Identity.Account.AccountID }}
<section>
<h2>Account: {{ $acctID.Email }}</h2>
<h3>{{ .Identity.Claims.Name }}</h3>
<section class="m-[1rem]">
<h2>
<div class="
flex
justify-start
items-center
gap-[1em]
pb-[0.5em]
border-b-[2px]
border-sidebar-border
">
<div
class="
flex
justify-center
items-center
"
style="
flex-basis: 4em;
flex-shrink: 0;
"
>
<img
src="{{ .Identity.Claims.Picture }}"
class="rounded-[50%] height-[3em]"
/>
</div>
<div class="flex flex-col">
<span class="font-display" style="word-break: break-word;">
{{ .Identity.Claims.Name }}
</span>
<span style="word-break: break-word;">
{{ or .Identity.Claims.Nickname .Identity.Claims.Subject }}
</span>
</div>
</div>
</h2>
</section>
{{- $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.AccountID }}">
Link Your Etsy Store!
</a>
</h3>
<section
class="
m-[1rem]
pb-[1rem]
border-b-[2px]
border-sidebar-border
"
>
<details class="flex flex-col items-stretch">
<summary class="list-none cursor-pointer self-center">
<h2 class="bg-card my-[0.5em] px-[2em] py-[0.5em] rounded-lg">
Shops
</h2>
</summary>
<ul class="list-none">
{{- define "shop-list-entry" }}
{{/* .Platform, .AccountID */}}
<li class="my-[1rem] rounded-lg bg-accent">
<details class="group">
<summary class="
list-none
p-[1em]
after:content-['+']
group-open:after:content-['-']
after:float-right
after:font-bold
after:text-[2em]
after:leading-[1em]
cursor-pointer
group-open:border-b-background
group-open:border-b-[0.25rem]
border-dotted
">
<h3 class="inline-block">{{.Platform}}</h3>
</summary>
<div class="p-[1em] text-center">
{{- $pathSegment := lowerCamelCase .Platform }}
{{-
component
(printf "/accounts/%d/shops/link-sections/%s" .AccountID $pathSegment)
}}
</div>
</details>
</li>
{{- end }}
<h2><a href="/ui/accounts/{{$acctID.AccountID}}/reports">View Reports</a></h2>
{{- template "shop-list-entry" (props "Platform" "Amazon" "AccountID" $acctID) }}
{{- template "shop-list-entry" (props "Platform" "Big Cartel" "AccountID" $acctID) }}
{{- template "shop-list-entry" (props "Platform" "eBay" "AccountID" $acctID) }}
{{- template "shop-list-entry" (props "Platform" "Etsy" "AccountID" $acctID) }}
{{- template "shop-list-entry" (props "Platform" "Ecwid" "AccountID" $acctID) }}
{{- template "shop-list-entry" (props "Platform" "Shopify" "AccountID" $acctID) }}
{{- template "shop-list-entry" (props "Platform" "Square Online" "AccountID" $acctID) }}
{{- template "shop-list-entry" (props "Platform" "Squarespace" "AccountID" $acctID) }}
{{- template "shop-list-entry" (props "Platform" "Tiktok" "AccountID" $acctID) }}
{{- template "shop-list-entry" (props "Platform" "Walmart Marketplace" "AccountID" $acctID) }}
{{- template "shop-list-entry" (props "Platform" "Wix" "AccountID" $acctID) }}
{{- template "shop-list-entry" (props "Platform" "Woo Commerce" "AccountID" $acctID) }}
{{- template "shop-list-entry" (props "Platform" "Zoho" "AccountID" $acctID) }}
</ul>
</details>
</section>