fix: remove external dependency for icones (#805)

* change all icons to use iconify

* fix minor UI elements

* fix layout of table
This commit is contained in:
Hayden 2024-02-29 19:20:18 -06:00 committed by GitHub
parent cf166ac641
commit f91b33db38
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
40 changed files with 303 additions and 183 deletions

View File

@ -111,8 +111,6 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
@ -122,8 +120,6 @@ github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJm
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/olahol/melody v1.1.4 h1:RQHfKZkQmDxI0+SLZRNBCn4LiXdqxLKRGSkT8Dyoe/E=
github.com/olahol/melody v1.1.4/go.mod h1:GgkTl6Y7yWj/HtfD48Q5vLKPVoZOH+Qqgfa7CvJgJM4=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU=
github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts=
github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
@ -141,10 +137,6 @@ github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0=
github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
@ -235,8 +227,6 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E=
modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E=
modernc.org/sqlite v1.29.1 h1:19GY2qvWB4VPw0HppFlZCPAbmxFU41r+qjKZQdQ1ryA=
modernc.org/sqlite v1.29.1/go.mod h1:hG41jCYxOAOoO6BRK66AdRlmOcDzXf7qnwlwjUIOqa0=
modernc.org/sqlite v1.29.2 h1:xgBSyA3gemwgP31PWFfFjtBorQNYpeypGdoSDjXhrgI=
modernc.org/sqlite v1.29.2/go.mod h1:hG41jCYxOAOoO6BRK66AdRlmOcDzXf7qnwlwjUIOqa0=
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=

View File

@ -1,4 +1,6 @@
<script lang="ts" setup>
import MdiPlus from "~icons/mdi/mdi-plus";
const ctx = useAuthContext();
const api = useUserApi();
@ -103,7 +105,7 @@
<div class="dropdown">
<label tabindex="0" class="btn btn-primary btn-sm">
<span>
<Icon name="mdi-plus" class="mr-1 -ml-1" />
<MdiPlus class="mr-1 -ml-1" />
</span>
Create
</label>

View File

@ -32,7 +32,7 @@
<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" />
<MdiUpload class="h-5 w-5 mr-2" />
Upload
</BaseButton>
<p class="text-center pt-4 -mb-5">
@ -48,6 +48,7 @@
</template>
<script setup lang="ts">
import MdiUpload from "~icons/mdi/upload";
type Props = {
modelValue: boolean;
};

View File

@ -14,14 +14,14 @@
>
<div class="flex gap-1">
<template v-if="notify.type == 'success'">
<Icon name="heroicons-check" class="h-5 w-5" />
<MdiCheckboxMarkedCircle class="h-5 w-5" />
</template>
<template v-if="notify.type == 'info'">
<Icon name="heroicons-information-circle" class="h-5 w-5" />
<MdiInformationSlabCircle class="h-5 w-5" />
</template>
<template v-if="notify.type == 'error'">
<Icon name="heroicons-bell-alert" class="h-5 w-5" />
<MdiAlert class="h-5 w-5" />
</template>
{{ notify.message }}
</div>
@ -31,6 +31,10 @@
</template>
<script setup lang="ts">
import MdiCheckboxMarkedCircle from "~icons/mdi/checkbox-marked-circle";
import MdiInformationSlabCircle from "~icons/mdi/information-slab-circle";
import MdiAlert from "~icons/mdi/alert";
import { useNotifications } from "@/composables/use-notifier";
const { notifications, dropNotification } = useNotifications();

View File

@ -1,14 +0,0 @@
<template>
<div class="divider">
<div class="btn-group min-w-[180px] flex-nowrap">
<button name="options" class="btn btn-sm btn-primary" @click="$emit('edit')">
<Icon name="heroicons-pencil" class="h-5 w-5 mr-1" aria-hidden="true" />
<span> Edit </span>
</button>
<button name="options" class="btn btn-sm btn-primary" @click="$emit('delete')">
<Icon name="heroicons-trash" class="h-5 w-5 mr-1" aria-hidden="true" />
<span> Delete </span>
</button>
</div>
</div>
</template>

View File

@ -6,8 +6,8 @@
<slot name="title"></slot>
<template v-if="collapsable">
<span class="ml-2 swap swap-rotate" :class="`${collapsed ? 'swap-active' : ''}`">
<Icon class="h-6 w-6 swap-on" name="mdi-chevron-right" />
<Icon class="h-6 w-6 swap-off" name="mdi-chevron-down" />
<MdiChevronRight class="h-6 w-6 swap-on" />
<MdiChevronDown class="h-6 w-6 swap-off" />
</span>
</template>
</h3>
@ -34,6 +34,9 @@
</template>
<script setup lang="ts">
import MdiChevronDown from "~icons/mdi/chevron-down";
import MdiChevronRight from "~icons/mdi/chevron-right";
defineProps<{
collapsable?: boolean;
}>();

View File

@ -1,7 +1,7 @@
<template>
<div class="pb-3">
<h3
class="text-3xl font-bold tracking-tight"
class="text-3xl font-bold tracking-tight flex items-center"
:class="{
'text-neutral-content': dark,
'text-content': !dark,

View File

@ -16,10 +16,10 @@
class="absolute inset-y-0 right-6 flex items-center rounded-r-md px-2 focus:outline-none"
@click="clear"
>
<Icon name="mdi-close" class="w-5 h-5" />
<MdiClose class="w-5 h-5" />
</button>
<ComboboxButton class="absolute inset-y-0 right-0 flex items-center rounded-r-md px-2 focus:outline-none">
<Icon name="mdi-chevron-down" class="w-5 h-5" />
<MdiChevronDown class="w-5 h-5" />
</ComboboxButton>
<ComboboxOptions
v-if="computedItems.length > 0"
@ -49,7 +49,7 @@
active ? 'text-primary-content' : 'bg-primary',
]"
>
<Icon name="mdi-check" class="h-5 w-5" aria-hidden="true" />
<MdiCheck class="h-5 w-5" aria-hidden="true" />
</span>
</slot>
</li>
@ -70,6 +70,9 @@
ComboboxButton,
ComboboxLabel,
} from "@headlessui/vue";
import MdiClose from "~icons/mdi/close";
import MdiChevronDown from "~icons/mdi/chevron-down";
import MdiCheck from "~icons/mdi/check";
type SupportValues = string | { [key: string]: any };

View File

