tutoring/resources/views/calendar/index.blade.php

137 lines
7.5 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<link rel="stylesheet" href="{{ asset('css/custom.css') }}">
@php
use App\Services\BusyWindowService;
use Carbon\Carbon;
// Load all external busy windows with ±40 min buffer
$busyWindows = BusyWindowService::getBusyRanges();
@endphp
@include('partials.flash')
<x-app-layout>
<div class="container mx-auto my-6">
<div class="flex justify-between items-center mb-4">
<h2 class="text-2xl font-semibold">
Calendar: {{ $start->toFormattedDateString() }} {{ $end->toFormattedDateString() }}
</h2>
<div class="space-x-2">
<a href="{{ route('admin.calendar', ['week' => $weekOffset - 1]) }}"
class="px-3 py-1 bg-gray-200 rounded hover:bg-gray-300"> Previous</a>
<a href="{{ route('admin.calendar') }}"
class="px-3 py-1 bg-blue-200 rounded hover:bg-blue-300">This Week</a>
<a href="{{ route('admin.calendar', ['week' => $weekOffset + 1]) }}"
class="px-3 py-1 bg-gray-200 rounded hover:bg-gray-300">Next </a>
</div>
</div>
<div class="mb-3 text-sm">
<span class="inline-block px-2 py-1 rounded bg-green-100 border">Free</span>
<span class="inline-block px-2 py-1 rounded bg-red-200 border ml-2">Booked</span>
<span class="inline-block px-2 py-1 rounded bg-yellow-200 border ml-2">Closed (Admin)</span>
<span class="inline-block px-2 py-1 rounded bg-amber-200 border ml-2">Busy (External)</span>
<span class="inline-block px-2 py-1 rounded bg-gray-100 border ml-2">Closed (Past/ 2h)</span>
</div>
@php
$times = ['09:00:00','10:00:00','11:00:00','14:00:00','15:00:00','16:00:00'];
@endphp
<table class="w-full border-collapse border border-gray-300">
<thead>
<tr class="bg-gray-100">
<th class="border p-2">Time</th>
@for ($i = 0; $i < 5; $i++) {{-- MonFri --}}
<th class="border p-2">
{{ $start->copy()->addDays($i)->format('D d M') }}
</th>
@endfor
</tr>
</thead>
<tbody>
@foreach ($times as $time)
<tr>
<td class="border p-2 font-medium">{{ substr($time, 0, 5) }}</td>
@for ($weekday = 1; $weekday <= 5; $weekday++) {{-- 1=Mon . 5=Fri --}}
@php
$date = $start->copy()->addDays($weekday - 1)->toDateString();
// Find the recurring slot for this weekday+time
$slot = $slots->first(function($s) use ($weekday, $time) {
return (int)$s->weekday === $weekday && $s->time === $time;
});
// Existing booking for that visible date?
$booking = $slot ? $slot->bookings->firstWhere('date', $date) : null;
// 2-hour rule
$sessionStart = Carbon::createFromFormat('Y-m-d H:i:s', $date.' '.$time, $now->timezone);
$minutesUntil = $now->diffInMinutes($sessionStart, false);
$tooSoon = $minutesUntil <= 120;
// External busy window check (±40 min buffer already applied)
$isExternalBusy = BusyWindowService::isInBusyWindow($sessionStart, $busyWindows);
// Assign background class
$class = 'border p-2 text-center ';
if ($booking?->status === 'booked') $class .= 'bg-red-200';
elseif ($booking?->status === 'blocked') $class .= 'bg-yellow-200';
elseif ($isExternalBusy) $class .= 'bg-amber-200';
elseif ($slot && !$booking && !$tooSoon) $class .= 'bg-green-100';
else $class .= 'bg-gray-100';
@endphp
<td class="{{ $class }}">
@if ($isExternalBusy)
Busy (External)
@elseif ($booking)
{{ $booking->status === 'blocked' ? 'Closed' : 'Booked' }}
@if ($booking->status === 'booked' && $booking->student_name)
<br><span class="text-xs">{{ $booking->student_name }}</span>
@endif
@elseif (!$slot)
Not seeded
@elseif ($tooSoon || $minutesUntil < 0)
Closed
@else
@php $isStudent = isset($viewer) && $viewer === 'student'; @endphp
@if ($slot)
@if ($isStudent)
<div class="flex items-center justify-center gap-3">
<a href="{{ route('student.bookings.create', ['date' => $date, 'slot_id' => $slot->id]) }}"
class="underline text-blue-700 hover:text-blue-900">
Book
</a>
<a href="{{ route('student.bookings.series.create', ['date' => $date, 'slot_id' => $slot->id, 'weeks' => 6]) }}"
class="underline text-purple-700 hover:text-purple-900">
Book series
</a>
</div>
@else
<div class="flex items-center justify-center gap-3">
<a href="{{ route('admin.bookings.create', ['date' => $date, 'slot_id' => $slot->id]) }}"
class="underline text-blue-700 hover:text-blue-900">Book</a>
<a href="{{ route('admin.bookings.block.create', ['date' => $date, 'slot_id' => $slot->id]) }}"
class="underline text-amber-700 hover:text-amber-900">Close</a>
<a href="{{ route('admin.bookings.series.create', ['date' => $date, 'slot_id' => $slot->id, 'weeks' => 6]) }}"
class="underline text-purple-700 hover:text-purple-900">Block booking</a>
</div>
@endif
@else
Free
@endif
@endif
</td>
@endfor
</tr>
@endforeach
</tbody>
</table>
</div>
</x-app-layout>