WIP: February 2026 event improvements and calendar refactor #1
@ -52,6 +52,7 @@ class CalendarController extends Controller
|
|||||||
$defaultView = $user->getSetting('calendar.last_view', 'month');
|
$defaultView = $user->getSetting('calendar.last_view', 'month');
|
||||||
$defaultDate = $user->getSetting('calendar.last_date', Carbon::today($tz)->toDateString());
|
$defaultDate = $user->getSetting('calendar.last_date', Carbon::today($tz)->toDateString());
|
||||||
$defaultDensity = (int) $user->getSetting('calendar.last_density', 30);
|
$defaultDensity = (int) $user->getSetting('calendar.last_density', 30);
|
||||||
|
$defaultBusinessHours = (int) $user->getSetting('calendar.business_hours', 0);
|
||||||
|
|
||||||
// week start preference
|
// week start preference
|
||||||
$weekStartPref = $user->getSetting('calendar.week_start', 'sunday'); // 'sunday'|'monday'
|
$weekStartPref = $user->getSetting('calendar.week_start', 'sunday'); // 'sunday'|'monday'
|
||||||
@ -76,6 +77,16 @@ class CalendarController extends Controller
|
|||||||
60 => 4,
|
60 => 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// business hours toggle
|
||||||
|
$businessHoursEnabled = (int) $request->query('business_hours', $defaultBusinessHours) === 1;
|
||||||
|
$businessHoursRange = [
|
||||||
|
'start' => 8,
|
||||||
|
'end' => 18,
|
||||||
|
];
|
||||||
|
$businessHoursRows = $businessHoursEnabled
|
||||||
|
? intdiv((($businessHoursRange['end'] - $businessHoursRange['start']) * 60), 15)
|
||||||
|
: 96;
|
||||||
|
|
||||||
// date range span and controls
|
// date range span and controls
|
||||||
$span = $this->gridSpan($view, $range, $weekStart, $weekEnd);
|
$span = $this->gridSpan($view, $range, $weekStart, $weekEnd);
|
||||||
$nav = $this->navDates($view, $range['start'], $tz);
|
$nav = $this->navDates($view, $range['start'], $tz);
|
||||||
@ -92,6 +103,9 @@ class CalendarController extends Controller
|
|||||||
$user->setSetting('calendar.last_date', $range['start']->toDateString());
|
$user->setSetting('calendar.last_date', $range['start']->toDateString());
|
||||||
$user->setSetting('calendar.last_density', (string) $stepMinutes);
|
$user->setSetting('calendar.last_density', (string) $stepMinutes);
|
||||||
}
|
}
|
||||||
|
if ($request->has('business_hours')) {
|
||||||
|
$user->setSetting('calendar.business_hours', $businessHoursEnabled ? '1' : '0');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -121,6 +135,10 @@ class CalendarController extends Controller
|
|||||||
$span['end']
|
$span['end']
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$businessHoursForView = ($businessHoursEnabled && in_array($view, ['day', 'week', 'four'], true))
|
||||||
|
? $businessHoursRange
|
||||||
|
: null;
|
||||||
|
|
||||||
$events = $this->buildEventPayloads(
|
$events = $this->buildEventPayloads(
|
||||||
$events,
|
$events,
|
||||||
$calendar_map,
|
$calendar_map,
|
||||||
@ -130,6 +148,7 @@ class CalendarController extends Controller
|
|||||||
$tz,
|
$tz,
|
||||||
$recurrence,
|
$recurrence,
|
||||||
$span,
|
$span,
|
||||||
|
$businessHoursForView,
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -175,6 +194,7 @@ class CalendarController extends Controller
|
|||||||
$tz,
|
$tz,
|
||||||
$recurrence,
|
$recurrence,
|
||||||
['start' => $mini_grid_start, 'end' => $mini_grid_end],
|
['start' => $mini_grid_start, 'end' => $mini_grid_end],
|
||||||
|
null,
|
||||||
);
|
);
|
||||||
|
|
||||||
// now build the mini from mini_events (not from $events)
|
// now build the mini from mini_events (not from $events)
|
||||||
@ -231,6 +251,12 @@ class CalendarController extends Controller
|
|||||||
'mini' => $mini, // mini calendar days with events for indicators
|
'mini' => $mini, // mini calendar days with events for indicators
|
||||||
'mini_nav' => $mini_nav, // separate mini calendar navigation
|
'mini_nav' => $mini_nav, // separate mini calendar navigation
|
||||||
'mini_headers' => $mini_headers,
|
'mini_headers' => $mini_headers,
|
||||||
|
'business_hours' => [
|
||||||
|
'enabled' => $businessHoursEnabled,
|
||||||
|
'start' => $businessHoursRange['start'],
|
||||||
|
'end' => $businessHoursRange['end'],
|
||||||
|
'rows' => $businessHoursRows,
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
// time-based payload values
|
// time-based payload values
|
||||||
@ -238,11 +264,23 @@ class CalendarController extends Controller
|
|||||||
if ($timeBased)
|
if ($timeBased)
|
||||||
{
|
{
|
||||||
// create the time gutter if we're in a time-based view
|
// create the time gutter if we're in a time-based view
|
||||||
$payload['slots'] = $this->timeSlots($range['start'], $tz, $timeFormat);
|
$payload['slots'] = $this->timeSlots(
|
||||||
|
$range['start'],
|
||||||
|
$tz,
|
||||||
|
$timeFormat,
|
||||||
|
$businessHoursEnabled ? $businessHoursRange : null
|
||||||
|
);
|
||||||
$payload['time_format'] = $timeFormat; // optional, if the blade cares
|
$payload['time_format'] = $timeFormat; // optional, if the blade cares
|
||||||
|
|
||||||
// add the now indicator
|
// add the now indicator
|
||||||
$payload['now'] = $this->nowIndicator($view, $range, $tz, 15);
|
$payload['now'] = $this->nowIndicator(
|
||||||
|
$view,
|
||||||
|
$range,
|
||||||
|
$tz,
|
||||||
|
15,
|
||||||
|
1,
|
||||||
|
$businessHoursEnabled ? $businessHoursRange : null
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// send the density array always, even though it doesn't matter for month
|
// send the density array always, even though it doesn't matter for month
|
||||||
@ -570,15 +608,23 @@ class CalendarController extends Controller
|
|||||||
*
|
*
|
||||||
* Create the time gutter for time-based views
|
* Create the time gutter for time-based views
|
||||||
*/
|
*/
|
||||||
private function timeSlots(Carbon $dayStart, string $tz, string $timeFormat): array
|
private function timeSlots(Carbon $dayStart, string $tz, string $timeFormat, ?array $businessHours = null): array
|
||||||
{
|
{
|
||||||
$minutesPerSlot = 15;
|
$minutesPerSlot = 15;
|
||||||
$slotsPerDay = intdiv(24 * 60, $minutesPerSlot); // 96
|
$startMinutes = 0;
|
||||||
|
$endMinutes = 24 * 60;
|
||||||
|
|
||||||
|
if (is_array($businessHours)) {
|
||||||
|
$startMinutes = (int) $businessHours['start'] * 60;
|
||||||
|
$endMinutes = (int) $businessHours['end'] * 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
$slotsPerDay = intdiv(max(0, $endMinutes - $startMinutes), $minutesPerSlot);
|
||||||
|
|
||||||
$format = $timeFormat === '24' ? 'H:i' : 'g:i a';
|
$format = $timeFormat === '24' ? 'H:i' : 'g:i a';
|
||||||
|
|
||||||
$slots = [];
|
$slots = [];
|
||||||
$t = $dayStart->copy()->tz($tz)->startOfDay();
|
$t = $dayStart->copy()->tz($tz)->startOfDay()->addMinutes($startMinutes);
|
||||||
|
|
||||||
for ($i = 0; $i < $slotsPerDay; $i++) {
|
for ($i = 0; $i < $slotsPerDay; $i++) {
|
||||||
$slots[] = [
|
$slots[] = [
|
||||||
@ -586,7 +632,7 @@ class CalendarController extends Controller
|
|||||||
'label' => $t->format($format),
|
'label' => $t->format($format),
|
||||||
'key' => $t->format('H:i'), // stable "machine" value
|
'key' => $t->format('H:i'), // stable "machine" value
|
||||||
'index' => $i, // 0..95
|
'index' => $i, // 0..95
|
||||||
'minutes' => $i * $minutesPerSlot,
|
'minutes' => $startMinutes + ($i * $minutesPerSlot),
|
||||||
'duration' => $minutesPerSlot, // handy for styling math
|
'duration' => $minutesPerSlot, // handy for styling math
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -613,7 +659,8 @@ class CalendarController extends Controller
|
|||||||
?Carbon $endLocal,
|
?Carbon $endLocal,
|
||||||
Carbon $rangeStart,
|
Carbon $rangeStart,
|
||||||
string $view,
|
string $view,
|
||||||
int $minutesPerSlot = 15
|
int $minutesPerSlot = 15,
|
||||||
|
int $gridStartMinutes = 0
|
||||||
): array
|
): array
|
||||||
{
|
{
|
||||||
$start = $startLocal->copy();
|
$start = $startLocal->copy();
|
||||||
@ -626,7 +673,8 @@ class CalendarController extends Controller
|
|||||||
$displayMinutes = $durationMinutes > 0 ? $durationMinutes : $minutesPerSlot;
|
$displayMinutes = $durationMinutes > 0 ? $durationMinutes : $minutesPerSlot;
|
||||||
|
|
||||||
// row placement (96 rows when minutesPerSlot=15)
|
// row placement (96 rows when minutesPerSlot=15)
|
||||||
$startMinutesFromMidnight = ($start->hour * 60) + $start->minute;
|
$startMinutesFromMidnight = (($start->hour * 60) + $start->minute) - $gridStartMinutes;
|
||||||
|
$startMinutesFromMidnight = max(0, $startMinutesFromMidnight);
|
||||||
$startRow = intdiv($startMinutesFromMidnight, $minutesPerSlot) + 1;
|
$startRow = intdiv($startMinutesFromMidnight, $minutesPerSlot) + 1;
|
||||||
|
|
||||||
$rowSpan = max(1, (int) ceil($displayMinutes / $minutesPerSlot));
|
$rowSpan = max(1, (int) ceil($displayMinutes / $minutesPerSlot));
|
||||||
@ -665,11 +713,14 @@ class CalendarController extends Controller
|
|||||||
array $range,
|
array $range,
|
||||||
string $tz,
|
string $tz,
|
||||||
EventRecurrence $recurrence,
|
EventRecurrence $recurrence,
|
||||||
array $span
|
array $span,
|
||||||
|
?array $businessHours = null
|
||||||
): Collection {
|
): Collection {
|
||||||
$uiFormat = $timeFormat === '24' ? 'H:i' : 'g:ia';
|
$uiFormat = $timeFormat === '24' ? 'H:i' : 'g:ia';
|
||||||
$spanStartUtc = $span['start']->copy()->utc();
|
$spanStartUtc = $span['start']->copy()->utc();
|
||||||
$spanEndUtc = $span['end']->copy()->utc();
|
$spanEndUtc = $span['end']->copy()->utc();
|
||||||
|
$gridStartMinutes = $businessHours ? ((int) $businessHours['start'] * 60) : 0;
|
||||||
|
$gridEndMinutes = $businessHours ? ((int) $businessHours['end'] * 60) : (24 * 60);
|
||||||
|
|
||||||
return $events->flatMap(function ($e) use (
|
return $events->flatMap(function ($e) use (
|
||||||
$calendarMap,
|
$calendarMap,
|
||||||
@ -679,7 +730,10 @@ class CalendarController extends Controller
|
|||||||
$tz,
|
$tz,
|
||||||
$recurrence,
|
$recurrence,
|
||||||
$spanStartUtc,
|
$spanStartUtc,
|
||||||
$spanEndUtc
|
$spanEndUtc,
|
||||||
|
$gridStartMinutes,
|
||||||
|
$gridEndMinutes,
|
||||||
|
$businessHours
|
||||||
) {
|
) {
|
||||||
$cal = $calendarMap[$e->calendarid];
|
$cal = $calendarMap[$e->calendarid];
|
||||||
$timezone = $cal->timezone ?? config('app.timezone');
|
$timezone = $cal->timezone ?? config('app.timezone');
|
||||||
@ -723,7 +777,10 @@ class CalendarController extends Controller
|
|||||||
$tz,
|
$tz,
|
||||||
$timezone,
|
$timezone,
|
||||||
$color,
|
$color,
|
||||||
$colorFg
|
$colorFg,
|
||||||
|
$gridStartMinutes,
|
||||||
|
$gridEndMinutes,
|
||||||
|
$businessHours
|
||||||
) {
|
) {
|
||||||
$startUtc = $occ['start'];
|
$startUtc = $occ['start'];
|
||||||
$endUtc = $occ['end'];
|
$endUtc = $occ['end'];
|
||||||
@ -734,12 +791,28 @@ class CalendarController extends Controller
|
|||||||
$startForGrid = $startUtc->copy()->tz($tz);
|
$startForGrid = $startUtc->copy()->tz($tz);
|
||||||
$endForGrid = $endUtc->copy()->tz($tz);
|
$endForGrid = $endUtc->copy()->tz($tz);
|
||||||
|
|
||||||
|
if ($businessHours) {
|
||||||
|
$startMinutes = ($startForGrid->hour * 60) + $startForGrid->minute;
|
||||||
|
$endMinutes = ($endForGrid->hour * 60) + $endForGrid->minute;
|
||||||
|
|
||||||
|
if ($endMinutes <= $gridStartMinutes || $startMinutes >= $gridEndMinutes) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$displayStartMinutes = max($startMinutes, $gridStartMinutes);
|
||||||
|
$displayEndMinutes = min($endMinutes, $gridEndMinutes);
|
||||||
|
|
||||||
|
$startForGrid = $startForGrid->copy()->startOfDay()->addMinutes($displayStartMinutes);
|
||||||
|
$endForGrid = $endForGrid->copy()->startOfDay()->addMinutes($displayEndMinutes);
|
||||||
|
}
|
||||||
|
|
||||||
$placement = $this->slotPlacement(
|
$placement = $this->slotPlacement(
|
||||||
$startForGrid,
|
$startForGrid,
|
||||||
$endForGrid,
|
$endForGrid,
|
||||||
$range['start']->copy()->tz($tz),
|
$range['start']->copy()->tz($tz),
|
||||||
$view,
|
$view,
|
||||||
15
|
15,
|
||||||
|
$gridStartMinutes
|
||||||
);
|
);
|
||||||
|
|
||||||
$occurrenceId = $occ['recurrence_id']
|
$occurrenceId = $occ['recurrence_id']
|
||||||
@ -770,7 +843,7 @@ class CalendarController extends Controller
|
|||||||
'start_col' => $placement['start_col'],
|
'start_col' => $placement['start_col'],
|
||||||
'duration' => $placement['duration'],
|
'duration' => $placement['duration'],
|
||||||
];
|
];
|
||||||
});
|
})->filter()->values();
|
||||||
})->keyBy('occurrence_id');
|
})->keyBy('occurrence_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -967,7 +1040,14 @@ class CalendarController extends Controller
|
|||||||
* 'col_end' => int, // grid column end
|
* 'col_end' => int, // grid column end
|
||||||
* ]
|
* ]
|
||||||
*/
|
*/
|
||||||
private function nowIndicator(string $view, array $range, string $tz, int $minutesPerSlot = 15, int $gutterCols = 1): array
|
private function nowIndicator(
|
||||||
|
string $view,
|
||||||
|
array $range,
|
||||||
|
string $tz,
|
||||||
|
int $minutesPerSlot = 15,
|
||||||
|
int $gutterCols = 1,
|
||||||
|
?array $businessHours = null
|
||||||
|
): array
|
||||||
{
|
{
|
||||||
// only meaningful for time-based views
|
// only meaningful for time-based views
|
||||||
if (!in_array($view, ['day', 'week', 'four'], true)) {
|
if (!in_array($view, ['day', 'week', 'four'], true)) {
|
||||||
@ -986,8 +1066,15 @@ class CalendarController extends Controller
|
|||||||
|
|
||||||
// row: minutes since midnight, snapped down to slot size
|
// row: minutes since midnight, snapped down to slot size
|
||||||
$minutes = ($now->hour * 60) + $now->minute;
|
$minutes = ($now->hour * 60) + $now->minute;
|
||||||
$snapped = intdiv($minutes, $minutesPerSlot) * $minutesPerSlot;
|
$gridStartMinutes = $businessHours ? ((int) $businessHours['start'] * 60) : 0;
|
||||||
$row = intdiv($snapped, $minutesPerSlot) + 1; // 1-based
|
$gridEndMinutes = $businessHours ? ((int) $businessHours['end'] * 60) : (24 * 60);
|
||||||
|
|
||||||
|
if ($businessHours && ($minutes < $gridStartMinutes || $minutes > $gridEndMinutes)) {
|
||||||
|
return ['show' => false, 'row' => 1, 'day_col' => 1, 'col_start' => 1, 'col_end' => 2];
|
||||||
|
}
|
||||||
|
|
||||||
|
$snapped = intdiv($minutes - $gridStartMinutes, $minutesPerSlot) * $minutesPerSlot;
|
||||||
|
$row = intdiv(max(0, $snapped), $minutesPerSlot) + 1; // 1-based
|
||||||
|
|
||||||
// column: 1..N where 1 is the first day column in the events grid
|
// column: 1..N where 1 is the first day column in the events grid
|
||||||
if ($view === 'day') {
|
if ($view === 'day') {
|
||||||
|
|||||||
@ -131,7 +131,7 @@
|
|||||||
/* time column */
|
/* time column */
|
||||||
ol.time {
|
ol.time {
|
||||||
@apply grid z-0 pt-4;
|
@apply grid z-0 pt-4;
|
||||||
grid-template-rows: repeat(96, var(--row-height));
|
grid-template-rows: repeat(var(--grid-rows, 96), var(--row-height));
|
||||||
|
|
||||||
time {
|
time {
|
||||||
@apply relative flex items-center justify-end items-start pr-4;
|
@apply relative flex items-center justify-end items-start pr-4;
|
||||||
@ -150,7 +150,7 @@
|
|||||||
/* event positioning */
|
/* event positioning */
|
||||||
ol.events {
|
ol.events {
|
||||||
@apply grid py-4;
|
@apply grid py-4;
|
||||||
grid-template-rows: repeat(96, var(--row-height));
|
grid-template-rows: repeat(var(--grid-rows, 96), var(--row-height));
|
||||||
--event-col: 0;
|
--event-col: 0;
|
||||||
--event-row: 0;
|
--event-row: 0;
|
||||||
--event-end: 4;
|
--event-end: 4;
|
||||||
@ -381,4 +381,3 @@
|
|||||||
transform: translateX(0);
|
transform: translateX(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -74,6 +74,7 @@
|
|||||||
:view="$view"
|
:view="$view"
|
||||||
:density="$density"
|
:density="$density"
|
||||||
:headers="$mini_headers"
|
:headers="$mini_headers"
|
||||||
|
:business_hours="$business_hours"
|
||||||
class="aside-inset"
|
class="aside-inset"
|
||||||
/>
|
/>
|
||||||
</x-slot>
|
</x-slot>
|
||||||
@ -105,6 +106,7 @@
|
|||||||
{{-- persist values from other forms --}}
|
{{-- persist values from other forms --}}
|
||||||
<input type="hidden" name="view" value="{{ $view }}">
|
<input type="hidden" name="view" value="{{ $view }}">
|
||||||
<input type="hidden" name="density" value="{{ $density['step'] }}">
|
<input type="hidden" name="density" value="{{ $density['step'] }}">
|
||||||
|
<input type="hidden" name="business_hours" value="{{ (int) ($business_hours['enabled'] ?? 0) }}">
|
||||||
|
|
||||||
<nav class="button-group button-group--primary">
|
<nav class="button-group button-group--primary">
|
||||||
<x-button.group-button
|
<x-button.group-button
|
||||||
@ -148,6 +150,7 @@
|
|||||||
|
|
||||||
{{-- persist data from density form --}}
|
{{-- persist data from density form --}}
|
||||||
<input type="hidden" name="density" value="{{ $density['step'] }}">
|
<input type="hidden" name="density" value="{{ $density['step'] }}">
|
||||||
|
<input type="hidden" name="business_hours" value="{{ (int) ($business_hours['enabled'] ?? 0) }}">
|
||||||
<x-button.group-input value="day" :active="$view === 'day'">Day</x-button.group-input>
|
<x-button.group-input value="day" :active="$view === 'day'">Day</x-button.group-input>
|
||||||
<x-button.group-input value="week" :active="$view === 'week'">Week</x-button.group-input>
|
<x-button.group-input value="week" :active="$view === 'week'">Week</x-button.group-input>
|
||||||
<x-button.group-input value="month" :active="$view === 'month'">Month</x-button.group-input>
|
<x-button.group-input value="month" :active="$view === 'month'">Month</x-button.group-input>
|
||||||
@ -176,6 +179,7 @@
|
|||||||
:active="$active"
|
:active="$active"
|
||||||
:density="$density"
|
:density="$density"
|
||||||
:weekstart="$week_start"
|
:weekstart="$week_start"
|
||||||
|
:business_hours="$business_hours"
|
||||||
:now="$now"
|
:now="$now"
|
||||||
/>
|
/>
|
||||||
@break
|
@break
|
||||||
@ -190,6 +194,7 @@
|
|||||||
:hgroup="$hgroup"
|
:hgroup="$hgroup"
|
||||||
:active="$active"
|
:active="$active"
|
||||||
:density="$density"
|
:density="$density"
|
||||||
|
:business_hours="$business_hours"
|
||||||
:now="$now"
|
:now="$now"
|
||||||
/>
|
/>
|
||||||
@break
|
@break
|
||||||
@ -204,6 +209,7 @@
|
|||||||
:hgroup="$hgroup"
|
:hgroup="$hgroup"
|
||||||
:active="$active"
|
:active="$active"
|
||||||
:density="$density"
|
:density="$density"
|
||||||
|
:business_hours="$business_hours"
|
||||||
:now="$now"
|
:now="$now"
|
||||||
/>
|
/>
|
||||||
@break
|
@break
|
||||||
|
|||||||
@ -9,11 +9,12 @@
|
|||||||
'active' => [],
|
'active' => [],
|
||||||
'density' => '30',
|
'density' => '30',
|
||||||
'now' => [],
|
'now' => [],
|
||||||
|
'business_hours' => [],
|
||||||
])
|
])
|
||||||
|
|
||||||
<section
|
<section
|
||||||
class="calendar {{ $class }}" data-density="{{ $density['step'] }}"
|
class="calendar {{ $class }}" data-density="{{ $density['step'] }}"
|
||||||
style="--now-row: {{ $now['row'] }}; --now-col-start: {{ $now['col_start'] }}; --now-col-end: {{ $now['col_end'] }};"
|
style="--now-row: {{ $now['row'] }}; --now-col-start: {{ $now['col_start'] }}; --now-col-end: {{ $now['col_end'] }}; --grid-rows: {{ $business_hours['rows'] ?? 96 }};"
|
||||||
>
|
>
|
||||||
<hgroup>
|
<hgroup>
|
||||||
@foreach ($hgroup as $h)
|
@foreach ($hgroup as $h)
|
||||||
@ -39,6 +40,7 @@
|
|||||||
@endif
|
@endif
|
||||||
</ol>
|
</ol>
|
||||||
<footer>
|
<footer>
|
||||||
<x-calendar.time.density view="day" :density="$density" />
|
<x-calendar.time.business-hours view="day" :density="$density" :business_hours="$business_hours" />
|
||||||
|
<x-calendar.time.density view="day" :density="$density" :business_hours="$business_hours" />
|
||||||
</footer>
|
</footer>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
'active' => [],
|
'active' => [],
|
||||||
'density' => '30',
|
'density' => '30',
|
||||||
'now' => [],
|
'now' => [],
|
||||||
|
'business_hours' => [],
|
||||||
])
|
])
|
||||||
|
|
||||||
<section
|
<section
|
||||||
@ -16,7 +17,8 @@
|
|||||||
style=
|
style=
|
||||||
"--now-row: {{ (int) $now['row'] }};
|
"--now-row: {{ (int) $now['row'] }};
|
||||||
--now-col-start: {{ (int) $now['col_start'] }};
|
--now-col-start: {{ (int) $now['col_start'] }};
|
||||||
--now-col-end: {{ (int) $now['col_end'] }};"
|
--now-col-end: {{ (int) $now['col_end'] }};
|
||||||
|
--grid-rows: {{ $business_hours['rows'] ?? 96 }};"
|
||||||
>
|
>
|
||||||
<hgroup>
|
<hgroup>
|
||||||
@foreach ($hgroup as $h)
|
@foreach ($hgroup as $h)
|
||||||
@ -42,6 +44,7 @@
|
|||||||
@endif
|
@endif
|
||||||
</ol>
|
</ol>
|
||||||
<footer>
|
<footer>
|
||||||
<x-calendar.time.density view="four" :density="$density" />
|
<x-calendar.time.business-hours view="four" :density="$density" :business_hours="$business_hours" />
|
||||||
|
<x-calendar.time.density view="four" :density="$density" :business_hours="$business_hours" />
|
||||||
</footer>
|
</footer>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
'class' => '',
|
'class' => '',
|
||||||
'density' => [],
|
'density' => [],
|
||||||
'headers' => [],
|
'headers' => [],
|
||||||
|
'business_hours' => [],
|
||||||
])
|
])
|
||||||
|
|
||||||
<section id="mini" class="mini mini--month {{ $class }}">
|
<section id="mini" class="mini mini--month {{ $class }}">
|
||||||
@ -22,6 +23,7 @@
|
|||||||
{{-- preserve main calendar context for full-reload fallback --}}
|
{{-- preserve main calendar context for full-reload fallback --}}
|
||||||
<input type="hidden" name="view" value="{{ $view }}">
|
<input type="hidden" name="view" value="{{ $view }}">
|
||||||
<input type="hidden" name="date" value="{{ request('date') }}">
|
<input type="hidden" name="date" value="{{ request('date') }}">
|
||||||
|
<input type="hidden" name="business_hours" value="{{ (int) ($business_hours['enabled'] ?? 0) }}">
|
||||||
{{-- nav buttons --}}
|
{{-- nav buttons --}}
|
||||||
<button type="submit" name="mini" class="button--icon button--sm" value="{{ $nav['prev'] }}" aria-label="Go back 1 month">
|
<button type="submit" name="mini" class="button--icon button--sm" value="{{ $nav['prev'] }}" aria-label="Go back 1 month">
|
||||||
<x-icon-chevron-left />
|
<x-icon-chevron-left />
|
||||||
@ -51,6 +53,7 @@
|
|||||||
{{-- stay on the same view (month/week/etc --}}
|
{{-- stay on the same view (month/week/etc --}}
|
||||||
<input type="hidden" name="view" value="{{ $view }}">
|
<input type="hidden" name="view" value="{{ $view }}">
|
||||||
<input type="hidden" name="density" value="{{ $density['step'] }}">
|
<input type="hidden" name="density" value="{{ $density['step'] }}">
|
||||||
|
<input type="hidden" name="business_hours" value="{{ (int) ($business_hours['enabled'] ?? 0) }}">
|
||||||
|
|
||||||
@foreach ($mini['days'] as $day)
|
@foreach ($mini['days'] as $day)
|
||||||
<button
|
<button
|
||||||
|
|||||||
@ -0,0 +1,34 @@
|
|||||||
|
@props([
|
||||||
|
'business_hours' => [],
|
||||||
|
'view' => 'day',
|
||||||
|
'density' => [],
|
||||||
|
])
|
||||||
|
|
||||||
|
@php
|
||||||
|
$enabled = (int) ($business_hours['enabled'] ?? 0) === 1;
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
<form id="calendar-business-hours"
|
||||||
|
method="get"
|
||||||
|
class="button-group button-group--primary button-group--sm"
|
||||||
|
action="{{ route('calendar.index') }}"
|
||||||
|
hx-get="{{ route('calendar.index') }}"
|
||||||
|
hx-target="#calendar"
|
||||||
|
hx-select="#calendar"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
hx-push-url="true"
|
||||||
|
hx-trigger="change"
|
||||||
|
hx-include="#calendar-toggles">
|
||||||
|
|
||||||
|
{{-- preserve current view and anchor date --}}
|
||||||
|
<input type="hidden" name="view" value="{{ $view }}">
|
||||||
|
<input type="hidden" name="date" value="{{ $density['anchor'] ?? request('date') }}">
|
||||||
|
<input type="hidden" name="density" value="{{ $density['step'] ?? 30 }}">
|
||||||
|
|
||||||
|
<x-button.group-input value="0" name="business_hours" :active="!$enabled">All day</x-button.group-input>
|
||||||
|
<x-button.group-input value="1" name="business_hours" :active="$enabled">Business hours</x-button.group-input>
|
||||||
|
|
||||||
|
<noscript>
|
||||||
|
<button type="submit" class="button">{{ __('Apply') }}</button>
|
||||||
|
</noscript>
|
||||||
|
</form>
|
||||||
@ -1,6 +1,7 @@
|
|||||||
@props([
|
@props([
|
||||||
'density' => [],
|
'density' => [],
|
||||||
'view' => 'day',
|
'view' => 'day',
|
||||||
|
'business_hours' => [],
|
||||||
])
|
])
|
||||||
|
|
||||||
<form id="calendar-density"
|
<form id="calendar-density"
|
||||||
@ -18,6 +19,7 @@
|
|||||||
{{-- preserve current view and anchor date --}}
|
{{-- preserve current view and anchor date --}}
|
||||||
<input type="hidden" name="view" value="{{ $view }}">
|
<input type="hidden" name="view" value="{{ $view }}">
|
||||||
<input type="hidden" name="date" value="{{ $density['anchor'] }}">
|
<input type="hidden" name="date" value="{{ $density['anchor'] }}">
|
||||||
|
<input type="hidden" name="business_hours" value="{{ (int) ($business_hours['enabled'] ?? 0) }}">
|
||||||
|
|
||||||
<x-button.group-input value="15" name="density" :active="(int)($density['step'] ?? 30) === 15">15m</x-button.group-input>
|
<x-button.group-input value="15" name="density" :active="(int)($density['step'] ?? 30) === 15">15m</x-button.group-input>
|
||||||
<x-button.group-input value="30" name="density" :active="(int)($density['step'] ?? 30) === 30">30m</x-button.group-input>
|
<x-button.group-input value="30" name="density" :active="(int)($density['step'] ?? 30) === 30">30m</x-button.group-input>
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
'density' => '30',
|
'density' => '30',
|
||||||
'weekstart' => 0,
|
'weekstart' => 0,
|
||||||
'now' => [],
|
'now' => [],
|
||||||
|
'business_hours' => [],
|
||||||
])
|
])
|
||||||
|
|
||||||
<section
|
<section
|
||||||
@ -17,7 +18,8 @@
|
|||||||
style=
|
style=
|
||||||
"--now-row: {{ (int) $now['row'] }};
|
"--now-row: {{ (int) $now['row'] }};
|
||||||
--now-col-start: {{ (int) $now['col_start'] }};
|
--now-col-start: {{ (int) $now['col_start'] }};
|
||||||
--now-col-end: {{ (int) $now['col_end'] }};"
|
--now-col-end: {{ (int) $now['col_end'] }};
|
||||||
|
--grid-rows: {{ $business_hours['rows'] ?? 96 }};"
|
||||||
>
|
>
|
||||||
<hgroup>
|
<hgroup>
|
||||||
@foreach ($hgroup as $h)
|
@foreach ($hgroup as $h)
|
||||||
@ -43,6 +45,7 @@
|
|||||||
@endif
|
@endif
|
||||||
</ol>
|
</ol>
|
||||||
<footer>
|
<footer>
|
||||||
<x-calendar.time.density view="week" :density="$density" />
|
<x-calendar.time.business-hours view="week" :density="$density" :business_hours="$business_hours" />
|
||||||
|
<x-calendar.time.density view="week" :density="$density" :business_hours="$business_hours" />
|
||||||
</footer>
|
</footer>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user