chart bug fix

This commit is contained in:
Naser Mansour 2025-12-27 20:26:53 +02:00
parent b69b4c8be2
commit a052266950
1 changed files with 164 additions and 187 deletions

View File

@ -375,99 +375,19 @@ new class extends Component
@else @else
<div <div
wire:ignore wire:ignore
x-data="trendsChart($wire.chartData)" x-data="{
class="h-64"
>
<canvas x-ref="canvas"></canvas>
</div>
@endif
</div>
{{-- Consultation Breakdown Chart --}}
<div class="rounded-lg border border-zinc-200 bg-white p-6 dark:border-zinc-700 dark:bg-zinc-800">
<flux:heading size="sm" class="mb-4">{{ __('admin_metrics.consultation_breakdown') }}</flux:heading>
@if ($chartData['consultationBreakdown']['free'] === 0 && $chartData['consultationBreakdown']['paid'] === 0)
<div class="flex h-64 items-center justify-center">
<flux:text class="text-zinc-500 dark:text-zinc-400">{{ __('admin_metrics.no_data_available') }}</flux:text>
</div>
@else
<div
wire:ignore
x-data="breakdownChart($wire.chartData.consultationBreakdown)"
class="h-64"
>
<canvas x-ref="canvas"></canvas>
</div>
@endif
</div>
{{-- No-show Rate Chart --}}
<div class="rounded-lg border border-zinc-200 bg-white p-6 dark:border-zinc-700 dark:bg-zinc-800 lg:col-span-2">
<flux:heading size="sm" class="mb-4">{{ __('admin_metrics.noshow_rate_trend') }}</flux:heading>
@if (array_sum($chartData['noShowRates']) === 0)
<div class="flex h-64 items-center justify-center">
<flux:text class="text-zinc-500 dark:text-zinc-400">{{ __('admin_metrics.no_data_available') }}</flux:text>
</div>
@else
<div
wire:ignore
x-data="noShowChart($wire.chartData)"
class="h-64"
>
<canvas x-ref="canvas"></canvas>
</div>
@endif
</div>
</div>
</div>
{{-- Quick Actions Panel Section --}}
<div class="mt-8">
<flux:heading size="lg" class="mb-6">{{ __('widgets.quick_actions') }}</flux:heading>
<div class="grid grid-cols-1 gap-6 lg:grid-cols-3">
{{-- Quick Actions Panel --}}
<div class="rounded-lg border border-zinc-200 bg-white p-6 dark:border-zinc-700 dark:bg-zinc-800 lg:col-span-3">
<livewire:admin.widgets.quick-actions />
</div>
{{-- Pending Bookings Widget --}}
<div class="rounded-lg border border-zinc-200 bg-white p-6 dark:border-zinc-700 dark:bg-zinc-800">
<livewire:admin.widgets.pending-bookings />
</div>
{{-- Today's Schedule Widget --}}
<div class="rounded-lg border border-zinc-200 bg-white p-6 dark:border-zinc-700 dark:bg-zinc-800">
<livewire:admin.widgets.todays-schedule />
</div>
{{-- Recent Updates Widget --}}
<div class="rounded-lg border border-zinc-200 bg-white p-6 dark:border-zinc-700 dark:bg-zinc-800">
<livewire:admin.widgets.recent-updates />
</div>
</div>
</div>
@script
<script>
// Ensure Chart.js is available
if (typeof Chart === 'undefined') {
console.error('Chart.js is not loaded');
}
Alpine.data('trendsChart', (data) => ({
chart: null, chart: null,
data: @js($chartData),
init() { init() {
if (typeof Chart === 'undefined') return; if (typeof Chart === 'undefined') return;
this.chart = new Chart(this.$refs.canvas, { this.chart = new Chart(this.$refs.canvas, {
type: 'line', type: 'line',
data: { data: {
labels: data.labels, labels: this.data.labels,
datasets: [ datasets: [
{ {
label: @js(__('admin_metrics.new_clients')), label: @js(__('admin_metrics.new_clients')),
data: data.newClients, data: this.data.newClients,
borderColor: '#D4AF37', borderColor: '#D4AF37',
backgroundColor: 'rgba(212, 175, 55, 0.1)', backgroundColor: 'rgba(212, 175, 55, 0.1)',
tension: 0.3, tension: 0.3,
@ -475,7 +395,7 @@ new class extends Component
}, },
{ {
label: @js(__('admin_metrics.consultations')), label: @js(__('admin_metrics.consultations')),
data: data.consultations, data: this.data.consultations,
borderColor: '#0A1F44', borderColor: '#0A1F44',
backgroundColor: 'rgba(10, 31, 68, 0.1)', backgroundColor: 'rgba(10, 31, 68, 0.1)',
tension: 0.3, tension: 0.3,
@ -503,30 +423,41 @@ new class extends Component
}); });
}, },
destroy() { destroy() {
if (this.chart) { if (this.chart) this.chart.destroy();
this.chart.destroy();
} }
} }"
})); class="h-64"
>
<canvas x-ref="canvas"></canvas>
</div>
@endif
</div>
Alpine.data('breakdownChart', (data) => ({ {{-- Consultation Breakdown Chart --}}
<div class="rounded-lg border border-zinc-200 bg-white p-6 dark:border-zinc-700 dark:bg-zinc-800">
<flux:heading size="sm" class="mb-4">{{ __('admin_metrics.consultation_breakdown') }}</flux:heading>
@if ($chartData['consultationBreakdown']['free'] === 0 && $chartData['consultationBreakdown']['paid'] === 0)
<div class="flex h-64 items-center justify-center">
<flux:text class="text-zinc-500 dark:text-zinc-400">{{ __('admin_metrics.no_data_available') }}</flux:text>
</div>
@else
<div
wire:ignore
x-data="{
chart: null, chart: null,
data: @js($chartData['consultationBreakdown']),
init() { init() {
if (typeof Chart === 'undefined') return; if (typeof Chart === 'undefined') return;
const total = this.data.free + this.data.paid;
const total = data.free + data.paid;
const freePercent = total > 0 ? Math.round((data.free / total) * 100) : 0;
const paidPercent = total > 0 ? Math.round((data.paid / total) * 100) : 0;
this.chart = new Chart(this.$refs.canvas, { this.chart = new Chart(this.$refs.canvas, {
type: 'doughnut', type: 'doughnut',
data: { data: {
labels: [ labels: [
@js(__('admin_metrics.free')) + ` (${data.free})`, @js(__('admin_metrics.free')) + ` (${this.data.free})`,
@js(__('admin_metrics.paid')) + ` (${data.paid})` @js(__('admin_metrics.paid')) + ` (${this.data.paid})`
], ],
datasets: [{ datasets: [{
data: [data.free, data.paid], data: [this.data.free, this.data.paid],
backgroundColor: ['#D4AF37', '#0A1F44'], backgroundColor: ['#D4AF37', '#0A1F44'],
borderWidth: 0, borderWidth: 0,
}] }]
@ -553,24 +484,38 @@ new class extends Component
}); });
}, },
destroy() { destroy() {
if (this.chart) { if (this.chart) this.chart.destroy();
this.chart.destroy();
} }
} }"
})); class="h-64"
>
<canvas x-ref="canvas"></canvas>
</div>
@endif
</div>
Alpine.data('noShowChart', (data) => ({ {{-- No-show Rate Chart --}}
<div class="rounded-lg border border-zinc-200 bg-white p-6 dark:border-zinc-700 dark:bg-zinc-800 lg:col-span-2">
<flux:heading size="sm" class="mb-4">{{ __('admin_metrics.noshow_rate_trend') }}</flux:heading>
@if (array_sum($chartData['noShowRates']) === 0)
<div class="flex h-64 items-center justify-center">
<flux:text class="text-zinc-500 dark:text-zinc-400">{{ __('admin_metrics.no_data_available') }}</flux:text>
</div>
@else
<div
wire:ignore
x-data="{
chart: null, chart: null,
data: @js($chartData),
init() { init() {
if (typeof Chart === 'undefined') return; if (typeof Chart === 'undefined') return;
this.chart = new Chart(this.$refs.canvas, { this.chart = new Chart(this.$refs.canvas, {
type: 'line', type: 'line',
data: { data: {
labels: data.labels, labels: this.data.labels,
datasets: [{ datasets: [{
label: @js(__('admin_metrics.noshow_rate_percent')), label: @js(__('admin_metrics.noshow_rate_percent')),
data: data.noShowRates, data: this.data.noShowRates,
borderColor: '#E74C3C', borderColor: '#E74C3C',
backgroundColor: 'rgba(231, 76, 60, 0.1)', backgroundColor: 'rgba(231, 76, 60, 0.1)',
fill: true, fill: true,
@ -625,11 +570,43 @@ new class extends Component
}); });
}, },
destroy() { destroy() {
if (this.chart) { if (this.chart) this.chart.destroy();
this.chart.destroy();
} }
} }"
})); class="h-64"
</script> >
@endscript <canvas x-ref="canvas"></canvas>
</div>
@endif
</div>
</div>
</div>
{{-- Quick Actions Panel Section --}}
<div class="mt-8">
<flux:heading size="lg" class="mb-6">{{ __('widgets.quick_actions') }}</flux:heading>
<div class="grid grid-cols-1 gap-6 lg:grid-cols-3">
{{-- Quick Actions Panel --}}
<div class="rounded-lg border border-zinc-200 bg-white p-6 dark:border-zinc-700 dark:bg-zinc-800 lg:col-span-3">
<livewire:admin.widgets.quick-actions />
</div>
{{-- Pending Bookings Widget --}}
<div class="rounded-lg border border-zinc-200 bg-white p-6 dark:border-zinc-700 dark:bg-zinc-800">
<livewire:admin.widgets.pending-bookings />
</div>
{{-- Today's Schedule Widget --}}
<div class="rounded-lg border border-zinc-200 bg-white p-6 dark:border-zinc-700 dark:bg-zinc-800">
<livewire:admin.widgets.todays-schedule />
</div>
{{-- Recent Updates Widget --}}
<div class="rounded-lg border border-zinc-200 bg-white p-6 dark:border-zinc-700 dark:bg-zinc-800">
<livewire:admin.widgets.recent-updates />
</div>
</div>
</div>
</div> </div>