@ -7,12 +7,14 @@
data-tip="Toggle Password Show"
@click="toggle()"
>
<Icon name="mdi-eye" class="h-5 w-5" />
<MdiEye name="mdi-eye" class="h-5 w-5" />
</button>
</div>
</template>
<script setup lang="ts">
import MdiEye from "~icons/mdi/eye";
type Props = {
modelValue: string;
placeholder?: string;

View File

@ -1,31 +0,0 @@
<script setup lang="ts">
import type { Ref } from "vue";
import type { IconifyIcon } from "@iconify/vue";
import { Icon as Iconify, loadIcon } from "@iconify/vue";
const nuxtApp = useNuxtApp();
const props = defineProps({
name: {
type: String,
required: true,
},
});
const icon: Ref<IconifyIcon | null> = ref(null);
const component = computed(() => nuxtApp.vueApp.component(props.name));
icon.value = await loadIcon(props.name).catch(() => null);
watch(
() => props.name,
async () => {
icon.value = await loadIcon(props.name).catch(() => null);
}
);
</script>
<template>
<Iconify v-if="icon" :icon="icon" class="inline-block" />
<Component :is="component" v-else-if="component" />
<span v-else>{{ name }}</span>
</template>

View File

@ -6,15 +6,15 @@
class="flex items-center justify-between py-3 pl-3 pr-4 text-sm"
>
<div class="flex w-0 flex-1 items-center">
<Icon name="mdi-paperclip" class="h-5 w-5 flex-shrink-0 text-gray-400" aria-hidden="true" />
<MdiPaperclip class="h-5 w-5 flex-shrink-0 text-gray-400" aria-hidden="true" />
<span class="ml-2 w-0 flex-1 truncate"> {{ attachment.document.title }}</span>
</div>
<div class="ml-4 flex-shrink-0">
<a class="tooltip mr-2" data-tip="Download" :href="attachmentURL(attachment.id)" target="_blank">
<Icon class="h-5 w-5" name="mdi-download" />
<MdiDownload class="h-5 w-5" />
</a>
<a class="tooltip" data-tip="Open" :href="attachmentURL(attachment.id)" target="_blank">
<Icon class="h-5 w-5" name="mdi-open-in-new" />
<MdiOpenInNew class="h-5 w-5" />
</a>
</div>
</li>
@ -23,6 +23,9 @@
<script setup lang="ts">
import { ItemAttachment } from "~~/lib/api/types/data-contracts";
import MdiPaperclip from "~icons/mdi/paperclip";
import MdiDownload from "~icons/mdi/download";
import MdiOpenInNew from "~icons/mdi/open-in-new";
const props = defineProps({
attachments: {

View File

@ -17,7 +17,7 @@
<div class="divider my-0"></div>
<div class="flex justify-between gap-2">
<div v-if="item.insured" class="tooltip z-10" data-tip="Insured">
<Icon class="h-5 w-5 text-primary" name="mdi-shield-check" />
<MdiShieldCheck class="h-5 w-5 text-primary" />
</div>
<div class="tooltip" data-tip="Quantity">
<span class="badge h-5 w-5 badge-primary badge-sm text-xs">
@ -35,6 +35,7 @@
<script setup lang="ts">
import { ItemOut, ItemSummary } from "~~/lib/api/types/data-contracts";
import MdiShieldCheck from "~icons/mdi/shield-check";
const api = useUserApi();

View File

@ -10,14 +10,14 @@
<div class="flex justify-center">
<BaseButton class="rounded-r-none" :loading="loading" type="submit">
<template #icon>
<Icon name="mdi-package-variant" class="swap-off h-5 w-5" />
<Icon name="mdi-package-variant-closed" class="swap-on h-5 w-5" />
<MdiPackageVariant class="swap-off h-5 w-5" />
<MdiPackageVariantClosed class="swap-on h-5 w-5" />
</template>
Create
</BaseButton>
<div class="dropdown dropdown-top">
<label tabindex="0" class="btn rounded-l-none rounded-r-xl">
<Icon class="h-5 w-5" name="mdi-chevron-down" />
<MdiChevronDown class="h-5 w-5" name="mdi-chevron-down" />
</label>
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-64 right-0">
<li>
@ -38,6 +38,9 @@
import { ItemCreate, LabelOut, LocationOut } from "~~/lib/api/types/data-contracts";
import { useLabelStore } from "~~/stores/labels";
import { useLocationStore } from "~~/stores/locations";
import MdiPackageVariant from "~icons/mdi/package-variant";
import MdiPackageVariantClosed from "~icons/mdi/package-variant-closed";
import MdiChevronDown from "~icons/mdi/chevron-down";
const props = defineProps({
modelValue: {

View File

@ -1,6 +1,9 @@
<script setup lang="ts">
import { ViewType } from "~~/composables/use-preferences";
import { ItemSummary } from "~~/lib/api/types/data-contracts";
import MdiDotsVertical from "~icons/mdi/dots-vertical";
import MdiCardTextOutline from "~icons/mdi/card-text-outline";
import MdiTable from "~icons/mdi/table";
type Props = {
view?: ViewType;
@ -30,18 +33,18 @@
<template #description>
<div v-if="!viewSet" class="dropdown dropdown-hover dropdown-left">
<label tabindex="0" class="btn btn-ghost m-1">
<Icon name="mdi-dots-vertical" class="h-7 w-7" />
<MdiDotsVertical class="h-7 w-7" />
</label>
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-32">
<li>
<button @click="setViewPreference('card')">
<Icon name="mdi-card-text-outline" class="h-5 w-5" />
<MdiCardTextOutline class="h-5 w-5" />
Card
</button>
</li>
<li>
<button @click="setViewPreference('table')">
<Icon name="mdi-table" class="h-5 w-5" />
<MdiTable class="h-5 w-5" />
Table
</button>
</li>

View File

@ -19,10 +19,13 @@
>
<template v-if="typeof h === 'string'">{{ h }}</template>
<template v-else>{{ h.text }}</template>
<div :class="`inline-flex ${sortByProperty === h.value ? '' : 'opacity-0'}`">
<div
v-if="sortByProperty === h.value"
:class="`inline-flex ${sortByProperty === h.value ? '' : 'opacity-0'}`"
>
<span class="swap swap-rotate" :class="{ 'swap-active': pagination.descending }">
<Icon name="mdi-arrow-down" class="swap-on h-5 w-5" />
<Icon name="mdi-arrow-up" class="swap-off h-5 w-5" />
<MdiArrowDown class="swap-on h-5 w-5" />
<MdiArrowUp class="swap-off h-5 w-5" />
</span>
</div>
</div>
@ -50,8 +53,8 @@
<Currency :amount="d.purchasePrice" />
</template>
<template v-else-if="cell(h) === 'cell-insured'">
<Icon v-if="d.insured" name="mdi-check" class="text-green-500 h-5 w-5" />
<Icon v-else name="mdi-close" class="text-red-500 h-5 w-5" />
<MdiCheck v-if="d.insured" class="text-green-500 h-5 w-5 inline" />
<MdiClose v-else class="text-red-500 h-5 w-5 inline" />
</template>
<slot v-else :name="cell(h)" v-bind="{ item: d }">
{{ extractValue(d, h.value) }}
@ -73,6 +76,10 @@
<script setup lang="ts">
import { TableData, TableHeader } from "./Table.types";
import { ItemSummary } from "~~/lib/api/types/data-contracts";
import MdiArrowDown from "~icons/mdi/arrow-down";
import MdiArrowUp from "~icons/mdi/arrow-up";
import MdiCheck from "~icons/mdi/check";
import MdiClose from "~icons/mdi/close";
type Props = {
items: ItemSummary[];

View File

@ -1,5 +1,7 @@
<script setup lang="ts">
import { LabelOut, LabelSummary } from "~~/lib/api/types/data-contracts";
import MdiArrowRight from "~icons/mdi/arrow-right";
import MdiTagOutline from "~icons/mdi/tag-outline";
export type sizes = "sm" | "md" | "lg" | "xl";
defineProps({
@ -32,8 +34,8 @@
:to="`/label/${label.id}`"
>
<label class="swap swap-rotate" :class="isActive ? 'swap-active' : ''">
<Icon name="heroicons-arrow-right" class="mr-2 swap-on"></Icon>
<Icon name="heroicons-tag" class="mr-2 swap-off"></Icon>
<MdiArrowRight class="mr-2 swap-on" />
<MdiTagOutline class="mr-2 swap-off" />
</label>
{{ label.name }}
</NuxtLink>

View File

@ -15,7 +15,7 @@
<BaseButton class="rounded-r-none" :loading="loading" type="submit"> Create </BaseButton>
<div class="dropdown dropdown-top">
<label tabindex="0" class="btn rounded-l-none rounded-r-xl">
<Icon class="h-5 w-5" name="mdi-chevron-down" />
<MdiChevronDown class="h-5 w-5" />
</label>
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-64 right-0">
<li>
@ -33,6 +33,7 @@
</template>
<script setup lang="ts">
import MdiChevronDown from "~icons/mdi/chevron-down";
const props = defineProps({
modelValue: {
type: Boolean,

View File

@ -13,18 +13,13 @@
>
<h2 class="flex items-center justify-between gap-2">
<label class="swap swap-rotate" :class="isActive ? 'swap-active' : ''">
<Icon name="heroicons-arrow-right" class="swap-on h-6 w-6" />
<Icon name="heroicons-map-pin" class="swap-off h-6 w-6" />
<MdiArrowRight class="swap-on h-6 w-6" />
<MdiMapMarkerOutline class="swap-off h-6 w-6" />
</label>
<span class="mx-auto">
{{ location.name }}
</span>
<span
class="badge badge-primary h-6 badge-lg"
:class="{
'opacity-0': !hasCount,
}"
>
<span class="badge badge-primary h-6 badge-lg" :class="{ 'opacity-0': !hasCount }">
{{ count }}
</span>
</h2>
@ -34,6 +29,8 @@
<script lang="ts" setup>
import { LocationOut, LocationOutCount, LocationSummary } from "~~/lib/api/types/data-contracts";
import MdiArrowRight from "~icons/mdi/arrow-right";
import MdiMapMarkerOutline from "~icons/mdi/map-marker-outline";
const props = defineProps({
location: {

View File

@ -16,7 +16,7 @@
<BaseButton class="rounded-r-none" type="submit" :loading="loading"> Create </BaseButton>
<div class="dropdown dropdown-top">
<label tabindex="0" class="btn rounded-l-none rounded-r-xl">
<Icon class="h-5 w-5" name="mdi-chevron-down" />
<MdiChevronDown class="h-5 w-5" />
</label>
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-64 right-0">
<li>
@ -35,6 +35,7 @@
<script setup lang="ts">
import { LocationSummary } from "~~/lib/api/types/data-contracts";
import MdiChevronDown from "~icons/mdi/chevron-down";
const props = defineProps({
modelValue: {
type: Boolean,

View File

@ -8,7 +8,7 @@
v-if="selected"
:class="['absolute inset-y-0 right-0 flex items-center pr-4', active ? 'text-white' : 'text-primary']"
>
<Icon name="mdi-check" class="h-5 w-5" aria-hidden="true" />
<MdiCheck class="h-5 w-5" aria-hidden="true" />
</span>
</div>
<div v-if="cast(item.value).name != cast(item.value).treeString" class="text-xs mt-1">
@ -22,6 +22,7 @@
<script lang="ts" setup>
import { FlatTreeItem, useFlatLocations } from "~~/composables/use-location-helpers";
import { LocationSummary } from "~~/lib/api/types/data-contracts";
import MdiCheck from "~icons/mdi/check";
type Props = {
modelValue?: LocationSummary | null;

View File

@ -1,6 +1,10 @@
<script setup lang="ts">
import { useTreeState } from "./tree-state";
import { TreeItem } from "~~/lib/api/types/data-contracts";
import MdiChevronDown from "~icons/mdi/chevron-down";
import MdiChevronRight from "~icons/mdi/chevron-right";
import MdiMapMarker from "~icons/mdi/map-marker";
import MdiPackageVariant from "~icons/mdi/package-variant";
type Props = {
treeId: string;
@ -56,12 +60,12 @@
'swap-active': openRef,
}"
>
<Icon name="mdi-chevron-right" class="h-6 w-6 swap-off" />
<Icon name="mdi-chevron-down" class="h-6 w-6 swap-on" />
<MdiChevronRight name="mdi-chevron-right" class="h-6 w-6 swap-off" />
<MdiChevronDown name="mdi-chevron-down" class="h-6 w-6 swap-on" />
</label>
</div>
<Icon v-if="item.type === 'location'" name="mdi-map-marker" class="h-4 w-4" />
<Icon v-else name="mdi-package-variant" class="h-4 w-4" />
<MdiMapMarker v-if="item.type === 'location'" class="h-4 w-4" />
<MdiPackageVariant v-else class="h-4 w-4" />
<NuxtLink class="hover:link text-lg" :to="link" @click.stop>{{ item.name }} </NuxtLink>
</div>
<div v-if="openRef" class="ml-4">

View File

@ -1,7 +1,7 @@
<template>
<div ref="el" class="dropdown" :class="{ 'dropdown-open': dropdownOpen }">
<button ref="btn" tabindex="0" class="btn btn-xs" @click="toggle">
{{ label }} {{ len }} <Icon name="mdi-chevron-down" class="h-4 w-4" />
{{ label }} {{ len }} <MdiChevronDown class="h-4 w-4" />
</button>
<div tabindex="0" class="dropdown-content mt-1 w-64 shadow bg-base-100 rounded-md">
<div class="pt-4 px-4 shadow-sm mb-1">
@ -39,6 +39,7 @@
</template>
<script setup lang="ts">
import MdiChevronDown from "~icons/mdi/chevron-down";
type Props = {
label: string;
options: any[];

View File

@ -6,17 +6,15 @@
'swap-active': copied,
}"
>
<Icon
<MdiContentCopy
class="swap-off"
name="mdi-content-copy"
:style="{
height: `${iconSize}px`,
width: `${iconSize}px`,
}"
/>
<Icon
<MdiClipboard
class="swap-on"
name="mdi-clipboard"
:style="{
height: `${iconSize}px`,
width: `${iconSize}px`,
@ -27,6 +25,9 @@
</template>
<script setup lang="ts">
import MdiContentCopy from "~icons/mdi/content-copy";
import MdiClipboard from "~icons/mdi/clipboard";
const props = defineProps({
text: {
type: String as () => string,
@ -51,5 +52,3 @@
}, 1000);
}
</script>
<style scoped></style>

View File

@ -16,7 +16,7 @@
<template v-else-if="detail.type === 'link'">
<div class="tooltip tooltip-primary tooltip-right" :data-tip="detail.href">
<a class="btn btn-primary btn-xs" :href="detail.href" target="_blank">
<Icon name="mdi-open-in-new" class="mr-2 swap-on"></Icon>
<MdiOpenInNew class="mr-2 swap-on" />
{{ detail.text }}
</a>
</div>
@ -51,6 +51,7 @@
<script setup lang="ts">
import type { AnyDetail, Detail } from "./types";
import MdiOpenInNew from "~icons/mdi/open-in-new";
defineProps({
details: {

View File

@ -2,7 +2,7 @@
<div class="dropdown dropdown-left">
<slot>
<label tabindex="0" class="btn btn-circle btn-sm">
<Icon name="mdi-qrcode" />
<MdiQrcode />
</label>
</slot>
<div tabindex="0" class="card compact dropdown-content shadow-lg bg-base-100 rounded-box w-64">
@ -16,6 +16,7 @@
<script setup lang="ts">
import { route } from "../../lib/api/base";
import MdiQrcode from "~icons/mdi/qrcode";
function getQRCodeUrl(): string {
const currentURL = window.location.href;

1
frontend/global.d.ts vendored Normal file
View File

@ -0,0 +1 @@
/// <reference types="unplugin-icons/types/vue" />

View File

@ -17,7 +17,7 @@
<!-- Button -->
<div class="navbar z-[99] lg:hidden top-0 fixed bg-primary shadow-md drawer-button">
<label for="my-drawer-2" class="btn btn-square btn-ghost text-base-100 drawer-button lg:hidden">
<Icon name="mdi-menu" class="h-6 w-6" />
<MdiMenu class="h-6 w-6" />
</label>
<NuxtLink to="/home">
<h2 class="text-3xl font-bold tracking-tight text-base-100 flex">
@ -51,7 +51,7 @@
<div class="dropdown overflow visible w-40">
<label tabindex="0" class="btn btn-primary btn-block text-lg text-no-transform">
<span>
<Icon name="mdi-plus" class="mr-1 -ml-1" />
<MdiPlus class="mr-1 -ml-1" />
</span>
Create
</label>
@ -74,7 +74,7 @@
'bg-secondary text-secondary-content': n.active?.value,
}"
>
<Icon :name="n.icon" class="h-6 w-6 mr-4" />
<component :is="n.icon" class="h-6 w-6 mr-4" />
{{ n.name }}
</NuxtLink>
</li>
@ -93,6 +93,14 @@
<script lang="ts" setup>
import { useLabelStore } from "~~/stores/labels";
import { useLocationStore } from "~~/stores/locations";
import MdiMenu from "~icons/mdi/menu";
import MdiPlus from "~icons/mdi/plus";
import MdiHome from "~icons/mdi/home";
import MdiFileTree from "~icons/mdi/file-tree";
import MdiMagnify from "~icons/mdi/magnify";
import MdiAccount from "~icons/mdi/account";
import MdiCog from "~icons/mdi/cog";
const username = computed(() => authCtx.user?.name || "User");
@ -138,35 +146,35 @@
const nav = [
{
icon: "mdi-home",
icon: MdiHome,
active: computed(() => route.path === "/home"),
id: 0,
name: "Home",
to: "/home",
},
{
icon: "mdi-file-tree",
icon: MdiFileTree,
id: 4,
active: computed(() => route.path === "/locations"),
name: "Locations",
to: "/locations",
},
{
icon: "mdi-magnify",
icon: MdiMagnify,
id: 3,
active: computed(() => route.path === "/items"),
name: "Search",
to: "/items",
},
{
icon: "mdi-account",
icon: MdiAccount,
id: 1,
active: computed(() => route.path === "/profile"),
name: "Profile",
to: "/profile",
},
{
icon: "mdi-cog",
icon: MdiCog,
id: 6,
active: computed(() => route.path === "/tools"),
name: "Tools",

View File

@ -3,7 +3,14 @@ import { defineNuxtConfig } from "nuxt/config";
// https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({
ssr: false,
modules: ["@nuxtjs/tailwindcss", "@pinia/nuxt", "@vueuse/nuxt", "@vite-pwa/nuxt", "./nuxt.proxyoverride.ts"],
modules: [
"@nuxtjs/tailwindcss",
"@pinia/nuxt",
"@vueuse/nuxt",
"@vite-pwa/nuxt",
"./nuxt.proxyoverride.ts",
"unplugin-icons/nuxt",
],
nitro: {
devProxy: {
"/api": {

View File

@ -15,6 +15,7 @@
},
"devDependencies": {
"@faker-js/faker": "^8.0.0",
"@iconify-json/mdi": "^1.1.64",
"@nuxtjs/eslint-config-typescript": "^12.0.0",
"@types/dompurify": "^3.0.0",
"@types/markdown-it": "^13.0.0",
@ -30,12 +31,12 @@
"nuxt": "3.6.5",
"prettier": "^2.7.1",
"typescript": "^5.0.0",
"unplugin-icons": "^0.18.5",
"vite-plugin-eslint": "^1.8.1",
"vitest": "^1.0.0"
},
"dependencies": {
"@headlessui/vue": "^1.7.9",
"@iconify/vue": "^3.2.1",
"@nuxtjs/tailwindcss": "^6.1.3",
"@pinia/nuxt": "^0.5.0",
"@tailwindcss/aspect-ratio": "^0.4.0",

View File

@ -1,4 +1,14 @@
<script setup lang="ts">
import MdiGithub from "~icons/mdi/github";
import MdiTwitter from "~icons/mdi/twitter";
import MdiDiscord from "~icons/mdi/discord";
import MdiFolder from "~icons/mdi/folder";
import MdiAccount from "~icons/mdi/account";
import MdiAccountPlus from "~icons/mdi/account-plus";
import MdiLogin from "~icons/mdi/login";
import MdiArrowRight from "~icons/mdi/arrow-right";
import MdiLock from "~icons/mdi/lock";
useHead({
title: "Homebox | Organize and Tag Your Stuff",
});
@ -141,16 +151,16 @@
</div>
<div class="flex mt-6 sm:mt-0 gap-4 ml-auto text-neutral-content">
<a class="tooltip" data-tip="Project Github" href="https://github.com/hay-kot/homebox" target="_blank">
<Icon name="mdi-github" class="h-8 w-8" />
<MdiGithub class="h-8 w-8" />
</a>
<a href="https://twitter.com/haybytes" class="tooltip" data-tip="Follow The Developer" target="_blank">
<Icon name="mdi-twitter" class="h-8 w-8" />
<MdiTwitter class="h-8 w-8" />
</a>
<a href="https://discord.gg/tuncmNrE4z" class="tooltip" data-tip="Join The Discord" target="_blank">
<Icon name="mdi-discord" class="h-8 w-8" />
<MdiDiscord class="h-8 w-8" />
</a>
<a href="https://hay-kot.github.io/homebox/" class="tooltip" data-tip="Read The Docs" target="_blank">
<Icon name="mdi-folder" class="h-8 w-8" />
<MdiFolder class="h-8 w-8" />
</a>
</div>
</header>
@ -161,7 +171,7 @@
<div class="card w-max-[500px] md:w-[500px] bg-base-100 shadow-xl">
<div class="card-body">
<h2 class="card-title text-2xl align-center">
<Icon name="heroicons-user" class="mr-1 w-7 h-7" />
<MdiAccount class="mr-1 w-7 h-7" />
Register
</h2>
<FormTextField v-model="email" label="Set your email?" />
@ -191,7 +201,7 @@
<div class="card w-max-[500px] md:w-[500px] bg-base-100 shadow-xl">
<div class="card-body">
<h2 class="card-title text-2xl align-center">
<Icon name="heroicons-user" class="mr-1 w-7 h-7" />
<MdiAccount class="mr-1 w-7 h-7" />
Login
</h2>
<template v-if="status && status.demo">
@ -225,14 +235,14 @@
@click="() => toggleLogin()"
>
<template #icon>
<Icon v-if="!registerForm" name="mdi-account-plus-outline" class="w-5 h-5 swap-off" />
<Icon v-else name="mdi-login" class="w-5 h-5 swap-off" />
<Icon name="mdi-arrow-right" class="w-5 h-5 swap-on" />
<MdiAccountPlus v-if="!registerForm" class="w-5 h-5 swap-off" />
<MdiLogin v-else class="w-5 h-5 swap-off" />
<MdiArrowRight class="w-5 h-5 swap-on" />
</template>
{{ registerForm ? "Login" : "Register" }}
</BaseButton>
<p v-else class="text-base-content italic text-sm inline-flex items-center gap-2">
<Icon name="mdi-lock" class="w-4 h-4 inline-block" />
<MdiLock class="w-4 h-4 inline-block" />
Registration Disabled
</p>
</div>

View File

@ -1,6 +1,11 @@
<script setup lang="ts">
import { AnyDetail, Detail, Details, filterZeroValues } from "~~/components/global/DetailsSection/types";
import { ItemAttachment } from "~~/lib/api/types/data-contracts";
import MdiClose from "~icons/mdi/close";
import MdiPackageVariant from "~icons/mdi/package-variant";
import MdiPlus from "~icons/mdi/plus";
import MdiMinus from "~icons/mdi/minus";
import MdiDownload from "~icons/mdi/download";
definePageMeta({
middleware: ["auth"],
@ -439,10 +444,10 @@
<div ref="refDialogBody" class="relative">
<div class="absolute right-0 -mt-3 -mr-3 sm:-mt-4 sm:-mr-4 space-x-1">
<a class="btn btn-sm sm:btn-md btn-primary btn-circle" :href="dialoged.src" download>
<Icon class="h-5 w-5" name="mdi-download" />
<MdiDownload class="h-5 w-5" />
</a>
<button class="btn btn-sm sm:btn-md btn-primary btn-circle" @click="closeDialog()">
<Icon class="h-5 w-5" name="mdi-close" />
<MdiClose class="h-5 w-5" />
</button>
</div>
@ -456,7 +461,7 @@
<div class="flex flex-wrap items-end gap-2">
<div class="avatar placeholder mb-auto">
<div class="bg-neutral-focus text-neutral-content rounded-full w-12">
<Icon name="mdi-package-variant" class="h-7 w-7" />
<MdiPackageVariant class="h-7 w-7" />
</div>
</div>
<div>
@ -525,10 +530,10 @@
class="opacity-0 group-hover:opacity-100 ml-4 my-0 duration-75 transition-opacity inline-flex gap-2"
>
<button class="btn btn-circle btn-xs" @click="adjustQuantity(-1)">
<Icon name="mdi-minus" class="h-3 w-3" />
<MdiMinus class="h-3 w-3" />
</button>
<button class="btn btn-circle btn-xs" @click="adjustQuantity(1)">
<Icon name="mdi-plus" class="h-3 w-3" />
<MdiPlus class="h-3 w-3" />
</button>
</span>
</template>

View File

@ -5,6 +5,9 @@
import { useLocationStore } from "~~/stores/locations";
import { capitalize } from "~~/lib/strings";
import Autocomplete from "~~/components/Form/Autocomplete.vue";
import MdiDelete from "~icons/mdi/delete";
import MdiPencil from "~icons/mdi/pencil";
import MdiContentSaveOutline from "~icons/mdi/content-save-outline";
definePageMeta({
middleware: ["auth"],
@ -445,12 +448,12 @@
</div>
<BaseButton size="sm" @click="saveItem">
<template #icon>
<Icon name="mdi-content-save-outline" />
<MdiContentSaveOutline />
</template>
Save
</BaseButton>
<BaseButton class="btn btn-sm btn-error" @click="deleteItem()">
<Icon name="mdi-delete" class="mr-2" />
<MdiDelete class="mr-2" />
Delete
</BaseButton>
</div>
@ -522,7 +525,7 @@
<FormTextField v-model="field.textValue" label="Value" />
<div class="tooltip" data-tip="Delete">
<button class="btn btn-sm btn-square mb-2 ml-2" @click="item.fields.splice(idx, 1)">
<Icon name="mdi-delete" />
<MdiDelete />
</button>
</div>
</div>
@ -576,12 +579,12 @@
<div class="flex gap-2 justify-end">
<div class="tooltip" data-tip="Delete">
<button class="btn btn-sm btn-square" @click="deleteAttachment(attachment.id)">
<Icon name="mdi-delete" />
<MdiDelete />
</button>
</div>
<div class="tooltip" data-tip="Edit">
<button class="btn btn-sm btn-square" @click="openAttachmentEditDialog(attachment)">
<Icon name="mdi-pencil" />
<MdiPencil />
</button>
</div>
</div>

View File

@ -2,6 +2,13 @@
import DatePicker from "~~/components/Form/DatePicker.vue";
import { StatsFormat } from "~~/components/global/StatCard/types";
import { ItemOut, MaintenanceEntry } from "~~/lib/api/types/data-contracts";
import MdiPost from "~icons/mdi/post";
import MdiPlus from "~icons/mdi/plus";
import MdiCheck from "~icons/mdi/check";
import MdiDelete from "~icons/mdi/delete";
import MdiEdit from "~icons/mdi/edit";
import MdiCalendar from "~icons/mdi/calendar";
import MdiWrenchClock from "~icons/mdi/wrench-clock";
const props = defineProps<{
item: ItemOut;
@ -184,7 +191,7 @@
<div class="py-2 flex justify-end">
<BaseButton type="submit" class="ml-2 mt-2">
<template #icon>
<Icon name="mdi-post" />
<MdiPost />
</template>
{{ entry.id ? "Update" : "Create" }}
</BaseButton>
@ -214,7 +221,7 @@
</div>
<BaseButton class="ml-auto" size="sm" @click="newEntry()">
<template #icon>
<Icon name="mdi-plus" />
<MdiPlus />
</template>
New
</BaseButton>
@ -228,11 +235,11 @@
<template #description>
<div class="flex flex-wrap gap-2">
<div v-if="validDate(e.completedDate)" class="badge p-3">
<Icon name="mdi-check" class="mr-2" />
<MdiCheck class="mr-2" />
<DateTime :date="e.completedDate" format="human" datetime-type="date" />
</div>
<div v-else-if="validDate(e.scheduledDate)" class="badge p-3">
<Icon name="mdi-calendar" class="mr-2" />
<MdiCalendar class="mr-2" />
<DateTime :date="e.scheduledDate" format="human" datetime-type="date" />
</div>
<div class="tooltip tooltip-primary" data-tip="Cost">
@ -249,13 +256,13 @@
<div class="flex justify-end p-4 gap-1">
<BaseButton size="sm" @click="openEditDialog(e)">
<template #icon>
<Icon name="mdi-edit" />
<MdiEdit />
</template>
Edit
</BaseButton>
<BaseButton size="sm" @click="deleteEntry(e.id)">
<template #icon>
<Icon name="mdi-delete" />
<MdiDelete />
</template>
Delete
</BaseButton>
@ -267,7 +274,7 @@
class="relative block w-full rounded-lg border-2 border-dashed border-base-content p-12 text-center"
@click="newEntry()"
>
<Icon name="mdi-wrench-clock" class="h-16 w-16"></Icon>
<MdiWrenchClock class="h-16 w-16 inline" />
<span class="mt-2 block text-sm font-medium text-gray-900"> Create Your First Entry </span>
</button>
</div>

View File

@ -2,6 +2,11 @@
import { ItemSummary, LabelSummary, LocationOutCount } from "~~/lib/api/types/data-contracts";
import { useLabelStore } from "~~/stores/labels";
import { useLocationStore } from "~~/stores/locations";
import MdiLoading from "~icons/mdi/loading";
import MdiMagnify from "~icons/mdi/magnify";
import MdiDelete from "~icons/mdi/delete";
import MdiChevronRight from "~icons/mdi/chevron-right";
import MdiChevronLeft from "~icons/mdi/chevron-left";
definePageMeta({
middleware: ["auth"],
@ -319,8 +324,8 @@
</div>
<BaseButton class="btn-block md:w-auto" @click.prevent="submit">
<template #icon>
<Icon v-if="loading" name="mdi-loading" class="animate-spin" />
<Icon v-else name="mdi-search" />
<MdiLoading v-if="loading" class="animate-spin" />
<MdiMagnify v-else />
</template>
Search
</BaseButton>
@ -408,7 +413,7 @@
class="btn btn-square btn-sm md:ml-0 ml-auto mt-auto mb-2"
@click="fieldTuples.splice(idx, 1)"
>
<Icon name="mdi-trash" class="w-5 h-5" />
<MdiDelete class="w-5 h-5" />
</button>
</div>
<BaseButton type="button" class="btn-sm mt-2" @click="() => fieldTuples.push(['', ''])"> Add</BaseButton>
@ -431,14 +436,14 @@
<div class="flex">
<div class="btn-group">
<button :disabled="!hasPrev" class="btn text-no-transform" @click="prev">
<Icon class="mr-1 h-6 w-6" name="mdi-chevron-left" />
<MdiChevronLeft class="mr-1 h-6 w-6" name="mdi-chevron-left" />
Prev
</button>
<button v-if="hasPrev" class="btn text-no-transform" @click="page = 1">First</button>
<button v-if="hasNext" class="btn text-no-transform" @click="page = totalPages">Last</button>
<button :disabled="!hasNext" class="btn text-no-transform" @click="next">
Next
<Icon class="ml-1 h-6 w-6" name="mdi-chevron-right" />
<MdiChevronRight class="ml-1 h-6 w-6" name="mdi-chevron-right" />
</button>
</div>
</div>

View File

@ -1,4 +1,8 @@
<script setup lang="ts">
import MdiPackageVariant from "~icons/mdi/package-variant";
import MdiPencil from "~icons/mdi/pencil";
import MdiDelete from "~icons/mdi/delete";
definePageMeta({
middleware: ["auth"],
});
@ -107,7 +111,7 @@
<div class="flex flex-wrap items-end gap-2">
<div class="avatar placeholder mb-auto">
<div class="bg-neutral-focus text-neutral-content rounded-full w-12">
<Icon name="mdi-package-variant" class="h-7 w-7" />
<MdiPackageVariant class="h-7 w-7" />
</div>
</div>
<div>
@ -125,12 +129,12 @@
<div class="btn-group">
<PageQRCode class="dropdown-left" />
<BaseButton size="sm" @click="openUpdate">
<Icon class="mr-1" name="mdi-pencil" />
<MdiPencil class="mr-1" />
Edit
</BaseButton>
</div>
<BaseButton class="btn btn-sm" @click="confirmDelete()">
<Icon name="mdi-delete" class="mr-2" />
<MdiDelete class="mr-2" />
Delete
</BaseButton>
</div>

View File

@ -1,6 +1,9 @@
<script setup lang="ts">
import { LocationSummary, LocationUpdate } from "~~/lib/api/types/data-contracts";
import { useLocationStore } from "~~/stores/locations";
import MdiPackageVariant from "~icons/mdi/package-variant";
import MdiPencil from "~icons/mdi/pencil";
import MdiDelete from "~icons/mdi/delete";
definePageMeta({
middleware: ["auth"],
@ -123,7 +126,7 @@
<div class="flex flex-wrap items-end gap-2">
<div class="avatar placeholder mb-auto">
<div class="bg-neutral-focus text-neutral-content rounded-full w-12">
<Icon name="mdi-package-variant" class="h-7 w-7" />
<MdiPackageVariant name="mdi-package-variant" class="h-7 w-7" />
</div>
</div>
<div>
@ -149,12 +152,12 @@
<div class="btn-group">
<PageQRCode class="dropdown-left" />
<BaseButton size="sm" @click="openUpdate">
<Icon class="mr-1" name="mdi-pencil" />
<MdiPencil class="mr-1" name="mdi-pencil" />
Edit
</BaseButton>
</div>
<BaseButton class="btn btn-sm" @click="confirmDelete()">
<Icon name="mdi-delete" class="mr-2" />
<MdiDelete name="mdi-delete" class="mr-2" />
Delete
</BaseButton>
</div>

View File

@ -1,5 +1,6 @@
<script setup lang="ts">
import { useTreeState } from "~~/components/Location/Tree/tree-state";
import MdiCollapseAllOutline from "~icons/mdi/collapse-all-outline";
definePageMeta({
middleware: ["auth"],
@ -67,7 +68,7 @@
<div class="flex justify-end mb-2">
<div class="btn-group">
<button class="btn btn-sm tooltip tooltip-top" data-tip="Collapse Tree" @click="closeAll">
<Icon name="mdi-collapse-all-outline" />
<MdiCollapseAllOutline />
</button>
</div>
</div>

View File

@ -2,6 +2,12 @@
import { Detail } from "~~/components/global/DetailsSection/types";
import { themes } from "~~/lib/data/themes";
import { CurrenciesCurrency, NotifierCreate, NotifierOut } from "~~/lib/api/types/data-contracts";
import MdiAccount from "~icons/mdi/account";
import MdiMegaphone from "~icons/mdi/megaphone";
import MdiDelete from "~icons/mdi/delete";
import MdiFill from "~icons/mdi/fill";
import MdiPencil from "~icons/mdi/pencil";
import MdiAccountMultiple from "~icons/mdi/account-multiple";
definePageMeta({
middleware: ["auth"],
@ -341,7 +347,7 @@
<BaseCard>
<template #title>
<BaseSectionHeader>
<Icon name="mdi-account" class="mr-2 -mt-1 text-base-600" />
<MdiAccount class="mr-2 -mt-1 text-base-600" />
<span class="text-base-600"> User Profile </span>
<template #description> Invite users, and manage your account. </template>
</BaseSectionHeader>
@ -368,7 +374,7 @@
<BaseCard>
<template #title>
<BaseSectionHeader>
<Icon name="mdi-megaphone" class="mr-2 -mt-1 text-base-600" />
<MdiMegaphone class="mr-2 -mt-1 text-base-600" />
<span class="text-base-600"> Notifiers </span>
<template #description> Get notifications for up coming maintenance reminders </template>
</BaseSectionHeader>
@ -381,12 +387,12 @@
<div class="flex gap-2 justify-end">
<div class="tooltip" data-tip="Delete">
<button class="btn btn-sm btn-square" @click="deleteNotifier(n.id)">
<Icon name="mdi-delete" />
<MdiDelete />
</button>
</div>
<div class="tooltip" data-tip="Edit">
<button class="btn btn-sm btn-square" @click="openNotifierDialog(n)">
<Icon name="mdi-pencil" />
<MdiPencil />
</button>
</div>
</div>
@ -412,7 +418,7 @@
<BaseCard>
<template #title>
<BaseSectionHeader class="pb-0">
<Icon name="mdi-accounts" class="mr-2 -mt-1 text-base-600" />
<MdiAccountMultiple class="mr-2 -mt-1 text-base-600" />
<span class="text-base-600"> Group Settings </span>
<template #description>
Shared Group Settings. You may need to refresh your browser for some settings to apply.
@ -433,7 +439,7 @@
<BaseCard>
<template #title>
<BaseSectionHeader>
<Icon name="mdi-fill" class="mr-2 text-base-600" />
<MdiFill class="mr-2 text-base-600" />
<span class="text-base-600"> Theme Settings </span>
<template #description>
Theme settings are stored in your browser's local storage. You can change the theme at any time. If you're
@ -484,7 +490,7 @@
<BaseCard>
<template #title>
<BaseSectionHeader>
<Icon name="mdi-delete" class="mr-2 -mt-1 text-base-600" />
<MdiDelete class="mr-2 -mt-1 text-base-600" />
<span class="text-base-600"> Delete Account</span>
<template #description> Delete your account and all its associated data. </template>
</BaseSectionHeader>

View File

@ -5,7 +5,7 @@
<BaseCard>
<template #title>
<BaseSectionHeader>
<Icon name="mdi-file-chart" class="mr-2 -mt-1" />
<MdiFileChart class="mr-2" />
<span> Reports </span>
<template #description> Generate different reports for your inventory. </template>
</BaseSectionHeader>
@ -17,7 +17,7 @@
are able to print labels ahead of time and apply them to your inventory when you receive them.
<template #button>
Label Generator
<Icon name="mdi-arrow-right" class="ml-2" />
<MdiArrowRight class="ml-2" />
</template>
</DetailAction>
<DetailAction @action="getBillOfMaterials()">
@ -31,7 +31,7 @@
<BaseCard>
<template #title>
<BaseSectionHeader>
<Icon name="mdi-database" class="mr-2 -mt-1" />
<MdiDatabase class="mr-2" />
<span> Import / Export </span>
<template #description>
Import and export your inventory to and from a CSV file. This is useful for migrating your inventory to a
@ -54,7 +54,7 @@
<BaseCard>
<template #title>
<BaseSectionHeader>
<Icon name="mdi-warning" class="mr-2 -mt-1" />
<MdiAlert class="mr-2" />
<span> Inventory Actions </span>
<template #description>
Apply Actions to your inventory in bulk. These are irreversible actions. <b>Be careful.</b>
@ -95,6 +95,11 @@
</template>
<script setup lang="ts">
import MdiFileChart from "~icons/mdi/file-chart";
import MdiArrowRight from "~icons/mdi/arrow-right";
import MdiDatabase from "~icons/mdi/database";
import MdiAlert from "~icons/mdi/alert";
definePageMeta({
middleware: ["auth"],
});

View File

@ -8,9 +8,6 @@ dependencies:
'@headlessui/vue':
specifier: ^1.7.9
version: 1.7.9(vue@3.3.4)
'@iconify/vue':
specifier: ^3.2.1
version: 3.2.1(vue@3.3.4)
'@nuxtjs/tailwindcss':
specifier: ^6.1.3
version: 6.1.3(rollup@2.79.1)(webpack@5.90.3)
@ -82,6 +79,9 @@ devDependencies:
'@faker-js/faker':
specifier: ^8.0.0
version: 8.0.0
'@iconify-json/mdi':
specifier: ^1.1.64
version: 1.1.64
'@nuxtjs/eslint-config-typescript':
specifier: ^12.0.0
version: 12.0.0(eslint@8.29.0)(typescript@5.0.2)
@ -124,6 +124,9 @@ devDependencies:
typescript:
specifier: ^5.0.0
version: 5.0.2
unplugin-icons:
specifier: ^0.18.5
version: 0.18.5
vite-plugin-eslint:
specifier: ^1.8.1
version: 1.8.1(eslint@8.29.0)(vite@5.1.4)
@ -148,6 +151,23 @@ packages:
'@jridgewell/trace-mapping': 0.3.23
dev: true
/@antfu/install-pkg@0.1.1:
resolution: {integrity: sha512-LyB/8+bSfa0DFGC06zpCEfs89/XoWZwws5ygEa5D+Xsm3OfI+aXQ86VgVG7Acyef+rSZ5HE7J8rrxzrQeM3PjQ==}
dependencies:
execa: 5.1.1
find-up: 5.0.0
dev: true
/@antfu/install-pkg@0.3.1:
resolution: {integrity: sha512-A3zWY9VeTPnxlMiZtsGHw2lSd3ghwvL8s9RiGOtqvDxhhFfZ781ynsGBa/iUnDJ5zBrmTFQrJDud3TGgRISaxw==}
dependencies:
execa: 8.0.1
dev: true
/@antfu/utils@0.7.7:
resolution: {integrity: sha512-gFPqTG7otEJ8uP6wrhDv6mqwGWYZKNvAcCq6u9hOj0c+IKCEsY4L1oC9trPq2SaWIzAfHvqfBDxF591JkMf+kg==}
dev: true
/@apideck/better-ajv-errors@0.3.6(ajv@8.12.0):
resolution: {integrity: sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==}
engines: {node: '>=10'}
@ -2440,13 +2460,29 @@ packages:
/@humanwhocodes/object-schema@1.2.1:
resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==}
/@iconify/vue@3.2.1(vue@3.3.4):
resolution: {integrity: sha512-c4R6ZgFo1JrJ8aPMMgOPgfU7lBswihMGR+yWe/P4ZukC3kTkeT4+lkt9Pc/itVFMkwva/S/7u9YofmYv57fnNQ==}
peerDependencies:
vue: 3.x
/@iconify-json/mdi@1.1.64:
resolution: {integrity: sha512-zGeo5TjhNFAY6FmSDBLAzDO811t77r6v/mDi7CAL9w5eXqKez6bIjk8R9AL/RHIeq44ALP4Ozr4lMqFTkHr7ug==}
dependencies:
vue: 3.3.4
dev: false
'@iconify/types': 2.0.0
dev: true
/@iconify/types@2.0.0:
resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
dev: true
/@iconify/utils@2.1.22:
resolution: {integrity: sha512-6UHVzTVXmvO8uS6xFF+L/QTSpTzA/JZxtgU+KYGFyDYMEObZ1bu/b5l+zNJjHy+0leWjHI+C0pXlzGvv3oXZMA==}
dependencies:
'@antfu/install-pkg': 0.1.1
'@antfu/utils': 0.7.7
'@iconify/types': 2.0.0
debug: 4.3.4
kolorist: 1.8.0
local-pkg: 0.5.0
mlly: 1.6.1
transitivePeerDependencies:
- supports-color
dev: true
/@ioredis/commands@1.2.0:
resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==}
@ -4389,7 +4425,7 @@ packages:
engines: {node: '>= 6'}
dependencies:
glob: 7.2.3
graceful-fs: 4.2.10
graceful-fs: 4.2.11
lazystream: 1.0.1
lodash.defaults: 4.2.0
lodash.difference: 4.5.0
@ -5548,7 +5584,7 @@ packages:
resolution: {integrity: sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==}
engines: {node: '>=6.9.0'}
dependencies:
graceful-fs: 4.2.10
graceful-fs: 4.2.11
memory-fs: 0.5.0
tapable: 1.1.3
@ -5564,7 +5600,7 @@ packages:
resolution: {integrity: sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==}
engines: {node: '>=10.13.0'}
dependencies:
graceful-fs: 4.2.10
graceful-fs: 4.2.11
tapable: 2.2.1
/enhanced-resolve@5.15.1:
@ -6794,7 +6830,6 @@ packages:
/graceful-fs@4.2.11:
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
dev: false
/grapheme-splitter@1.0.4:
resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==}
@ -7435,7 +7470,7 @@ packages:
dependencies:
universalify: 2.0.0
optionalDependencies:
graceful-fs: 4.2.10
graceful-fs: 4.2.11
/jsonpointer@5.0.1:
resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==}
@ -7524,6 +7559,10 @@ packages:
- supports-color
dev: false
/kolorist@1.8.0:
resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==}
dev: true
/lazystream@1.0.1:
resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==}
engines: {node: '>= 0.6.3'}
@ -10567,6 +10606,37 @@ packages:
resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==}
engines: {node: '>= 10.0.0'}
/unplugin-icons@0.18.5:
resolution: {integrity: sha512-KVNAohXbZ7tVcG1C3p6QaC7wU9Qrj7etv4XvsMMJAxr5LccQZ+Iuv5LOIv/7GtqXaGN1BuFCqRO1ErsHEgEXdQ==}
peerDependencies:
'@svgr/core': '>=7.0.0'
'@svgx/core': ^1.0.1
'@vue/compiler-sfc': ^3.0.2 || ^2.7.0
vue-template-compiler: ^2.6.12
vue-template-es2015-compiler: ^1.9.0
peerDependenciesMeta:
'@svgr/core':
optional: true
'@svgx/core':
optional: true
'@vue/compiler-sfc':
optional: true
vue-template-compiler:
optional: true
vue-template-es2015-compiler:
optional: true
dependencies:
'@antfu/install-pkg': 0.3.1
'@antfu/utils': 0.7.7
'@iconify/utils': 2.1.22
debug: 4.3.4
kolorist: 1.8.0
local-pkg: 0.5.0
unplugin: 1.7.1
transitivePeerDependencies:
- supports-color
dev: true
/unplugin-vue-router@0.6.4(rollup@2.79.1)(vue-router@4.2.4)(vue@3.3.4):
resolution: {integrity: sha512-9THVhhtbVFxbsIibjK59oPwMI1UCxRWRPX7azSkTUABsxovlOXJys5SJx0kd/0oKIqNJuYgkRfAgPuO77SqCOg==}
peerDependencies:
@ -11383,7 +11453,6 @@ packages:
/workbox-google-analytics@7.0.0:
resolution: {integrity: sha512-MEYM1JTn/qiC3DbpvP2BVhyIH+dV/5BjHk756u9VbwuAhu0QHyKscTnisQuz21lfRpOwiS9z4XdqeVAKol0bzg==}
deprecated: It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained
dependencies:
workbox-background-sync: 7.0.0
workbox-core: 7.0.0