mirror of
https://github.com/hay-kot/homebox.git
synced 2025-08-05 17:10:30 +00:00
wip: more UI fixes for consistency across themes
This commit is contained in:
parent
b66bc407fc
commit
b6c73733dc
12 changed files with 278 additions and 129 deletions
|
@ -29,7 +29,7 @@ func (ctrl *V1Controller) HandleItemsGetAll() server.HandlerFunc {
|
||||||
|
|
||||||
return repo.ItemQuery{
|
return repo.ItemQuery{
|
||||||
Page: queryIntOrNegativeOne(params.Get("page")),
|
Page: queryIntOrNegativeOne(params.Get("page")),
|
||||||
PageSize: queryIntOrNegativeOne(params.Get("perPage")),
|
PageSize: queryIntOrNegativeOne(params.Get("pageSize")),
|
||||||
Search: params.Get("q"),
|
Search: params.Get("q"),
|
||||||
LocationIDs: queryUUIDList(params, "locations"),
|
LocationIDs: queryUUIDList(params, "locations"),
|
||||||
LabelIDs: queryUUIDList(params, "labels"),
|
LabelIDs: queryUUIDList(params, "labels"),
|
||||||
|
|
|
@ -1,26 +1,64 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
// https://stackoverflow.com/questions/36721830/convert-hsl-to-rgb-and-hex
|
||||||
|
function hslToHex(h: number, s: number, l: number) {
|
||||||
|
l /= 100;
|
||||||
|
const a = (s * Math.min(l, 1 - l)) / 100;
|
||||||
|
const f = (n: number) => {
|
||||||
|
const k = (n + h / 30) % 12;
|
||||||
|
const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
|
||||||
|
return Math.round(255 * color)
|
||||||
|
.toString(16)
|
||||||
|
.padStart(2, "0"); // convert to Hex and prefix "0" if needed
|
||||||
|
};
|
||||||
|
return `#${f(0)}${f(8)}${f(4)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function unstring(value: string): [number, number, number] {
|
||||||
|
const [h, s, l] = value
|
||||||
|
.replace("hsla(", "")
|
||||||
|
.replace(")", "")
|
||||||
|
.replace(/%/g, "")
|
||||||
|
.split(",")
|
||||||
|
.map(v => v.trim());
|
||||||
|
|
||||||
|
return [Number(h), Number(s), Number(l)];
|
||||||
|
}
|
||||||
|
|
||||||
|
const primary = useCssVar("--p");
|
||||||
|
const primaryHex = computed(() => hslToHex(...unstring(primary.value)));
|
||||||
|
|
||||||
|
const accent = useCssVar("--a");
|
||||||
|
const accentHex = computed(() => hslToHex(...unstring(accent.value)));
|
||||||
|
|
||||||
|
const neutral = useCssVar("--n");
|
||||||
|
const neutralHex = computed(() => hslToHex(...unstring(neutral.value)));
|
||||||
|
|
||||||
|
const base100 = useCssVar("--b1");
|
||||||
|
const base100Hex = computed(() => hslToHex(...unstring(base100.value)));
|
||||||
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<svg viewBox="0 0 1440 237" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg viewBox="0 0 1440 237" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<g clip-path="url(#a)" filter="url(#b)">
|
<g clip-path="url(#a)" filter="url(#b)">
|
||||||
<path fill="#fff" d="M0-103h1440v310H0z" />
|
<path fill="#fff" d="M0-103h1440v310H0z" />
|
||||||
<path fill="#2C2E27" d="M0-103h1440v310H0z" />
|
<path :fill="neutralHex" d="M0-103h1440v310H0z" />
|
||||||
<g clip-path="url(#c)">
|
<g clip-path="url(#c)">
|
||||||
<path
|
<path
|
||||||
d="M1344.93 230.569h-75.81v-45.486h30.32c5.98 0 11.89 1.177 17.41 3.463s10.53 5.636 14.76 9.86c8.53 8.53 13.32 20.099 13.32 32.163Z"
|
d="M1344.93 230.569h-75.81v-45.486h30.32c5.98 0 11.89 1.177 17.41 3.463s10.53 5.636 14.76 9.86c8.53 8.53 13.32 20.099 13.32 32.163Z"
|
||||||
fill="#507B5D"
|
:fill="primaryHex"
|
||||||
/>
|
/>
|
||||||
<path
|
<path
|
||||||
d="M1297.89 170.07c0-3.395-2.75-6.147-6.14-6.147-3.4 0-6.15 2.752-6.15 6.147 0 3.395 2.75 6.148 6.15 6.148 3.39 0 6.14-2.753 6.14-6.148ZM1328.45 170.07c0-3.395-2.75-6.147-6.15-6.147-3.39 0-6.15 2.752-6.15 6.147 0 3.395 2.76 6.148 6.15 6.148 3.4 0 6.15-2.753 6.15-6.148Z"
|
d="M1297.89 170.07c0-3.395-2.75-6.147-6.14-6.147-3.4 0-6.15 2.752-6.15 6.147 0 3.395 2.75 6.148 6.15 6.148 3.39 0 6.14-2.753 6.14-6.148ZM1328.45 170.07c0-3.395-2.75-6.147-6.15-6.147-3.39 0-6.15 2.752-6.15 6.147 0 3.395 2.76 6.148 6.15 6.148 3.4 0 6.15-2.753 6.15-6.148Z"
|
||||||
fill="#F6FAFB"
|
:fill="base100Hex"
|
||||||
/>
|
/>
|
||||||
</g>
|
</g>
|
||||||
<g clip-path="url(#d)">
|
<g clip-path="url(#d)">
|
||||||
<path
|
<path
|
||||||
d="M1401.78 60c7.5 0 14.83 2.2231 21.06 6.388 6.24 4.165 11.09 10.0848 13.96 17.0109 2.87 6.9261 3.62 14.5474 2.16 21.9001-1.46 7.353-5.07 14.107-10.37 19.408-5.3 5.301-12.06 8.911-19.41 10.373-7.35 1.463-14.98.712-21.9-2.157-6.93-2.869-12.85-7.727-17.01-13.96-4.17-6.234-6.39-13.562-6.39-21.0587V60h37.9Z"
|
d="M1401.78 60c7.5 0 14.83 2.2231 21.06 6.388 6.24 4.165 11.09 10.0848 13.96 17.0109 2.87 6.9261 3.62 14.5474 2.16 21.9001-1.46 7.353-5.07 14.107-10.37 19.408-5.3 5.301-12.06 8.911-19.41 10.373-7.35 1.463-14.98.712-21.9-2.157-6.93-2.869-12.85-7.727-17.01-13.96-4.17-6.234-6.39-13.562-6.39-21.0587V60h37.9Z"
|
||||||
fill="#F6FAFB"
|
:fill="base100Hex"
|
||||||
/>
|
/>
|
||||||
</g>
|
</g>
|
||||||
<g clip-path="url(#e)">
|
<g clip-path="url(#e)">
|
||||||
<path d="M1269.12 135.809h75.81V60h-75.81v75.809Z" fill="#FFDA56" />
|
<path d="M1269.12 135.809h75.81V60h-75.81v75.809Z" :fill="accentHex" />
|
||||||
</g>
|
</g>
|
||||||
<g clip-path="url(#f)">
|
<g clip-path="url(#f)">
|
||||||
<path
|
<path
|
||||||
|
@ -29,35 +67,35 @@
|
||||||
/>
|
/>
|
||||||
</g>
|
</g>
|
||||||
<g clip-path="url(#g)">
|
<g clip-path="url(#g)">
|
||||||
<path d="M1079.6 135.809h75.81V60h-75.81v75.809Z" fill="#FFDA56" />
|
<path d="M1079.6 135.809h75.81V60h-75.81v75.809Z" :fill="accentHex" />
|
||||||
</g>
|
</g>
|
||||||
<g clip-path="url(#h)">
|
<g clip-path="url(#h)">
|
||||||
<path
|
<path
|
||||||
d="M890.08 60h75.808v45.485h-30.323c-5.973 0-11.888-1.176-17.406-3.462-5.519-2.2861-10.533-5.6365-14.757-9.8602C894.872 83.6327 890.08 72.0634 890.08 60Z"
|
d="M890.08 60h75.808v45.485h-30.323c-5.973 0-11.888-1.176-17.406-3.462-5.519-2.2861-10.533-5.6365-14.757-9.8602C894.872 83.6327 890.08 72.0634 890.08 60Z"
|
||||||
fill="#507B5D"
|
:fill="primaryHex"
|
||||||
/>
|
/>
|
||||||
<path
|
<path
|
||||||
d="M937.114 120.498c0 3.395 2.752 6.148 6.147 6.148 3.395 0 6.147-2.753 6.147-6.148 0-3.395-2.752-6.147-6.147-6.147-3.395 0-6.147 2.752-6.147 6.147ZM906.56 120.498c0 3.395 2.752 6.148 6.147 6.148 3.395 0 6.148-2.753 6.148-6.148 0-3.395-2.753-6.147-6.148-6.147-3.395 0-6.147 2.752-6.147 6.147Z"
|
d="M937.114 120.498c0 3.395 2.752 6.148 6.147 6.148 3.395 0 6.147-2.753 6.147-6.148 0-3.395-2.752-6.147-6.147-6.147-3.395 0-6.147 2.752-6.147 6.147ZM906.56 120.498c0 3.395 2.752 6.148 6.147 6.148 3.395 0 6.148-2.753 6.148-6.148 0-3.395-2.753-6.147-6.148-6.147-3.395 0-6.147 2.752-6.147 6.147Z"
|
||||||
fill="#F6FAFB"
|
:fill="base100Hex"
|
||||||
/>
|
/>
|
||||||
</g>
|
</g>
|
||||||
<g clip-path="url(#i)">
|
<g clip-path="url(#i)">
|
||||||
<path d="M795.32 154.76v75.809h75.808V154.76H795.32Z" fill="#FFDA56" />
|
<path d="M795.32 154.76v75.809h75.808V154.76H795.32Z" :fill="accentHex" />
|
||||||
</g>
|
</g>
|
||||||
<g clip-path="url(#j)">
|
<g clip-path="url(#j)">
|
||||||
<path
|
<path
|
||||||
d="M776.368 154.76v75.809h-45.485v-30.324c0-5.973 1.177-11.888 3.463-17.406 2.286-5.519 5.636-10.533 9.86-14.757 8.53-8.53 20.099-13.322 32.162-13.322Z"
|
d="M776.368 154.76v75.809h-45.485v-30.324c0-5.973 1.177-11.888 3.463-17.406 2.286-5.519 5.636-10.533 9.86-14.757 8.53-8.53 20.099-13.322 32.162-13.322Z"
|
||||||
fill="#507B5D"
|
:fill="primaryHex"
|
||||||
/>
|
/>
|
||||||
<path
|
<path
|
||||||
d="M715.87 201.794c-3.395 0-6.147 2.752-6.147 6.147 0 3.395 2.752 6.148 6.147 6.148 3.395 0 6.148-2.753 6.148-6.148 0-3.395-2.753-6.147-6.148-6.147ZM715.87 171.24c-3.395 0-6.147 2.752-6.147 6.147 0 3.395 2.752 6.148 6.147 6.148 3.395 0 6.148-2.753 6.148-6.148 0-3.395-2.753-6.147-6.148-6.147Z"
|
d="M715.87 201.794c-3.395 0-6.147 2.752-6.147 6.147 0 3.395 2.752 6.148 6.147 6.148 3.395 0 6.148-2.753 6.148-6.148 0-3.395-2.753-6.147-6.148-6.147ZM715.87 171.24c-3.395 0-6.147 2.752-6.147 6.147 0 3.395 2.752 6.148 6.147 6.148 3.395 0 6.148-2.753 6.148-6.148 0-3.395-2.753-6.147-6.148-6.147Z"
|
||||||
fill="#F6FAFB"
|
:fill="base100Hex"
|
||||||
/>
|
/>
|
||||||
</g>
|
</g>
|
||||||
<g clip-path="url(#k)">
|
<g clip-path="url(#k)">
|
||||||
<path
|
<path
|
||||||
d="M871.128 97.9043c0 7.4967-2.223 14.8247-6.388 21.0587-4.165 6.233-10.084 11.091-17.01 13.96-6.927 2.869-14.548 3.62-21.901 2.157-7.352-1.462-14.106-5.072-19.407-10.373-5.301-5.301-8.911-12.055-10.374-19.408-1.462-7.3527-.712-14.974 2.157-21.9001 2.869-6.9261 7.727-12.8459 13.961-17.0109C818.399 62.2231 825.727 60 833.224 60h37.904v37.9043Z"
|
d="M871.128 97.9043c0 7.4967-2.223 14.8247-6.388 21.0587-4.165 6.233-10.084 11.091-17.01 13.96-6.927 2.869-14.548 3.62-21.901 2.157-7.352-1.462-14.106-5.072-19.407-10.373-5.301-5.301-8.911-12.055-10.374-19.408-1.462-7.3527-.712-14.974 2.157-21.9001 2.869-6.9261 7.727-12.8459 13.961-17.0109C818.399 62.2231 825.727 60 833.224 60h37.904v37.9043Z"
|
||||||
fill="#F6FAFB"
|
:fill="base100Hex"
|
||||||
/>
|
/>
|
||||||
</g>
|
</g>
|
||||||
<g clip-path="url(#l)">
|
<g clip-path="url(#l)">
|
||||||
|
@ -72,17 +110,17 @@
|
||||||
<g clip-path="url(#m)">
|
<g clip-path="url(#m)">
|
||||||
<path
|
<path
|
||||||
d="M605.8 97.9043c0-7.4968 2.223-14.8252 6.388-21.0585 4.165-6.2333 10.085-11.0916 17.011-13.9605 6.926-2.8689 14.547-3.6195 21.9-2.157 7.353 1.4626 14.107 5.0726 19.408 10.3736 5.301 5.301 8.911 12.0549 10.373 19.4076 1.463 7.3527.712 14.9735-2.157 21.9005-2.869 6.926-7.727 12.846-13.96 17.01-6.234 4.165-13.562 6.389-21.059 6.389H605.8V97.9043Z"
|
d="M605.8 97.9043c0-7.4968 2.223-14.8252 6.388-21.0585 4.165-6.2333 10.085-11.0916 17.011-13.9605 6.926-2.8689 14.547-3.6195 21.9-2.157 7.353 1.4626 14.107 5.0726 19.408 10.3736 5.301 5.301 8.911 12.0549 10.373 19.4076 1.463 7.3527.712 14.9735-2.157 21.9005-2.869 6.926-7.727 12.846-13.96 17.01-6.234 4.165-13.562 6.389-21.059 6.389H605.8V97.9043Z"
|
||||||
fill="#F6FAFB"
|
:fill="base100Hex"
|
||||||
/>
|
/>
|
||||||
</g>
|
</g>
|
||||||
<g clip-path="url(#n)">
|
<g clip-path="url(#n)">
|
||||||
<path
|
<path
|
||||||
d="M511.04 135.809V60h45.485v30.3234c0 5.9732-1.176 11.8876-3.462 17.4066-2.286 5.518-5.637 10.533-9.86 14.756-8.53 8.53-20.1 13.323-32.163 13.323Z"
|
d="M511.04 135.809V60h45.485v30.3234c0 5.9732-1.176 11.8876-3.462 17.4066-2.286 5.518-5.637 10.533-9.86 14.756-8.53 8.53-20.1 13.323-32.163 13.323Z"
|
||||||
fill="#507B5D"
|
:fill="primaryHex"
|
||||||
/>
|
/>
|
||||||
<path
|
<path
|
||||||
d="M571.538 88.7746c3.395 0 6.147-2.7522 6.147-6.1473 0-3.395-2.752-6.1473-6.147-6.1473-3.395 0-6.147 2.7523-6.147 6.1473 0 3.3951 2.752 6.1473 6.147 6.1473ZM571.538 119.328c3.395 0 6.147-2.752 6.147-6.147 0-3.395-2.752-6.147-6.147-6.147-3.395 0-6.147 2.752-6.147 6.147 0 3.395 2.752 6.147 6.147 6.147Z"
|
d="M571.538 88.7746c3.395 0 6.147-2.7522 6.147-6.1473 0-3.395-2.752-6.1473-6.147-6.1473-3.395 0-6.147 2.7523-6.147 6.1473 0 3.3951 2.752 6.1473 6.147 6.1473ZM571.538 119.328c3.395 0 6.147-2.752 6.147-6.147 0-3.395-2.752-6.147-6.147-6.147-3.395 0-6.147 2.752-6.147 6.147 0 3.395 2.752 6.147 6.147 6.147Z"
|
||||||
fill="#F6FAFB"
|
:fill="base100Hex"
|
||||||
/>
|
/>
|
||||||
</g>
|
</g>
|
||||||
<g clip-path="url(#o)">
|
<g clip-path="url(#o)">
|
||||||
|
@ -103,28 +141,28 @@
|
||||||
<g clip-path="url(#q)">
|
<g clip-path="url(#q)">
|
||||||
<path
|
<path
|
||||||
d="M132 230.569V154.76h45.485v30.323c0 5.974-1.176 11.888-3.462 17.407-2.286 5.518-5.636 10.533-9.86 14.756-8.53 8.53-20.1 13.323-32.163 13.323Z"
|
d="M132 230.569V154.76h45.485v30.323c0 5.974-1.176 11.888-3.462 17.407-2.286 5.518-5.636 10.533-9.86 14.756-8.53 8.53-20.1 13.323-32.163 13.323Z"
|
||||||
fill="#507B5D"
|
:fill="primaryHex"
|
||||||
/>
|
/>
|
||||||
<path
|
<path
|
||||||
d="M192.498 183.535c3.395 0 6.148-2.753 6.148-6.148 0-3.395-2.753-6.147-6.148-6.147-3.395 0-6.147 2.752-6.147 6.147 0 3.395 2.752 6.148 6.147 6.148ZM192.498 214.089c3.395 0 6.148-2.753 6.148-6.148 0-3.395-2.753-6.147-6.148-6.147-3.395 0-6.147 2.752-6.147 6.147 0 3.395 2.752 6.148 6.147 6.148Z"
|
d="M192.498 183.535c3.395 0 6.148-2.753 6.148-6.148 0-3.395-2.753-6.147-6.148-6.147-3.395 0-6.147 2.752-6.147 6.147 0 3.395 2.752 6.148 6.147 6.148ZM192.498 214.089c3.395 0 6.148-2.753 6.148-6.148 0-3.395-2.753-6.147-6.148-6.147-3.395 0-6.147 2.752-6.147 6.147 0 3.395 2.752 6.148 6.147 6.148Z"
|
||||||
fill="#F6FAFB"
|
:fill="base100Hex"
|
||||||
/>
|
/>
|
||||||
</g>
|
</g>
|
||||||
<g clip-path="url(#r)">
|
<g clip-path="url(#r)">
|
||||||
<path
|
<path
|
||||||
d="M302.569 135.809H226.76V90.3234h30.323c5.974 0 11.888 1.1765 17.407 3.4624 5.518 2.2858 10.533 5.6362 14.756 9.8602 8.53 8.53 13.323 20.099 13.323 32.163Z"
|
d="M302.569 135.809H226.76V90.3234h30.323c5.974 0 11.888 1.1765 17.407 3.4624 5.518 2.2858 10.533 5.6362 14.756 9.8602 8.53 8.53 13.323 20.099 13.323 32.163Z"
|
||||||
fill="#507B5D"
|
:fill="primaryHex"
|
||||||
/>
|
/>
|
||||||
<path
|
<path
|
||||||
d="M255.535 75.3103c0-3.3951-2.753-6.1473-6.148-6.1473-3.395 0-6.147 2.7522-6.147 6.1473 0 3.3951 2.752 6.1473 6.147 6.1473 3.395 0 6.148-2.7522 6.148-6.1473ZM286.089 75.3103c0-3.3951-2.753-6.1473-6.148-6.1473-3.395 0-6.147 2.7522-6.147 6.1473 0 3.3951 2.752 6.1473 6.147 6.1473 3.395 0 6.148-2.7522 6.148-6.1473Z"
|
d="M255.535 75.3103c0-3.3951-2.753-6.1473-6.148-6.1473-3.395 0-6.147 2.7522-6.147 6.1473 0 3.3951 2.752 6.1473 6.147 6.1473 3.395 0 6.148-2.7522 6.148-6.1473ZM286.089 75.3103c0-3.3951-2.753-6.1473-6.148-6.1473-3.395 0-6.147 2.7522-6.147 6.1473 0 3.3951 2.752 6.1473 6.147 6.1473 3.395 0 6.148-2.7522 6.148-6.1473Z"
|
||||||
fill="#F6FAFB"
|
:fill="base100Hex"
|
||||||
/>
|
/>
|
||||||
</g>
|
</g>
|
||||||
<g clip-path="url(#s)">
|
<g clip-path="url(#s)">
|
||||||
<path d="M207.809 60H132v75.809h75.809V60Z" fill="#FFDA56" />
|
<path d="M207.809 60H132v75.809h75.809V60Z" :fill="accentHex" />
|
||||||
</g>
|
</g>
|
||||||
<g clip-path="url(#t)">
|
<g clip-path="url(#t)">
|
||||||
<path d="M502-31v75.8085h75.809V-31H502Z" fill="#FFDA56" />
|
<path d="M502-31v75.8085h75.809V-31H502Z" :fill="accentHex" />
|
||||||
</g>
|
</g>
|
||||||
<g clip-path="url(#u)">
|
<g clip-path="url(#u)">
|
||||||
<path
|
<path
|
||||||
|
@ -141,7 +179,7 @@
|
||||||
<g clip-path="url(#w)">
|
<g clip-path="url(#w)">
|
||||||
<path
|
<path
|
||||||
d="M388.089 6.66425c0 7.49675-2.224 14.82515-6.388 21.05845-4.165 6.2333-10.085 11.0916-17.011 13.9605-6.926 2.8689-14.548 3.6195-21.9 2.157-7.353-1.4626-14.107-5.0726-19.408-10.3736-5.301-5.301-8.911-12.0549-10.374-19.4076-1.462-7.3527-.712-14.973986 2.157-21.90008 2.869-6.92612 7.728-12.84592 13.961-17.01092 6.233-4.165 13.562-6.388 21.058-6.388h37.905V6.66425Z"
|
d="M388.089 6.66425c0 7.49675-2.224 14.82515-6.388 21.05845-4.165 6.2333-10.085 11.0916-17.011 13.9605-6.926 2.8689-14.548 3.6195-21.9 2.157-7.353-1.4626-14.107-5.0726-19.408-10.3736-5.301-5.301-8.911-12.0549-10.374-19.4076-1.462-7.3527-.712-14.973986 2.157-21.90008 2.869-6.92612 7.728-12.84592 13.961-17.01092 6.233-4.165 13.562-6.388 21.058-6.388h37.905V6.66425Z"
|
||||||
fill="#F6FAFB"
|
:fill="base100Hex"
|
||||||
/>
|
/>
|
||||||
</g>
|
</g>
|
||||||
<g clip-path="url(#x)">
|
<g clip-path="url(#x)">
|
||||||
|
@ -165,7 +203,7 @@
|
||||||
<g clip-path="url(#A)">
|
<g clip-path="url(#A)">
|
||||||
<path
|
<path
|
||||||
d="M956.648-31.24v75.8085h-45.485V14.2451c0-5.97318 1.177-11.88788 3.463-17.40639 2.286-5.5185 5.636-10.53271 9.86-14.75641 8.53-8.5301 20.099-13.3223 32.162-13.3223Z"
|
d="M956.648-31.24v75.8085h-45.485V14.2451c0-5.97318 1.177-11.88788 3.463-17.40639 2.286-5.5185 5.636-10.53271 9.86-14.75641 8.53-8.5301 20.099-13.3223 32.162-13.3223Z"
|
||||||
fill="#507B5D"
|
:fill="primaryHex"
|
||||||
/>
|
/>
|
||||||
<path
|
<path
|
||||||
d="M896.15 15.7939c-3.395 0-6.147 2.7522-6.147 6.1473 0 3.3951 2.752 6.1473 6.147 6.1473 3.395 0 6.148-2.7522 6.148-6.1473 0-3.3951-2.753-6.1473-6.148-6.1473Z"
|
d="M896.15 15.7939c-3.395 0-6.147 2.7522-6.147 6.1473 0 3.3951 2.752 6.1473 6.147 6.1473 3.395 0 6.148-2.7522 6.148-6.1473 0-3.3951-2.753-6.1473-6.148-6.1473Z"
|
||||||
|
@ -181,7 +219,7 @@
|
||||||
<g clip-path="url(#C)">
|
<g clip-path="url(#C)">
|
||||||
<path
|
<path
|
||||||
d="M1070.36 44.5685V-31.24h45.49V-.916588c0 5.973188-1.18 11.887888-3.47 17.406388-2.28 5.5185-5.63 10.5328-9.86 14.7564-8.53 8.5302-20.1 13.3223-32.16 13.3223Z"
|
d="M1070.36 44.5685V-31.24h45.49V-.916588c0 5.973188-1.18 11.887888-3.47 17.406388-2.28 5.5185-5.63 10.5328-9.86 14.7564-8.53 8.5302-20.1 13.3223-32.16 13.3223Z"
|
||||||
fill="#507B5D"
|
:fill="primaryHex"
|
||||||
/>
|
/>
|
||||||
<path
|
<path
|
||||||
d="M1130.86 28.0885c3.39 0 6.15-2.7522 6.15-6.1473 0-3.3951-2.76-6.1473-6.15-6.1473-3.4 0-6.15 2.7522-6.15 6.1473 0 3.3951 2.75 6.1473 6.15 6.1473Z"
|
d="M1130.86 28.0885c3.39 0 6.15-2.7522 6.15-6.1473 0-3.3951-2.76-6.1473-6.15-6.1473-3.4 0-6.15 2.7522-6.15 6.1473 0 3.3951 2.75 6.1473 6.15 6.1473Z"
|
||||||
|
@ -191,13 +229,13 @@
|
||||||
<g clip-path="url(#D)">
|
<g clip-path="url(#D)">
|
||||||
<path
|
<path
|
||||||
d="M1203.02 44.5685c-7.49 0-14.82-2.223-21.05-6.388-6.24-4.165-11.1-10.0848-13.96-17.0109-2.87-6.9261-3.62-14.54737-2.16-21.900078 1.46-7.352702 5.07-14.106622 10.37-19.407622 5.3-5.301 12.06-8.911 19.41-10.3736 7.35-1.4625 14.97-.7119 21.9 2.157 6.93 2.8689 12.85 7.7272 17.01 13.9605 4.17 6.23332 6.39 13.561722 6.39 21.05848V44.5685h-37.91Z"
|
d="M1203.02 44.5685c-7.49 0-14.82-2.223-21.05-6.388-6.24-4.165-11.1-10.0848-13.96-17.0109-2.87-6.9261-3.62-14.54737-2.16-21.900078 1.46-7.352702 5.07-14.106622 10.37-19.407622 5.3-5.301 12.06-8.911 19.41-10.3736 7.35-1.4625 14.97-.7119 21.9 2.157 6.93 2.8689 12.85 7.7272 17.01 13.9605 4.17 6.23332 6.39 13.561722 6.39 21.05848V44.5685h-37.91Z"
|
||||||
fill="#F6FAFB"
|
:fill="base100Hex"
|
||||||
/>
|
/>
|
||||||
</g>
|
</g>
|
||||||
<g clip-path="url(#E)">
|
<g clip-path="url(#E)">
|
||||||
<path
|
<path
|
||||||
d="M1335.69-31.24v75.8085h-45.49V14.2451c0-5.97318 1.18-11.88788 3.47-17.40639 2.28-5.5185 5.63-10.53271 9.86-14.75641 8.53-8.5301 20.1-13.3223 32.16-13.3223Z"
|
d="M1335.69-31.24v75.8085h-45.49V14.2451c0-5.97318 1.18-11.88788 3.47-17.40639 2.28-5.5185 5.63-10.53271 9.86-14.75641 8.53-8.5301 20.1-13.3223 32.16-13.3223Z"
|
||||||
fill="#507B5D"
|
:fill="primaryHex"
|
||||||
/>
|
/>
|
||||||
<path
|
<path
|
||||||
d="M1275.19 15.7939c-3.39 0-6.15 2.7522-6.15 6.1473 0 3.3951 2.76 6.1473 6.15 6.1473 3.4 0 6.15-2.7522 6.15-6.1473 0-3.3951-2.75-6.1473-6.15-6.1473Z"
|
d="M1275.19 15.7939c-3.39 0-6.15 2.7522-6.15 6.1473 0 3.3951 2.76 6.1473 6.15 6.1473 3.4 0 6.15-2.7522 6.15-6.1473 0-3.3951-2.75-6.1473-6.15-6.1473Z"
|
||||||
|
@ -207,7 +245,7 @@
|
||||||
<g clip-path="url(#F)">
|
<g clip-path="url(#F)">
|
||||||
<path
|
<path
|
||||||
d="M292.808-31v75.8085h-45.485V14.4851c0-5.97316 1.177-11.88786 3.463-17.40636 2.286-5.51851 5.636-10.53274 9.86-14.75644C269.176-26.2078 280.745-31 292.808-31Z"
|
d="M292.808-31v75.8085h-45.485V14.4851c0-5.97316 1.177-11.88786 3.463-17.40636 2.286-5.51851 5.636-10.53274 9.86-14.75644C269.176-26.2078 280.745-31 292.808-31Z"
|
||||||
fill="#507B5D"
|
:fill="primaryHex"
|
||||||
/>
|
/>
|
||||||
<path
|
<path
|
||||||
d="M232.31 16.0339c-3.395 0-6.147 2.7522-6.147 6.1473 0 3.3951 2.752 6.1473 6.147 6.1473 3.395 0 6.148-2.7522 6.148-6.1473 0-3.3951-2.753-6.1473-6.148-6.1473Z"
|
d="M232.31 16.0339c-3.395 0-6.147 2.7522-6.147 6.1473 0 3.3951 2.752 6.1473 6.147 6.1473 3.395 0 6.148-2.7522 6.148-6.1473 0-3.3951-2.753-6.1473-6.148-6.1473Z"
|
||||||
|
|
90
frontend/components/App/ImportDialog.vue
Normal file
90
frontend/components/App/ImportDialog.vue
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
<template>
|
||||||
|
<BaseModal v-model="dialog">
|
||||||
|
<template #title> Import CSV File </template>
|
||||||
|
<p>
|
||||||
|
Import a CSV file containing your items, labels, and locations. See documentation for more information on the
|
||||||
|
required format.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<form @submit.prevent="submitCsvFile">
|
||||||
|
<div class="flex flex-col gap-2 py-6">
|
||||||
|
<input ref="importRef" type="file" class="hidden" accept=".csv,.tsv" @change="setFile" />
|
||||||
|
|
||||||
|
<BaseButton type="button" @click="uploadCsv">
|
||||||
|
<Icon class="h-5 w-5 mr-2" name="mdi-upload" />
|
||||||
|
Upload
|
||||||
|
</BaseButton>
|
||||||
|
<p class="text-center pt-4 -mb-5">
|
||||||
|
{{ importCsv?.name }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-action">
|
||||||
|
<BaseButton type="submit" :disabled="!importCsv"> Submit </BaseButton>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</BaseModal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
type Props = {
|
||||||
|
modelValue: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
modelValue: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(["update:modelValue"]);
|
||||||
|
|
||||||
|
const dialog = useVModel(props, "modelValue", emit);
|
||||||
|
|
||||||
|
const api = useUserApi();
|
||||||
|
const toast = useNotifier();
|
||||||
|
|
||||||
|
const importCsv = ref<File | null>(null);
|
||||||
|
const importLoading = ref(false);
|
||||||
|
const importRef = ref<HTMLInputElement>();
|
||||||
|
whenever(
|
||||||
|
() => !dialog.value,
|
||||||
|
() => {
|
||||||
|
importCsv.value = null;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
function setFile(e: Event) {
|
||||||
|
importCsv.value = e.target.files[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
function uploadCsv() {
|
||||||
|
importRef.value.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
const eventBus = useEventBus();
|
||||||
|
|
||||||
|
async function submitCsvFile() {
|
||||||
|
if (!importCsv.value) {
|
||||||
|
toast.error("Please select a file to import.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
importLoading.value = true;
|
||||||
|
|
||||||
|
const { error } = await api.items.import(importCsv.value);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
toast.error("Import failed. Please try again later.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset
|
||||||
|
dialog.value = false;
|
||||||
|
importLoading.value = false;
|
||||||
|
importCsv.value = null;
|
||||||
|
|
||||||
|
if (importRef.value) {
|
||||||
|
importRef.value.value = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
eventBus.emit(EventTypes.ClearStores);
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="card bg-white shadow-xl sm:rounded-lg">
|
<div class="card bg-base-100 shadow-xl sm:rounded-lg">
|
||||||
<div v-if="$slots.title" class="px-4 py-5 sm:px-6">
|
<div v-if="$slots.title" class="px-4 py-5 sm:px-6">
|
||||||
<h3 class="text-lg font-medium leading-6">
|
<h3 class="text-lg font-medium leading-6">
|
||||||
<slot name="title"></slot>
|
<slot name="title"></slot>
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
<template>
|
<template>
|
||||||
<NuxtLink
|
<NuxtLink
|
||||||
ref="badge"
|
ref="badge"
|
||||||
class="badge badge-secondary"
|
class="badge badge-secondary text-secondary-content"
|
||||||
:class="{
|
:class="{
|
||||||
'badge-lg p-4': size === 'lg',
|
'badge-lg p-4': size === 'lg',
|
||||||
'p-3': size !== 'sm' && size !== 'lg',
|
'p-3': size !== 'sm' && size !== 'lg',
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<NuxtLink
|
<NuxtLink
|
||||||
ref="card"
|
ref="card"
|
||||||
:to="`/location/${location.id}`"
|
:to="`/location/${location.id}`"
|
||||||
class="card bg-white text-neutral rounded-md transition duration-300 shadow-md"
|
class="card bg-base-100 text-base-content rounded-md transition duration-300 shadow-md"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="card-body"
|
class="card-body"
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
<span class="mx-auto">
|
<span class="mx-auto">
|
||||||
{{ location.name }}
|
{{ location.name }}
|
||||||
</span>
|
</span>
|
||||||
<span v-if="hasCount" class="badge badge-primary h-6 w-6 badge-lg"> {{ count }}</span>
|
<span v-if="hasCount" class="badge badge-primary h-6 badge-lg"> {{ count }}</span>
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
<td
|
<td
|
||||||
v-for="h in headers"
|
v-for="h in headers"
|
||||||
:key="`${h.value}-${i}`"
|
:key="`${h.value}-${i}`"
|
||||||
class="bg-white"
|
class="bg-base-100"
|
||||||
:class="{
|
:class="{
|
||||||
'text-center': h.align === 'center',
|
'text-center': h.align === 'center',
|
||||||
'text-right': h.align === 'right',
|
'text-right': h.align === 'right',
|
||||||
|
|
|
@ -1,9 +1,19 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
|
<!--
|
||||||
|
Confirmation Modal is a singleton used by all components so we render
|
||||||
|
it here to ensure it's always available. Possibly could move this further
|
||||||
|
up the tree
|
||||||
|
-->
|
||||||
|
<ModalConfirm />
|
||||||
|
<AppImportDialog v-model="modals.import" />
|
||||||
|
<ItemCreateModal v-model="modals.item" />
|
||||||
|
<LabelCreateModal v-model="modals.label" />
|
||||||
|
<LocationCreateModal v-model="modals.location" />
|
||||||
<AppToast />
|
<AppToast />
|
||||||
<div class="drawer drawer-mobile">
|
<div class="drawer drawer-mobile">
|
||||||
<input id="my-drawer-2" type="checkbox" class="drawer-toggle" />
|
<input id="my-drawer-2" type="checkbox" class="drawer-toggle" />
|
||||||
<div class="drawer-content justify-center">
|
<div class="drawer-content justify-center bg-base-300">
|
||||||
<AppHeaderDecor class="-mt-10" />
|
<AppHeaderDecor class="-mt-10" />
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
|
|
||||||
|
@ -12,7 +22,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Sidebar -->
|
<!-- Sidebar -->
|
||||||
<div class="drawer-side shadow-lg w-60 flex flex-col justify-center py-10" style="background: white">
|
<div class="drawer-side overflow-visible shadow-lg w-60 flex flex-col justify-center bg-base-200 py-10">
|
||||||
<label for="my-drawer-2" class="drawer-overlay"></label>
|
<label for="my-drawer-2" class="drawer-overlay"></label>
|
||||||
<!-- Top Section -->
|
<!-- Top Section -->
|
||||||
<div class="space-y-8">
|
<div class="space-y-8">
|
||||||
|
@ -26,25 +36,37 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<div class="mx-auto w-40 mb-6">
|
<div class="mx-auto w-40 mb-6">
|
||||||
<BaseButton class="btn-block btn-primary text-xl">
|
<div class="dropdown overflow visible w-40">
|
||||||
<template #icon>
|
<label tabindex="0" class="btn btn-primary btn-block text-lg text-no-transform">
|
||||||
<Icon name="mdi-plus-circle" class="h-6 w-6" />
|
<span>
|
||||||
</template>
|
<Icon name="mdi-plus" class="mr-1 -ml-1" />
|
||||||
Create
|
|
||||||
</BaseButton>
|
|
||||||
</div>
|
|
||||||
<ul class="flex flex-col mx-auto gap-y-8">
|
|
||||||
<li v-for="n in nav" :key="n.id" class="text-xl">
|
|
||||||
<NuxtLink v-if="n.to" :to="n.to">
|
|
||||||
<span class="mr-4">
|
|
||||||
<Icon :name="n.icon" class="h-5 w-5" />
|
|
||||||
</span>
|
</span>
|
||||||
|
Create
|
||||||
|
</label>
|
||||||
|
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-40">
|
||||||
|
<li v-for="btn in dropdown" :key="btn.name">
|
||||||
|
<button @click="btn.action">
|
||||||
|
{{ btn.name }}
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ul class="flex flex-col mx-auto gap-2 w-40 menu">
|
||||||
|
<li v-for="n in nav" :key="n.id" class="text-xl">
|
||||||
|
<NuxtLink
|
||||||
|
v-if="n.to"
|
||||||
|
class="rounded-btn"
|
||||||
|
:to="n.to"
|
||||||
|
:class="{
|
||||||
|
'bg-secondary text-secondary-content': n.active?.value,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<Icon :name="n.icon" class="h-6 w-6 mr-4" />
|
||||||
{{ n.name }}
|
{{ n.name }}
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
<button v-else @click="n.action">
|
<button v-else class="rounded-btn" @click="n.action">
|
||||||
<span class="mr-4">
|
<Icon :name="n.icon" class="h-6 w-6 mr-4" />
|
||||||
<Icon :name="n.icon" class="h-5 w-5" />
|
|
||||||
</span>
|
|
||||||
{{ n.name }}
|
{{ n.name }}
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
|
@ -52,32 +74,67 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!-- Bottom -->
|
<!-- Bottom -->
|
||||||
<button class="mt-auto mb-6">Sign Out</button>
|
<button class="mt-auto mb-6" @click="logout">Sign Out</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import { useAuthStore } from "~~/stores/auth";
|
||||||
import { useLabelStore } from "~~/stores/labels";
|
import { useLabelStore } from "~~/stores/labels";
|
||||||
import { useLocationStore } from "~~/stores/locations";
|
import { useLocationStore } from "~~/stores/locations";
|
||||||
|
|
||||||
/**
|
const modals = reactive({
|
||||||
* Store Provider Initialization
|
item: false,
|
||||||
*/
|
location: false,
|
||||||
|
label: false,
|
||||||
|
import: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const dropdown = [
|
||||||
|
{
|
||||||
|
name: "Item / Asset",
|
||||||
|
action: () => {
|
||||||
|
modals.item = true;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Location",
|
||||||
|
action: () => {
|
||||||
|
modals.location = true;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Label",
|
||||||
|
action: () => {
|
||||||
|
modals.label = true;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
|
||||||
const nav = [
|
const nav = [
|
||||||
|
{
|
||||||
|
icon: "mdi-home",
|
||||||
|
active: computed(() => route.path === "/home"),
|
||||||
|
id: 0,
|
||||||
|
name: "Home",
|
||||||
|
to: "/home",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
icon: "mdi-account",
|
icon: "mdi-account",
|
||||||
id: 1,
|
id: 1,
|
||||||
|
active: computed(() => route.path === "/profile"),
|
||||||
name: "Profile",
|
name: "Profile",
|
||||||
to: "/profile",
|
to: "/profile",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: "mdi-document",
|
icon: "mdi-document",
|
||||||
id: 3,
|
id: 3,
|
||||||
|
active: computed(() => route.path === "/items"),
|
||||||
name: "Items",
|
name: "Items",
|
||||||
to: "/items",
|
to: "/items",
|
||||||
},
|
},
|
||||||
|
@ -85,14 +142,18 @@
|
||||||
icon: "mdi-database",
|
icon: "mdi-database",
|
||||||
id: 2,
|
id: 2,
|
||||||
name: "Import",
|
name: "Import",
|
||||||
action: () => {},
|
action: () => {
|
||||||
},
|
modals.import = true;
|
||||||
{
|
},
|
||||||
icon: "mdi-database-export",
|
|
||||||
id: 5,
|
|
||||||
name: "Export",
|
|
||||||
action: () => {},
|
|
||||||
},
|
},
|
||||||
|
// {
|
||||||
|
// icon: "mdi-database-export",
|
||||||
|
// id: 5,
|
||||||
|
// name: "Export",
|
||||||
|
// action: () => {
|
||||||
|
// console.log("Export");
|
||||||
|
// },
|
||||||
|
// },
|
||||||
];
|
];
|
||||||
|
|
||||||
const labelStore = useLabelStore();
|
const labelStore = useLabelStore();
|
||||||
|
@ -134,4 +195,16 @@
|
||||||
rmLocationStoreObserver();
|
rmLocationStoreObserver();
|
||||||
eventBus.off(EventTypes.ClearStores, "stores");
|
eventBus.off(EventTypes.ClearStores, "stores");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const authStore = useAuthStore();
|
||||||
|
const api = useUserApi();
|
||||||
|
|
||||||
|
async function logout() {
|
||||||
|
const { error } = await authStore.logout(api);
|
||||||
|
if (error) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
navigateTo("/");
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -24,57 +24,6 @@
|
||||||
const itemTable = itemsTable(api);
|
const itemTable = itemsTable(api);
|
||||||
const stats = statCardData(api);
|
const stats = statCardData(api);
|
||||||
|
|
||||||
// const importDialog = ref(false);
|
|
||||||
// const importCsv = ref(null);
|
|
||||||
// const importLoading = ref(false);
|
|
||||||
// const importRef = ref<HTMLInputElement>();
|
|
||||||
// whenever(
|
|
||||||
// () => !importDialog.value,
|
|
||||||
// () => {
|
|
||||||
// importCsv.value = null;
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
|
|
||||||
// function setFile(e: Event & { target: HTMLInputElement }) {
|
|
||||||
// importCsv.value = e.target.files[0];
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function openDialog() {
|
|
||||||
// importDialog.value = true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function uploadCsv() {
|
|
||||||
// importRef.value.click();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const eventBus = useEventBus();
|
|
||||||
|
|
||||||
// async function submitCsvFile() {
|
|
||||||
// if (!importCsv.value) {
|
|
||||||
// toast.error("Please select a file to import.");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// importLoading.value = true;
|
|
||||||
|
|
||||||
// const { error } = await api.items.import(importCsv.value);
|
|
||||||
|
|
||||||
// if (error) {
|
|
||||||
// toast.error("Import failed. Please try again later.");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Reset
|
|
||||||
// importDialog.value = false;
|
|
||||||
// importLoading.value = false;
|
|
||||||
// importCsv.value = null;
|
|
||||||
|
|
||||||
// if (importRef.value) {
|
|
||||||
// importRef.value.value = "";
|
|
||||||
// }
|
|
||||||
|
|
||||||
// eventBus.emit(EventTypes.ClearStores);
|
|
||||||
// }
|
|
||||||
|
|
||||||
const purchasePriceOverTime = purchasePriceOverTimeChart(api);
|
const purchasePriceOverTime = purchasePriceOverTimeChart(api);
|
||||||
|
|
||||||
const inventoryByLocation = inventoryByLocationChart(api);
|
const inventoryByLocation = inventoryByLocationChart(api);
|
||||||
|
|
|
@ -344,7 +344,7 @@
|
||||||
</div>
|
</div>
|
||||||
</dialog>
|
</dialog>
|
||||||
<section class="px-3">
|
<section class="px-3">
|
||||||
<div class="space-y-3">
|
<div class="space-y-6">
|
||||||
<BaseCard>
|
<BaseCard>
|
||||||
<template #title>
|
<template #title>
|
||||||
<BaseSectionHeader>
|
<BaseSectionHeader>
|
||||||
|
@ -410,7 +410,7 @@
|
||||||
</BaseCard>
|
</BaseCard>
|
||||||
|
|
||||||
<NuxtPage :item="item" :page-key="itemId" />
|
<NuxtPage :item="item" :page-key="itemId" />
|
||||||
<div v-if="!hasNested">
|
<template v-if="!hasNested">
|
||||||
<BaseCard v-if="photos && photos.length > 0">
|
<BaseCard v-if="photos && photos.length > 0">
|
||||||
<template #title> Photos </template>
|
<template #title> Photos </template>
|
||||||
<div
|
<div
|
||||||
|
@ -470,7 +470,7 @@
|
||||||
<template #title> Sold Details </template>
|
<template #title> Sold Details </template>
|
||||||
<DetailsSection :details="soldDetails" />
|
<DetailsSection :details="soldDetails" />
|
||||||
</BaseCard>
|
</BaseCard>
|
||||||
</div>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
|
@ -21,14 +21,12 @@
|
||||||
{
|
{
|
||||||
id: "total",
|
id: "total",
|
||||||
title: "Total Cost",
|
title: "Total Cost",
|
||||||
subtitle: "Sum over all entries",
|
value: log.value.costTotal,
|
||||||
value: fmtCurrency(log.value.costTotal),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "average",
|
id: "average",
|
||||||
title: "Monthly Average",
|
title: "Monthly Average",
|
||||||
subtitle: "Average over all entries",
|
value: log.value.costAverage,
|
||||||
value: fmtCurrency(log.value.costAverage),
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
@ -138,13 +136,14 @@
|
||||||
</BaseCard>
|
</BaseCard>
|
||||||
</div>
|
</div>
|
||||||
<div class="side-slot space-y-6">
|
<div class="side-slot space-y-6">
|
||||||
<div v-for="stat in stats" :key="stat.id" class="stats block shadow-xl border-l-primary">
|
<StatCard
|
||||||
<div class="stat">
|
v-for="stat in stats"
|
||||||
<div class="stat-title">{{ stat.title }}</div>
|
:key="stat.id"
|
||||||
<div class="stat-value text-primary">{{ stat.value }}</div>
|
class="stats block shadow-xl border-l-primary"
|
||||||
<div class="stat-desc">{{ stat.subtitle }}</div>
|
:title="stat.title"
|
||||||
</div>
|
:value="stat.value"
|
||||||
</div>
|
type="currency"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -12,7 +12,7 @@ module.exports = {
|
||||||
secondary: "#ECF4E7",
|
secondary: "#ECF4E7",
|
||||||
accent: "#FFDA56",
|
accent: "#FFDA56",
|
||||||
neutral: "#2C2E27",
|
neutral: "#2C2E27",
|
||||||
"base-100": "#F6FAFB",
|
"base-100": "#FFFFFF",
|
||||||
info: "#3ABFF8",
|
info: "#3ABFF8",
|
||||||
success: "#36D399",
|
success: "#36D399",
|
||||||
warning: "#FBBD23",
|
warning: "#FBBD23",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue