libra/resources/views/livewire/admin/settings/working-hours.blade.php

177 lines
6.6 KiB
PHP

<?php
use App\Models\AdminLog;
use App\Models\WorkingHour;
use Carbon\Carbon;
use Livewire\Volt\Component;
new class extends Component {
public array $schedule = [];
public function mount(): void
{
for ($day = 0; $day <= 6; $day++) {
$workingHour = WorkingHour::query()->where('day_of_week', $day)->first();
$this->schedule[$day] = [
'is_active' => $workingHour?->is_active ?? false,
'start_time' => $workingHour ? Carbon::parse($workingHour->start_time)->format('H:i') : '09:00',
'end_time' => $workingHour ? Carbon::parse($workingHour->end_time)->format('H:i') : '17:00',
];
}
}
public function save(): void
{
foreach ($this->schedule as $day => $config) {
if ($config['is_active'] && $config['end_time'] <= $config['start_time']) {
$this->addError("schedule.{$day}.end_time", __('validation.end_time_after_start'));
return;
}
}
$oldValues = WorkingHour::all()->keyBy('day_of_week')->toArray();
foreach ($this->schedule as $day => $config) {
WorkingHour::query()->updateOrCreate(
['day_of_week' => $day],
[
'is_active' => $config['is_active'],
'start_time' => $config['start_time'],
'end_time' => $config['end_time'],
]
);
}
AdminLog::create([
'admin_id' => auth()->id(),
'action' => 'update',
'target_type' => 'working_hours',
'old_values' => $oldValues,
'new_values' => $this->schedule,
'ip_address' => request()->ip(),
'created_at' => now(),
]);
session()->flash('success', __('messages.working_hours_saved'));
}
public function getSlotCount(int $day): int
{
if (! $this->schedule[$day]['is_active']) {
return 0;
}
$start = Carbon::parse($this->schedule[$day]['start_time']);
$end = Carbon::parse($this->schedule[$day]['end_time']);
if ($end->lte($start)) {
return 0;
}
$duration = 60;
$count = 0;
while ($start->copy()->addMinutes($duration)->lte($end)) {
$count++;
$start->addMinutes($duration);
}
return $count;
}
public function formatTime(string $time): string
{
return Carbon::parse($time)->format('g:i A');
}
}; ?>
<div>
<div class="mb-6">
<flux:heading size="xl">{{ __('admin.working_hours') }}</flux:heading>
<flux:text class="mt-1 text-zinc-500">
{{ __('admin.working_hours_description') }}
</flux:text>
</div>
@if (session('success'))
<div class="mb-6">
<flux:callout variant="success" icon="check-circle">
{{ session('success') }}
</flux:callout>
</div>
@endif
<div class="rounded-lg border border-zinc-200 bg-white p-6">
<form wire:submit="save">
<div class="space-y-1">
@foreach (range(0, 6) as $day)
<div
wire:key="day-{{ $day }}"
class="flex flex-col gap-4 border-b border-zinc-200 py-4 last:border-b-0 sm:flex-row sm:items-center"
>
<div class="flex items-center gap-4 sm:w-48">
<flux:switch
wire:model.live="schedule.{{ $day }}.is_active"
aria-label="{{ __('admin.working_hours') }} - {{ \App\Models\WorkingHour::getDayName($day) }}"
/>
<span class="font-medium text-zinc-900">
{{ \App\Models\WorkingHour::getDayName($day) }}
</span>
</div>
@if ($schedule[$day]['is_active'])
<div class="flex flex-1 flex-wrap items-center gap-3">
<div class="flex items-center gap-2">
<flux:input
type="time"
wire:model.live="schedule.{{ $day }}.start_time"
class="w-36"
/>
<span class="text-zinc-500">{{ __('admin.to') }}</span>
<flux:input
type="time"
wire:model.live="schedule.{{ $day }}.end_time"
class="w-36"
/>
</div>
<div class="flex items-center gap-2 text-sm">
<span class="text-zinc-500">
({{ $this->formatTime($schedule[$day]['start_time']) }} - {{ $this->formatTime($schedule[$day]['end_time']) }})
</span>
@php($slots = $this->getSlotCount($day))
@if ($slots > 0)
<flux:badge color="green" size="sm">
{{ __('admin.slots_available', ['count' => $slots]) }}
</flux:badge>
@else
<flux:badge color="red" size="sm">
{{ __('admin.no_slots') }}
</flux:badge>
@endif
</div>
</div>
@error("schedule.{$day}.end_time")
<div class="w-full">
<flux:text class="text-sm text-red-500">{{ $message }}</flux:text>
</div>
@enderror
@else
<span class="text-zinc-400">{{ __('admin.closed') }}</span>
@endif
</div>
@endforeach
</div>
<div class="mt-6 flex justify-end border-t border-zinc-200 pt-6">
<flux:button variant="primary" type="submit">
{{ __('admin.save_working_hours') }}
</flux:button>
</div>
</form>
</div>
</div>