125 lines
2.7 KiB
Vue
125 lines
2.7 KiB
Vue
<script setup>
|
|
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
|
|
import { computed } from 'vue';
|
|
|
|
const props = defineProps({
|
|
icon: {
|
|
type: [String, Object, Array],
|
|
default: null,
|
|
},
|
|
title: {
|
|
type: String,
|
|
default: 'Ni podatkov',
|
|
},
|
|
description: {
|
|
type: String,
|
|
default: null,
|
|
},
|
|
action: {
|
|
type: Object,
|
|
default: null,
|
|
},
|
|
size: {
|
|
type: String,
|
|
default: 'md', // sm, md, lg
|
|
validator: (value) => ['sm', 'md', 'lg'].includes(value),
|
|
},
|
|
});
|
|
|
|
const sizeClasses = computed(() => {
|
|
const sizes = {
|
|
sm: {
|
|
icon: 'text-4xl',
|
|
title: 'text-base',
|
|
description: 'text-sm',
|
|
container: 'py-8',
|
|
},
|
|
md: {
|
|
icon: 'text-5xl',
|
|
title: 'text-lg',
|
|
description: 'text-sm',
|
|
container: 'py-12',
|
|
},
|
|
lg: {
|
|
icon: 'text-6xl',
|
|
title: 'text-xl',
|
|
description: 'text-base',
|
|
container: 'py-16',
|
|
},
|
|
};
|
|
return sizes[props.size];
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<div
|
|
class="flex flex-col items-center justify-center text-center"
|
|
:class="sizeClasses.container"
|
|
>
|
|
<!-- Icon -->
|
|
<div
|
|
v-if="icon"
|
|
class="mb-4 text-gray-400"
|
|
:class="sizeClasses.icon"
|
|
>
|
|
<FontAwesomeIcon :icon="icon" />
|
|
</div>
|
|
<!-- Default icon if none provided -->
|
|
<div
|
|
v-else
|
|
class="mb-4 text-gray-400"
|
|
:class="sizeClasses.icon"
|
|
>
|
|
<svg
|
|
class="mx-auto"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
>
|
|
<path
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
stroke-width="1.5"
|
|
d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4"
|
|
/>
|
|
</svg>
|
|
</div>
|
|
|
|
<!-- Title -->
|
|
<h3
|
|
class="font-medium text-gray-900 mb-2"
|
|
:class="sizeClasses.title"
|
|
>
|
|
{{ title }}
|
|
</h3>
|
|
|
|
<!-- Description -->
|
|
<p
|
|
v-if="description"
|
|
class="text-gray-500 max-w-sm mb-6"
|
|
:class="sizeClasses.description"
|
|
>
|
|
{{ description }}
|
|
</p>
|
|
|
|
<!-- Action button -->
|
|
<div v-if="action">
|
|
<component
|
|
:is="action.to ? 'Link' : 'button'"
|
|
:href="action.to"
|
|
@click="action.onClick"
|
|
class="inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-white bg-indigo-600 rounded-lg hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition-colors"
|
|
>
|
|
<FontAwesomeIcon
|
|
v-if="action.icon"
|
|
:icon="action.icon"
|
|
class="w-4 h-4"
|
|
/>
|
|
{{ action.label }}
|
|
</component>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
|