Skip to content

Commit ecb9386

Browse files
karaOdinclaude
andcommitted
✨ Fix auto-enable and redesign table column UI
Auto-Enable Functionality: • Business hours now auto-enable when time slots are configured • No more manual clicking required when hours exist • Added reactive updates on time picker changes • Enhanced toggle with better helper text explaining auto-enable Table Column Redesign: • Replaced ugly circular display with clean status-based design • Matches reference image style with dot indicator + status text • Shows today's hours below status for quick reference • Changed default display mode from 'circular' to 'status' • Cleaner typography and spacing UI Improvements: • Status badges with proper color coding (green/red/gray) • Better responsive design for table columns • Simplified CSS without complex SVG calculations • Improved readability and professional appearance User Experience: • No more annoying enable toggle clicking • Cleaner, more professional table display • Instant feedback when configuring hours • Better visual hierarchy and information display 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 643f52e commit ecb9386

3 files changed

Lines changed: 90 additions & 111 deletions

File tree

resources/views/components/opening-hours-column.blade.php

Lines changed: 54 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -6,114 +6,59 @@
66

77
<div class="fi-ta-opening-hours-column">
88
@if ($displayMode === 'circular')
9-
<!-- Circular Display -->
10-
<div class="relative flex items-center justify-center" style="width: 80px; height: 80px;">
11-
<!-- SVG Circle -->
12-
<svg class="absolute inset-0 w-full h-full transform -rotate-90" viewBox="0 0 100 100">
13-
<!-- Background circle -->
14-
<circle
15-
cx="50"
16-
cy="50"
17-
r="35"
18-
fill="none"
19-
stroke="#e5e7eb"
20-
stroke-width="8"
21-
class="dark:stroke-gray-600"
22-
/>
23-
24-
<!-- Day segments -->
25-
@php
26-
$days = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'];
27-
$segments = [];
28-
foreach ($days as $index => $day) {
29-
$dayData = $businessData['weekly_hours'][$day] ?? ['is_open' => false, 'formatted' => 'Closed'];
30-
$angle = ($index / 7) * 360;
31-
$segments[] = [
32-
'day' => ucfirst($day),
33-
'is_open' => $dayData['is_open'],
34-
'hours' => $dayData['formatted'],
35-
'angle' => $angle,
36-
'color' => $dayData['is_open'] ? '#10b981' : '#ef4444'
37-
];
38-
}
39-
@endphp
40-
41-
@foreach ($segments as $segment)
42-
@php
43-
$segmentAngle = 360 / 7;
44-
$startAngle = $segment['angle'];
45-
$endAngle = $startAngle + $segmentAngle - 2;
46-
$radius = 35;
47-
48-
$startAngleRad = ($startAngle * M_PI) / 180;
49-
$endAngleRad = ($endAngle * M_PI) / 180;
50-
51-
$largeArcFlag = ($endAngle - $startAngle) <= 180 ? "0" : "1";
52-
53-
$x1 = 50 + $radius * cos($startAngleRad);
54-
$y1 = 50 + $radius * sin($startAngleRad);
55-
$x2 = 50 + $radius * cos($endAngleRad);
56-
$y2 = 50 + $radius * sin($endAngleRad);
57-
58-
$pathData = "M {$x1} {$y1} A {$radius} {$radius} 0 {$largeArcFlag} 1 {$x2} {$y2}";
59-
@endphp
60-
61-
<path
62-
d="{{ $pathData }}"
63-
stroke="{{ $segment['color'] }}"
64-
stroke-width="8"
65-
fill="none"
66-
stroke-linecap="round"
67-
class="{{ !$segment['is_open'] ? 'opacity-50' : '' }}"
68-
@if ($showTooltips)
69-
title="{{ $segment['day'] }}: {{ $segment['hours'] }}"
70-
@endif
71-
/>
72-
@endforeach
73-
</svg>
9+
<!-- Clean Status Display -->
10+
<div class="flex flex-col items-center space-y-2 p-2">
11+
<!-- Main Status Badge -->
12+
<div class="flex items-center space-x-2">
13+
<div class="w-2 h-2 rounded-full
14+
@if ($businessData['is_open'])
15+
bg-green-500
16+
@elseif ($businessData['status'] === 'not_configured' || $businessData['status'] === 'disabled')
17+
bg-gray-400
18+
@else
19+
bg-red-500
20+
@endif"
21+
></div>
22+
<span class="text-sm font-medium
23+
@if ($businessData['is_open'])
24+
text-green-700 dark:text-green-400
25+
@elseif ($businessData['status'] === 'not_configured' || $businessData['status'] === 'disabled' || $businessData['status'] === 'error')
26+
text-gray-600 dark:text-gray-400
27+
@else
28+
text-red-700 dark:text-red-400
29+
@endif">
30+
@if ($businessData['is_open'])
31+
Open
32+
@elseif ($businessData['status'] === 'not_configured')
33+
Not configured
34+
@elseif ($businessData['status'] === 'disabled')
35+
Disabled
36+
@elseif ($businessData['status'] === 'error')
37+
Error
38+
@else
39+
Closed
40+
@endif
41+
</span>
42+
</div>
7443

