mirror of
https://github.com/sysadminsmedia/homebox.git
synced 2025-12-24 06:28:34 +01:00
* feat: begin upgrading deps, still very buggy * feat: progress * feat: sort all type issues * fix: sort type issues * fix: import sonner styles * fix: nuxt is the enemy * fix: try sorting issue with workflows * fix: update vitest config for dynamic import of path and defineConfig * fix: add missing import * fix: add time out to try and fix issues * fix: add ui:ci:preview task for frontend build in CI mode * fix: i was silly * feat: add go:ci:with-frontend task for CI mode and remove ui:ci:preview from e2e workflow * fix: update baseURL in Playwright config for local testing to use port 7745 * fix: update E2E_BASE_URL and remove wait for timeout in login test for smoother execution
78 lines
2.8 KiB
Vue
78 lines
2.8 KiB
Vue
<script setup lang="ts">
|
|
import { useI18n } from "vue-i18n";
|
|
import { statCardData } from "./statistics";
|
|
import { itemsTable } from "./table";
|
|
import { useLabelStore } from "~~/stores/labels";
|
|
import { useLocationStore } from "~~/stores/locations";
|
|
import BaseContainer from "@/components/Base/Container.vue";
|
|
import BaseCard from "@/components/Base/Card.vue";
|
|
import Subtitle from "~/components/global/Subtitle.vue";
|
|
import StatCard from "~/components/global/StatCard/StatCard.vue";
|
|
import ItemViewTable from "~/components/Item/View/Table.vue";
|
|
import ItemCard from "~/components/Item/Card.vue";
|
|
import LocationCard from "~/components/Location/Card.vue";
|
|
import LabelChip from "~/components/Label/Chip.vue";
|
|
|
|
const { t } = useI18n();
|
|
|
|
definePageMeta({
|
|
middleware: ["auth"],
|
|
});
|
|
useHead({
|
|
title: "HomeBox | " + t("menu.home"),
|
|
});
|
|
|
|
const api = useUserApi();
|
|
const breakpoints = useBreakpoints();
|
|
|
|
const locationStore = useLocationStore();
|
|
const locations = computed(() => locationStore.parentLocations);
|
|
|
|
const labelsStore = useLabelStore();
|
|
const labels = computed(() => labelsStore.labels);
|
|
|
|
const itemTable = itemsTable(api);
|
|
const stats = statCardData(api);
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<BaseContainer class="flex flex-col gap-4">
|
|
<section>
|
|
<Subtitle> {{ $t("home.quick_statistics") }} </Subtitle>
|
|
<div class="grid grid-cols-2 gap-2 md:grid-cols-4 md:gap-6">
|
|
<StatCard v-for="(stat, i) in stats" :key="i" :title="stat.label" :value="stat.value" :type="stat.type" />
|
|
</div>
|
|
</section>
|
|
|
|
<section>
|
|
<Subtitle> {{ $t("home.recently_added") }} </Subtitle>
|
|
|
|
<p v-if="itemTable.items.length === 0" class="ml-2 text-sm">{{ $t("items.no_results") }}</p>
|
|
<BaseCard v-else-if="breakpoints.lg">
|
|
<ItemViewTable :items="itemTable.items" disable-controls />
|
|
</BaseCard>
|
|
<div v-else class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
|
<ItemCard v-for="item in itemTable.items" :key="item.id" :item="item" />
|
|
</div>
|
|
</section>
|
|
|
|
<section>
|
|
<Subtitle> {{ $t("home.storage_locations") }} </Subtitle>
|
|
<p v-if="locations.length === 0" class="ml-2 text-sm">{{ $t("locations.no_results") }}</p>
|
|
<div v-else class="grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3">
|
|
<LocationCard v-for="location in locations" :key="location.id" :location="location" />
|
|
</div>
|
|
</section>
|
|
|
|
<section>
|
|
<Subtitle> {{ $t("home.labels") }} </Subtitle>
|
|
<p v-if="labels.length === 0" class="ml-2 text-sm">{{ $t("labels.no_results") }}</p>
|
|
<div v-else class="flex flex-wrap gap-4">
|
|
<LabelChip v-for="label in labels" :key="label.id" size="lg" :label="label" class="shadow-md" />
|
|
</div>
|
|
</section>
|
|
</BaseContainer>
|
|
</div>
|
|
</template>
|