astrbbbb / dashboard /src /components /shared /ItemCard.vue
qa1145's picture
Upload 1245 files
8ede856 verified
<template>
<v-card class="item-card hover-elevation" style="padding: 4px;" elevation="0">
<v-card-title class="d-flex justify-space-between align-center pb-1 pt-3">
<span class="text-h2 text-truncate" :title="getItemTitle()">{{ getItemTitle() }}</span>
<v-tooltip location="top">
<template v-slot:activator="{ props }">
<v-switch
color="primary"
hide-details
density="compact"
:model-value="getItemEnabled()"
:loading="loading"
:disabled="loading || disableToggle"
v-bind="props"
@update:model-value="toggleEnabled"
></v-switch>
</template>
<span>{{ getItemEnabled() ? t('core.common.itemCard.enabled') : t('core.common.itemCard.disabled') }}</span>
</v-tooltip>
</v-card-title>
<v-card-text>
<slot name="item-details" :item="item"></slot>
</v-card-text>
<v-card-actions style="margin: 8px;">
<v-btn
variant="outlined"
color="error"
size="small"
rounded="xl"
:disabled="loading || disableDelete"
@click="$emit('delete', item)"
>
{{ t('core.common.itemCard.delete') }}
</v-btn>
<v-btn
v-if="showEditButton"
variant="tonal"
color="primary"
size="small"
rounded="xl"
:disabled="loading"
@click="$emit('edit', item)"
>
{{ t('core.common.itemCard.edit') }}
</v-btn>
<v-btn
v-if="showCopyButton"
variant="tonal"
color="secondary"
size="small"
rounded="xl"
:disabled="loading"
@click="$emit('copy', item)"
>
{{ t('core.common.itemCard.copy') }}
</v-btn>
<slot name="actions" :item="item"></slot>
<v-spacer></v-spacer>
</v-card-actions>
<div class="d-flex justify-end align-center" style="position: absolute; bottom: 16px; right: 16px; opacity: 0.2;" v-if="bglogo">
<v-img
:src="bglogo"
contain
width="120"
height="120"
></v-img>
</div>
</v-card>
</template>
<script>
import { useI18n } from '@/i18n/composables';
export default {
name: 'ItemCard',
setup() {
const { t } = useI18n();
return { t };
},
props: {
item: {
type: Object,
required: true
},
titleField: {
type: String,
default: 'id'
},
enabledField: {
type: String,
default: 'enable'
},
bglogo: {
type: String,
default: null
},
loading: {
type: Boolean,
default: false
},
showCopyButton: {
type: Boolean,
default: false
},
showEditButton: {
type: Boolean,
default: true
},
disableToggle: {
type: Boolean,
default: false
},
disableDelete: {
type: Boolean,
default: false
}
},
emits: ['toggle-enabled', 'delete', 'edit', 'copy'],
methods: {
getItemTitle() {
return this.item[this.titleField];
},
getItemEnabled() {
return this.item[this.enabledField];
},
toggleEnabled() {
this.$emit('toggle-enabled', this.item);
}
}
}
</script>
<style scoped>
.item-card {
position: relative;
border-radius: 18px;
transition: all 0.3s ease;
overflow: hidden;
min-height: 220px;
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.hover-elevation:hover {
transform: translateY(-2px);
}
.item-status-indicator {
position: absolute;
top: 8px;
left: 8px;
width: 8px;
height: 8px;
border-radius: 50%;
background-color: #ccc;
z-index: 10;
}
.item-status-indicator.active {
background-color: #4caf50;
}
</style>