File size: 5,429 Bytes
70ba896 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
@props([
'periods' => ['daily', 'weekly', 'monthly'],
'default' => 'daily',
'onPeriodChange' => null
])
<div class="bg-white/5 backdrop-blur-2xl border border-white/10 rounded-2xl p-2 shadow-2xl"
style="box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.05), inset 0 1px 0 rgba(255, 255, 255, 0.1);"
x-data="timeFilter('{{ $default }}')">
<div class="flex space-x-1">
@foreach($periods as $period)
<button @click="selectPeriod('{{ $period }}')"
:class="selectedPeriod === '{{ $period }}' ? 'active' : ''"
class="time-filter-btn px-4 py-2 rounded-xl text-sm font-semibold transition-all duration-300 relative overflow-hidden group">
<!-- Active background -->
<div class="absolute inset-0 bg-gradient-to-r from-emerald-400/20 to-emerald-600/20 rounded-xl opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
<!-- Content -->
<span class="relative z-10">{{ ucfirst($period) }}</span>
</button>
@endforeach
</div>
<!-- Date picker for specific date selection -->
<div x-show="showDatePicker"
x-transition:enter="transition ease-out duration-200"
x-transition:enter-start="opacity-0 scale-95"
x-transition:enter-end="opacity-100 scale-100"
x-transition:leave="transition ease-in duration-150"
x-transition:leave-start="opacity-100 scale-100"
x-transition:leave-end="opacity-0 scale-95"
class="mt-3 pt-3 border-t border-white/10">
<div class="flex items-center space-x-3">
<label class="text-white/80 text-sm font-medium">Date:</label>
<input type="date"
x-model="selectedDate"
@change="onDateChange()"
class="bg-white/10 border border-white/20 rounded-lg px-3 py-1 text-white text-sm focus:outline-none focus:ring-2 focus:ring-emerald-400/50 focus:border-emerald-400/50">
</div>
</div>
</div>
<style>
.time-filter-btn {
@apply text-white/70 hover:text-white;
}
.time-filter-btn.active {
@apply text-white bg-gradient-to-r from-emerald-400/30 to-emerald-600/30 border border-emerald-400/50;
box-shadow: 0 0 20px rgba(52, 211, 153, 0.3);
text-shadow: 0 0 10px rgba(52, 211, 153, 0.5);
}
.time-filter-btn:not(.active):hover {
@apply bg-white/10;
}
</style>
<script>
document.addEventListener('alpine:init', () => {
Alpine.data('timeFilter', (defaultPeriod) => ({
selectedPeriod: defaultPeriod,
selectedDate: new Date().toISOString().split('T')[0],
showDatePicker: false,
init() {
// Initialize with default period
this.onPeriodChange();
},
selectPeriod(period) {
if (this.selectedPeriod === period) return;
console.log('Time filter: selecting period', period);
this.selectedPeriod = period;
this.showDatePicker = period !== 'daily' || this.selectedDate !== new Date().toISOString().split('T')[0];
// Trigger period change
this.onPeriodChange();
// Add selection animation
this.animateSelection();
},
onDateChange() {
this.onPeriodChange();
},
onPeriodChange() {
console.log('Time filter: dispatching period change', this.selectedPeriod, this.selectedDate);
// Try to call dashboard instance directly
if (window.dashboardInstance && typeof window.dashboardInstance.onPeriodChange === 'function') {
console.log('Time filter: calling dashboard instance directly');
window.dashboardInstance.onPeriodChange(this.selectedPeriod, this.selectedDate);
} else {
console.log('Time filter: dashboard instance not available, using events');
// Fallback to event system
document.dispatchEvent(new CustomEvent('period-changed', {
detail: {
period: this.selectedPeriod,
date: this.selectedDate
}
}));
}
},
animateSelection() {
// Add a subtle animation to indicate selection
const activeBtn = this.$el.querySelector('.time-filter-btn.active');
if (activeBtn) {
activeBtn.style.transform = 'scale(0.95)';
setTimeout(() => {
activeBtn.style.transform = 'scale(1)';
}, 150);
}
},
// Public methods for external control
setPeriod(period) {
this.selectPeriod(period);
},
setDate(date) {
this.selectedDate = date;
this.onDateChange();
},
getCurrentSelection() {
return {
period: this.selectedPeriod,
date: this.selectedDate
};
}
}));
});
</script> |