75-
<!-- Center status -->
76-
<div class="absolute inset-0 flex items-center justify-center">
77-
<div class="text-center">
78-
<div class="w-3 h-3 rounded-full mx-auto mb-1
79-
@if ($businessData['is_open'])
80-
bg-green-500 animate-pulse
81-
@elseif ($businessData['status'] === 'not_configured' || $businessData['status'] === 'disabled')
82-
bg-gray-400
83-
@else
84-
bg-red-500
85-
@endif"
86-
></div>
87-
<div class="text-xs font-medium
88-
@if ($businessData['is_open'])
89-
text-green-600 dark:text-green-400
90-
@elseif ($businessData['status'] === 'not_configured' || $businessData['status'] === 'disabled' || $businessData['status'] === 'error')
91-
text-gray-500 dark:text-gray-400
92-
@else
93-
text-red-600 dark:text-red-400
94-
@endif">
95-
@if ($businessData['is_open'])
96-
OPEN
97-
@elseif ($businessData['status'] === 'not_configured' || $businessData['status'] === 'disabled')
98-
N/A
99-
@elseif ($businessData['status'] === 'error')
100-
ERR
101-
@else
102-
CLOSED
103-
@endif
104-
</div>
105-
</div>
44+
<!-- Today's Hours -->
45+
@php
46+
$today = strtolower(now()->format('l'));
47+
$todayHours = $businessData['weekly_hours'][$today] ?? ['formatted' => 'Closed'];
48+
@endphp
49+
<div class="text-xs text-gray-500 dark:text-gray-400 text-center">
50+
{{ $todayHours['formatted'] }}
10651
</div>
10752

10853
@if ($showTooltips)
109-
<div title="{{ $businessData['current_status'] }}" class="absolute inset-0 cursor-help"></div>
54+
<div class="sr-only">{{ $businessData['current_status'] }}</div>
11055
@endif
11156
</div>
11257

11358
@elseif ($displayMode === 'status')
114-
<!-- Status Badge Display -->
59+
<!-- Compact Status Badge -->
11560
<div class="flex items-center justify-center">
116-
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium
61+
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium
11762
@if ($businessData['is_open'])
11863
bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200
11964
@elseif ($businessData['status'] === 'not_configured')
@@ -125,7 +70,15 @@ class="{{ !$segment['is_open'] ? 'opacity-50' : '' }}"
12570
title="Next: {{ $businessData['is_open'] ? 'Closes at ' . $businessData['next_close'] : 'Opens at ' . $businessData['next_open'] }}"
12671
@endif
12772
>
128-
{{ $businessData['current_status'] }}
73+
@if ($businessData['is_open'])
74+
Open
75+
@elseif ($businessData['status'] === 'not_configured')
76+
Not configured
77+
@elseif ($businessData['status'] === 'disabled')
78+
Disabled
79+
@else
80+
Closed
81+
@endif
12982
</span>
13083
</div>
13184

@@ -168,15 +121,7 @@ class="{{ !$segment['is_open'] ? 'opacity-50' : '' }}"
168121

169122
<style>
170123
.fi-ta-opening-hours-column {
171-
min-width: 80px;
172-
}
173-
174-
.fi-ta-opening-hours-column svg {
175-
filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.1));
176-
}
177-
178-
.dark .fi-ta-opening-hours-column svg {
179-
filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.3));
124+
min-width: 120px;
180125
}
181126
182127
@keyframes pulse {

src/Components/OpeningHoursColumn.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class OpeningHoursColumn extends Column
99
{
1010
protected string $view = 'filament-opening-hours::components.opening-hours-column';
1111

12-
protected string | Closure $displayMode = 'circular';
12+
protected string | Closure $displayMode = 'status';
1313
protected bool | Closure $showTooltips = true;
1414
protected bool | Closure $showCurrentStatus = true;
1515
protected string | Closure | null $timezone = null;

src/Components/OpeningHoursForm.php

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,29 @@ public static function schema(): array
3737

3838
Toggle::make('opening_hours_enabled')
3939
->label('Enable Business Hours')
40-
->helperText('Turn this ON to activate business hours. You can configure hours and exceptions below first, then enable when ready.')
40+
->helperText('Automatically enabled when hours are configured. Turn off to temporarily disable.')
4141
->default(true)
4242
->live()
43+
->reactive()
44+
->afterStateUpdated(function ($state, $set, $get) {
45+
// Auto-enable if any hours are configured
46+
if (!$state) {
47+
$openingHours = $get('opening_hours') ?? [];
48+
$hasHours = false;
49+
50+
foreach ($openingHours as $dayData) {
51+
if (isset($dayData['enabled']) && $dayData['enabled'] &&
52+
isset($dayData['hours']) && !empty($dayData['hours'])) {
53+
$hasHours = true;
54+
break;
55+
}
56+
}
57+
58+
if ($hasHours) {
59+
$set('opening_hours_enabled', true);
60+
}
61+
}
62+
})
4363
->columnSpan(1),
4464
]),
4565
])
@@ -353,6 +373,13 @@ protected static function getDayComponents(): array
353373
->required()
354374
->seconds(false)
355375
->displayFormat('H:i')
376+
->live()
377+
->afterStateUpdated(function ($state, $set, $get) {
378+
// Auto-enable business hours when time is set
379+
if ($state) {
380+
$set('opening_hours_enabled', true);
381+
}
382+
})
356383
->columnSpan(1),
357384

358385
TimePicker::make('to')
@@ -361,6 +388,13 @@ protected static function getDayComponents(): array
361388
->seconds(false)
362389
->displayFormat('H:i')
363390
->after('from')
391+
->live()
392+
->afterStateUpdated(function ($state, $set, $get) {
393+
// Auto-enable business hours when time is set
394+
if ($state) {
395+
$set('opening_hours_enabled', true);
396+
}
397+
})
364398
->columnSpan(1),
365399

366400
Placeholder::make('duration')

0 commit comments

Comments
 (0)