329 lines
8.3 KiB
Cheetah
329 lines
8.3 KiB
Cheetah
{{- $loggedIn := and (and .Identity .Identity.AccessToken) true -}}
|
|
{{- $hasAccount := and (and .Identity .Identity.Account) true -}}
|
|
{{- $acctID := 0 }}
|
|
{{- $mockMode := false }}
|
|
{{- if $hasAccount }}
|
|
{{- $acctID = .Identity.Account.AccountID }}
|
|
{{- $mockMode = .Accounts.GetMockMode $acctID }}
|
|
{{- end }}
|
|
|
|
|
|
<!DOCTYPE html>
|
|
<html class="min-h-full flex flex-col items-stretch">
|
|
<head>
|
|
<title>
|
|
{{ block "title" . }} Inventory++ {{ end }}
|
|
</title>
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
|
|
|
<link rel="stylesheet" href="/styles/index.css">
|
|
|
|
<script src="/scripts/htmx.min.js.gz"></script>
|
|
<script src="/scripts/_hyperscript.min.js.gz"></script>
|
|
<script src="/scripts/htmx-ext-sse.js"></script>
|
|
<script src="/scripts/htmx-ext-path-params.js"></script>
|
|
<script src="/scripts/idiomorph-ext.js"></script>
|
|
<script src="/scripts/hx-drag.js"></script>
|
|
|
|
<link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png">
|
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png">
|
|
<link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png">
|
|
<link rel="manifest" href="/favicon/site.webmanifest">
|
|
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link href="https://fonts.googleapis.com/css2?family=Geist:wght@100..900&family=Open+Sans:ital,wght@0,300..800;1,300..800&display=swap" rel="stylesheet">
|
|
<link href="https://fonts.googleapis.com/css2?family=Alexandria:wght@100..900&family=Geist:wght@100..900&family=Open+Sans:ital,wght@0,300..800;1,300..800&display=swap" rel="stylesheet">
|
|
|
|
{{/* This can be set by the template in ./pages being rendered */}}
|
|
{{- block "head" . }}{{ end }}
|
|
</head>
|
|
|
|
<body
|
|
class="basis-full grow bg-background flex flex-col items-stretch"
|
|
hx-ext="morph,path-params,sse,drag"
|
|
{{/* get requests to just replace the body - until we start replacing the head, this will be good */}}
|
|
hx-boost="true"
|
|
|
|
{{/* subscribe to sse (if logged in) */}}
|
|
{{- if and $loggedIn $hasAccount }}
|
|
sse-connect="/api/events/"
|
|
sse-close="close"
|
|
{{- end }}
|
|
>
|
|
<header>
|
|
{{- $path := or .Request.URL.Path "/" }}
|
|
|
|
{{ define "navbar-class" }}class="
|
|
w-full
|
|
text-xl
|
|
overflow-x-hidden
|
|
overflow-y-hidden
|
|
|
|
flex
|
|
justify-center
|
|
"{{ end }}
|
|
|
|
{{ define "navbar-ul-class" }}class="
|
|
max-w-full
|
|
overflow-x-auto
|
|
overflow-y-hidden
|
|
text-nowrap
|
|
|
|
flex
|
|
basis-[fit-content]
|
|
"}}
|
|
{{ 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 }}
|
|
|
|
{{/* navbar updater */}}
|
|
{{- if $hasAccount }}
|
|
<div
|
|
hx-trigger="sse:accounts_{{$acctID}}_mock-mode"
|
|
hx-get="/ui{{$path}}"
|
|
hx-select="#header-navbar"
|
|
hx-target="#header-navbar"
|
|
hx-swap="outerHTML"
|
|
hidden
|
|
>
|
|
</div>
|
|
{{- end }}
|
|
|
|
<nav
|
|
{{ template "navbar-class" . }}
|
|
id="header-navbar"
|
|
>
|
|
<ul
|
|
hx-swap="morph:innerHTML"
|
|
{{ template "navbar-ul-class" }}
|
|
>
|
|
{{- if not $loggedIn }}
|
|
|
|
{{ template "navbar-link" (props
|
|
"Href" "/api/auth/login"
|
|
"NoHXBoost" true
|
|
"Selected" (eq $path "/auth/login")
|
|
"Content" "Log In"
|
|
)}}
|
|
|
|
{{- else if $hasAccount }}
|
|
{{ template "navbar-link" (props
|
|
"Href" (printf "/ui/accounts/%d" $acctID)
|
|
"Selected" (eq $path (printf "/accounts/%d" $acctID))
|
|
"Content" "Account"
|
|
)}}
|
|
|
|
{{- $shopUIPath := printf "/accounts/%d/shops" $acctID }}
|
|
{{- if $mockMode }}
|
|
{{- $shopUIPath = printf "%s/mock" $shopUIPath }}
|
|
{{- end }}
|
|
|
|
{{ template "navbar-link" (props
|
|
"Href" (printf "/ui%s" $shopUIPath)
|
|
"Selected" (hasPrefix $path $shopUIPath)
|
|
"Content" "Shops"
|
|
)}}
|
|
|
|
{{- $inventoryUIPath := printf "/accounts/%d/inventory" $acctID }}
|
|
{{- if $mockMode }}
|
|
{{- $inventoryUIPath = printf "%s/mock" $inventoryUIPath }}
|
|
{{- end }}
|
|
|
|
{{ template "navbar-link" (props
|
|
"Href" (printf "/ui%s" $inventoryUIPath)
|
|
"Selected" (hasPrefix $path $inventoryUIPath)
|
|
"Content" "Inventory"
|
|
)}}
|
|
|
|
{{- $reportsUIPath := printf "/accounts/%d/reports" $acctID }}
|
|
{{- if $mockMode }}
|
|
{{- $reportsUIPath = printf "%s/mock" $reportsUIPath }}
|
|
{{- end }}
|
|
|
|
{{ template "navbar-link" (props
|
|
"Href" (printf "/ui%s" $reportsUIPath)
|
|
"Selected" (hasPrefix $path $reportsUIPath)
|
|
"Content" "Reports"
|
|
)}}
|
|
|
|
{{- end }}
|
|
</ul>
|
|
</nav>
|
|
|
|
{{/* TODO: delete this AFTER we're sure we don't need this anymore */}}
|
|
{{/*- 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/mock" $acctID)
|
|
"Selected" (eq $path (printf "/accounts/%d/shops/mock" $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>
|
|
|
|
<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>
|
|
|
|
<footer class="grid grid-cols-[6rem_10fr_6rem] justify-center items-center">
|
|
<address class="grow-1 col-2 flex justify-center">
|
|
<a href="mailto:contact-us@inventory-plus-plus.com" class="p-[1em] font-display text-center">Contact Us</a>
|
|
<a href="mailto:support@inventory-plus-plus.com" class="p-[1em] font-display text-center">Support</a>
|
|
</address>
|
|
{{- if .Identity.Claims.Picture }}
|
|
<button
|
|
popovertarget="identity-popover"
|
|
class="
|
|
col-3
|
|
max-w-full
|
|
max-h-full
|
|
|
|
flex
|
|
justify-center
|
|
items-center
|
|
"
|
|
>
|
|
<img
|
|
src="{{ .Identity.Claims.Picture }}"
|
|
class="rounded-[50%]"
|
|
style="
|
|
max-height: 3rem;
|
|
margin: 1rem 0;
|
|
"
|
|
/>
|
|
</button>
|
|
<div
|
|
popover="auto"
|
|
id="identity-popover"
|
|
class="
|
|
border-[1px] border-sidebar-border rounded-lg
|
|
bg-card
|
|
p-[1em]
|
|
"
|
|
style="
|
|
top: calc(100% - 15rem);
|
|
left: calc(100% - 20rem);
|
|
box-shadow: 2px 2px 2px 1px rgb(0 0 0 / 20%);
|
|
"
|
|
>
|
|
<div class="
|
|
flex
|
|
justify-start
|
|
items-center
|
|
gap-[1em]
|
|
|
|
pb-[1em]
|
|
border-b-[2px]
|
|
border-sidebar-border
|
|
">
|
|
<div
|
|
class="
|
|
flex
|
|
justify-center
|
|
items-center
|
|
"
|
|
style="
|
|
flex-basis: 3rem;
|
|
flex-shrink: 0;
|
|
"
|
|
>
|
|
<img
|
|
src="{{ .Identity.Claims.Picture }}"
|
|
class="rounded-[50%]"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<div class="font-display" style="word-break: break-word;">
|
|
{{ .Identity.Claims.Name }}
|
|
</div>
|
|
|
|
<div style="word-break: break-word;">
|
|
{{ or .Identity.Claims.Nickname .Identity.Claims.Subject }}
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<a
|
|
href="/api/auth/logout"
|
|
hx-boost="false"
|
|
class="
|
|
w-fit
|
|
flex
|
|
items-center
|
|
p-[1em]
|
|
|
|
font-display
|
|
hover:underline
|
|
cursor-pointer
|
|
gap-[1em]
|
|
|
|
group
|
|
hover:bg-accent
|
|
rounded-lg
|
|
mt-[0.25em]
|
|
pr-[2em]
|
|
"
|
|
>
|
|
<img
|
|
src="/images/door.png"
|
|
class="h-[2rem] group-hover:scale-120 transition-[scale] dark:invert"
|
|
/>
|
|
Log Out
|
|
</a>
|
|
|
|
</div>
|
|
{{- end }}
|
|
</footer>
|
|
</body>
|
|
</html>
|