105 lines
3.4 KiB
PHP
105 lines
3.4 KiB
PHP
@props([
|
|
'label' => '',
|
|
'value' => '',
|
|
'icon' => null,
|
|
'iconClass' => 'size-5',
|
|
'iconBg' => 'bg-primary/10',
|
|
'iconColor' => 'text-primary',
|
|
'trend' => null,
|
|
'trendUp' => null,
|
|
'trendLabel' => null,
|
|
'suffix' => null,
|
|
'prefix' => null,
|
|
'loading' => false,
|
|
'compact' => false,
|
|
'href' => null,
|
|
'clickable' => false,
|
|
])
|
|
|
|
@php
|
|
$cardClasses = 'bg-white dark:bg-gray-900 rounded-xl border border-gray-200 dark:border-gray-800 shadow-sm transition-all duration-200';
|
|
if ($href || $clickable) {
|
|
$cardClasses .= ' hover:shadow-md hover:border-gray-300 dark:hover:border-gray-700 cursor-pointer';
|
|
}
|
|
$paddingClasses = $compact ? 'p-4' : 'p-5';
|
|
|
|
// Determine trend styling
|
|
$trendClasses = '';
|
|
$trendIcon = null;
|
|
if ($trendUp === true) {
|
|
$trendClasses = 'text-success';
|
|
$trendIcon = 'ri-arrow-up-line';
|
|
} elseif ($trendUp === false) {
|
|
$trendClasses = 'text-danger';
|
|
$trendIcon = 'ri-arrow-down-line';
|
|
} else {
|
|
$trendClasses = 'text-base/50';
|
|
$trendIcon = 'ri-subtract-line';
|
|
}
|
|
@endphp
|
|
|
|
@if($href)
|
|
<a href="{{ $href }}" {{ $attributes->merge(['class' => $cardClasses . ' ' . $paddingClasses . ' block']) }}>
|
|
@else
|
|
<div {{ $attributes->merge(['class' => $cardClasses . ' ' . $paddingClasses]) }}>
|
|
@endif
|
|
|
|
<div class="flex items-start justify-between gap-4">
|
|
<div class="flex-1 min-w-0">
|
|
{{-- Label --}}
|
|
<p class="text-sm font-medium text-base/60 mb-1 truncate">{{ $label }}</p>
|
|
|
|
{{-- Value --}}
|
|
<div class="flex items-baseline gap-1">
|
|
@if($prefix)
|
|
<span class="text-sm text-base/50">{{ $prefix }}</span>
|
|
@endif
|
|
|
|
@if($loading)
|
|
<div class="h-8 w-20 bg-neutral/20 rounded animate-pulse"></div>
|
|
@else
|
|
<span class="text-2xl font-bold text-base/90 truncate">{{ $value }}</span>
|
|
@endif
|
|
|
|
@if($suffix)
|
|
<span class="text-sm text-base/50">{{ $suffix }}</span>
|
|
@endif
|
|
</div>
|
|
|
|
{{-- Trend --}}
|
|
@if($trend !== null || $trendLabel)
|
|
<div class="flex items-center gap-1 mt-2">
|
|
@if($trendIcon)
|
|
<x-dynamic-component :component="$trendIcon" class="size-4 {{ $trendClasses }}" />
|
|
@endif
|
|
@if($trend !== null)
|
|
<span class="text-sm font-medium {{ $trendClasses }}">{{ $trend }}</span>
|
|
@endif
|
|
@if($trendLabel)
|
|
<span class="text-xs text-base/50">{{ $trendLabel }}</span>
|
|
@endif
|
|
</div>
|
|
@endif
|
|
|
|
{{-- Slot for additional content --}}
|
|
@if($slot->isNotEmpty())
|
|
<div class="mt-3">
|
|
{{ $slot }}
|
|
</div>
|
|
@endif
|
|
</div>
|
|
|
|
{{-- Icon --}}
|
|
@if($icon)
|
|
<div class="flex items-center justify-center w-12 h-12 rounded-xl {{ $iconBg }} flex-shrink-0">
|
|
<x-dynamic-component :component="$icon" class="{{ $iconClass }} {{ $iconColor }}" />
|
|
</div>
|
|
@endif
|
|
</div>
|
|
|
|
@if($href)
|
|
</a>
|
|
@else
|
|
</div>
|
|
@endif
|