homemanager-fe/src/components/item/StoredItemCard.vue

135 lines
4.0 KiB
Vue

<template>
<div class="flex justify-between">
<div class="flex space-x-2">
<div
:class="[
imageClasses,
'relative flex flex-shrink-0 items-center justify-center overflow-hidden rounded-md bg-gray-100 ring-1 ring-black ring-opacity-5',
]"
>
<img
class="object-contain"
v-if="storedItem.item.image"
:src="storedItem.item.image"
:alt="storedItem.item.displayName"
/>
<CubeIcon :class="iconClasses" />
</div>
<div class="-mt-1 flex flex-col">
<div class="flex flex-col md:flex-row md:items-center md:space-x-1">
<span :class="`text-${size} font-bold`">{{
storedItem.item.displayName
}}</span>
<span
:class="`md:mt-0.5 ${fontSize} text-gray-500`"
v-if="storedItem.addedBy"
><span class="hidden md:inline">· </span>Added
{{
dateToLocaleString(storedItem.acquiredAt || storedItem.createdAt)
}}
by {{ storedItem.addedBy.name }}</span
>
</div>
<div
:class="`flex items-center space-x-1 ${fontSize} text-gray-500`"
:title="`${ItemTypeName[storedItem.item.type]} - ${
ItemTypeDescription[storedItem.item.type]
}`"
>
<InformationCircleIcon class="h-4 w-4" />
<span>{{ ItemTypeName[storedItem.item.type] }}</span>
<span v-if="storedItem.item.consumable">· Consumable</span>
<span v-if="storedItem.consumedAt"
>· Consumed at {{ dateToLocaleString(storedItem.consumedAt) }}</span
>
</div>
<div
:class="[
'flex items-center space-x-1',
fontSize,
expiresSoon ? 'font-bold text-red-600' : '',
hasExpired ? 'uppercase' : '',
]"
v-if="storedItem.expiresAt"
>
<ExclamationTriangleIcon class="h-4 w-4" />
<span
>{{ hasExpired ? 'Expired' : 'Expires' }} at
{{ dateToLocaleString(storedItem.expiresAt) }}</span
>
</div>
<div
:class="`flex items-center space-x-1 ${fontSize} text-gray-500`"
title="Barcode"
v-if="storedItem.item.barcode"
>
<QrCodeIcon class="h-4 w-4" />
<span>{{ storedItem.item.barcode }}</span>
</div>
</div>
</div>
<div class="flex flex-col items-end">
<slot name="actions"></slot>
</div>
</div>
</template>
<script setup lang="ts">
import {
CubeIcon,
ExclamationTriangleIcon,
InformationCircleIcon,
QrCodeIcon,
} from '@heroicons/vue/24/outline';
import { computed } from 'vue';
import { ItemTypeDescription, ItemTypeName } from '../../enums/item-type.enum';
import { StoredItem } from '../../interfaces/storage.interfaces';
const props = defineProps<{
storedItem: StoredItem;
size?: 'sm' | 'md' | 'lg';
hideExtras?: boolean;
hideCost?: boolean;
}>();
const imageClasses = computed(() => {
if (props.size === 'sm') return 'h-8 w-8';
if (props.size === 'md') return 'h-12 w-12';
return 'sm:h-16 sm:w-16 h-8 w-8';
});
const iconClasses = computed(() => {
if (props.size === 'sm') return 'h-4 w-4';
if (props.size === 'md') return 'h-8 w-8';
return 'sm:h-12 sm:w-12 h-4 w-4';
});
const fontSize = computed(() => {
if (props.size === 'sm') return 'text-[0.75rem]';
return 'text-sm';
});
const expiresSoon = computed(
() =>
(!!props.storedItem.expiresAt &&
!props.storedItem.consumedAt &&
new Date(props.storedItem.expiresAt).getTime() <
Date.now() + 604800000) ??
false
);
const hasExpired = computed(
() =>
(!!props.storedItem.expiresAt &&
!props.storedItem.consumedAt &&
new Date(props.storedItem.expiresAt).getTime() < Date.now()) ??
false
);
const dateToLocaleString = (dateField: string) => {
const converted = new Date(dateField);
return `${converted.toLocaleString('en-UK')}`;
};
</script>