291 lines
15 KiB
PHP
291 lines
15 KiB
PHP
<div>
|
|
@if ($canReserve || $hasReserved || $isGuest)
|
|
<div class="md:self-end">
|
|
@if ($isGuest)
|
|
<!-- Guest - Show Reserve Button with Login Redirect -->
|
|
<div class="mb-3 text-sm">
|
|
{{ __('Attendance') }}
|
|
</div>
|
|
<div class="flex gap-3">
|
|
<button
|
|
onclick="window.location.href = '{{ route('login') }}?redirect=' + encodeURIComponent(window.location.href)"
|
|
class="inline-flex items-center px-4 py-2 bg-theme-brand border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-opacity-90 focus:bg-opacity-90 active:bg-opacity-90 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-25 transition ease-in-out duration-150"
|
|
>
|
|
{{ __('Reserve a spot') }}
|
|
</button>
|
|
</div>
|
|
@if ($reservationCount >= timebank_config('reactions.reserve.count_public_threshold', 5))
|
|
<div class="mt-2 text-sm text-theme-secondary">
|
|
{{ $reservationCount }} {{ $reservationCount === 1 ? __('reservation') : __('reservations') }}
|
|
</div>
|
|
@endif
|
|
@elseif ($hasReserved)
|
|
<!-- Already Reserved - Show Cancel Button -->
|
|
<div class="mb-3 text-sm">{{ __('You have reserved') }}</div>
|
|
<div class="flex gap-3">
|
|
<x-jetstream.secondary-button
|
|
wire:click="openCancelModal"
|
|
wire:loading.attr="disabled"
|
|
>
|
|
{{ __('Cancel your reservation') }}
|
|
</x-jetstream.secondary-button>
|
|
|
|
@if($isOrganizer && $reservationCount > 0)
|
|
<x-jetstream.secondary-button
|
|
wire:click="openReservationsModal"
|
|
wire:loading.attr="disabled"
|
|
>
|
|
{{ __('List') }}
|
|
</x-jetstream.secondary-button>
|
|
@endif
|
|
</div>
|
|
@else
|
|
<!-- Not Reserved - Show Reserve Button -->
|
|
<div class="mb-3 text-sm">
|
|
{{ __('Attendance') }}
|
|
</div>
|
|
<div class="flex gap-3">
|
|
<x-jetstream.button
|
|
wire:click="openConfirmModal"
|
|
wire:loading.attr="disabled"
|
|
class="bg-theme-brand hover:bg-opacity-90"
|
|
>
|
|
{{ __('Reserve a spot') }}
|
|
</x-jetstream.button>
|
|
|
|
@if($isOrganizer && $reservationCount > 0)
|
|
<x-jetstream.secondary-button
|
|
wire:click="openReservationsModal"
|
|
wire:loading.attr="disabled"
|
|
>
|
|
{{ __('List') }}
|
|
</x-jetstream.secondary-button>
|
|
@endif
|
|
</div>
|
|
@endif
|
|
|
|
@if ($reservationCount >= timebank_config('reactions.reserve.count_public_threshold', 5))
|
|
<div class="mt-2 text-sm text-theme-secondary">
|
|
{{ $reservationCount }} {{ $reservationCount === 1 ? __('reservation') : __('reservations') }}
|
|
</div>
|
|
@endif
|
|
</div>
|
|
@endif
|
|
|
|
<!-- Reservation Confirmation Modal -->
|
|
<x-jetstream.dialog-modal wire:model.live="showConfirmModal" maxWidth="2xl">
|
|
<x-slot name="title">
|
|
{{ __('Confirm reservation') }}
|
|
</x-slot>
|
|
|
|
<x-slot name="content">
|
|
<div class="space-y-4">
|
|
<p class="text-theme-primary">{{ __('Are you sure you want to reserve a spot for this event?') }}</p>
|
|
|
|
@if($post && $post->translations->first())
|
|
<div class="bg-theme-surface rounded-lg p-4 border">
|
|
<table class="w-full">
|
|
<tbody>
|
|
<tr>
|
|
<td class="py-2 pr-4 font-semibold text-theme-primary w-1/3">{{ __('Event') }}</td>
|
|
<td class="py-2 text-theme-primary">{{ $post->translations->first()->title }}</td>
|
|
</tr>
|
|
|
|
@if(isset($post->meeting))
|
|
@if($post->meeting->venue)
|
|
<tr>
|
|
<td class="py-2 pr-4 font-semibold text-theme-primary w-1/3">{{ __('Location') }}</td>
|
|
<td class="py-2 text-theme-primary">{{ $post->meeting->venue }}</td>
|
|
</tr>
|
|
@endif
|
|
|
|
@if($post->meeting->address)
|
|
<tr>
|
|
<td class="py-2 pr-4 font-semibold text-theme-primary w-1/3">{{ __('Address') }}</td>
|
|
<td class="py-2 text-theme-primary">
|
|
<a href="https://www.openstreetmap.org/search?query={{ urlencode($post->meeting->address) }}"
|
|
target="_blank"
|
|
class="underline hover:text-theme-secondary">
|
|
{{ $post->meeting->address }}
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
@endif
|
|
|
|
@if($post->meeting->from)
|
|
<tr>
|
|
<td class="py-2 pr-4 font-semibold text-theme-primary w-1/3">{{ __('Date & Time') }}</td>
|
|
<td class="py-2 text-theme-primary">{{ \Illuminate\Support\Carbon::parse($post->meeting->from)->isoFormat('dddd D MMMM YYYY, H:mm') }} {{ __('hour') }}</td>
|
|
</tr>
|
|
@endif
|
|
@endif
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</x-slot>
|
|
|
|
<x-slot name="footer">
|
|
<x-jetstream.secondary-button no-spinner wire:click="$set('showConfirmModal', false)">
|
|
{{ __('Cancel') }}
|
|
</x-jetstream.secondary-button>
|
|
|
|
<x-jetstream.button wire:click="confirmReservation" class="ml-3 bg-theme-brand">
|
|
{{ __('Confirm reservation') }}
|
|
</x-jetstream.button>
|
|
</x-slot>
|
|
</x-jetstream.dialog-modal>
|
|
|
|
<!-- Cancellation Confirmation Modal -->
|
|
<x-jetstream.dialog-modal wire:model.live="showCancelModal" maxWidth="2xl">
|
|
<x-slot name="title">
|
|
{{ __('Cancel reservation') }}
|
|
</x-slot>
|
|
|
|
<x-slot name="content">
|
|
<div class="space-y-4">
|
|
<p class="text-theme-primary">{{ __('Are you sure you want to cancel your reservation for this event?') }}</p>
|
|
|
|
@if($post && $post->translations->first())
|
|
<div class="bg-theme-surface rounded-lg p-4 border">
|
|
<table class="w-full">
|
|
<tbody>
|
|
<tr>
|
|
<td class="py-2 pr-4 font-semibold text-theme-primary w-1/3">{{ __('Event') }}</td>
|
|
<td class="py-2 text-theme-primary">{{ $post->translations->first()->title }}</td>
|
|
</tr>
|
|
|
|
@if(isset($post->meeting))
|
|
@if($post->meeting->venue)
|
|
<tr>
|
|
<td class="py-2 pr-4 font-semibold text-theme-primary w-1/3">{{ __('Location') }}</td>
|
|
<td class="py-2 text-theme-primary">{{ $post->meeting->venue }}</td>
|
|
</tr>
|
|
@endif
|
|
|
|
@if($post->meeting->address)
|
|
<tr>
|
|
<td class="py-2 pr-4 font-semibold text-theme-primary w-1/3">{{ __('Address') }}</td>
|
|
<td class="py-2 text-theme-primary">
|
|
<a href="https://www.openstreetmap.org/search?query={{ urlencode($post->meeting->address) }}"
|
|
target="_blank"
|
|
class="underline hover:text-theme-secondary">
|
|
{{ $post->meeting->address }}
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
@endif
|
|
|
|
@if($post->meeting->from)
|
|
<tr>
|
|
<td class="py-2 pr-4 font-semibold text-theme-primary w-1/3">{{ __('Date & Time') }}</td>
|
|
<td class="py-2 text-theme-primary">{{ \Illuminate\Support\Carbon::parse($post->meeting->from)->isoFormat('dddd D MMMM YYYY, H:mm') }} {{ __('hour') }}</td>
|
|
</tr>
|
|
@endif
|
|
@endif
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</x-slot>
|
|
|
|
<x-slot name="footer">
|
|
<x-jetstream.secondary-button no-spinner wire:click="$set('showCancelModal', false)">
|
|
{{ __('Keep reservation') }}
|
|
</x-jetstream.secondary-button>
|
|
|
|
<x-jetstream.button wire:click="confirmCancellation" class="ml-3">
|
|
{{ __('Cancel reservation') }}
|
|
</x-jetstream.button>
|
|
</x-slot>
|
|
</x-jetstream.dialog-modal>
|
|
|
|
<!-- Reservations List Modal (Organizer Only) -->
|
|
<x-jetstream.dialog-modal wire:model.live="showReservationsModal" maxWidth="2xl" closeButton="true">
|
|
<x-slot name="title">
|
|
{{ __('Reservations') }} ({{ $reservationCount }})
|
|
</x-slot>
|
|
|
|
<x-slot name="content">
|
|
<div class="space-y-4">
|
|
@foreach(['App\\Models\\User' => __('Users'), 'App\\Models\\Organization' => __('Organizations'), 'App\\Models\\Bank' => __('Banks'), 'App\\Models\\Admin' => __('Admins')] as $type => $label)
|
|
@php
|
|
$reacters = $reservationsByType[$type] ?? [];
|
|
@endphp
|
|
@if(count($reacters) > 0)
|
|
<div class="space-y-2">
|
|
<h4 class="text-sm font-medium text-theme-secondary">{{ $label }} ({{ count($reacters) }})</h4>
|
|
<div class="space-y-2">
|
|
@foreach($reacters as $reacter)
|
|
<div class="flex items-center space-x-3 py-2">
|
|
@if($reacter->profile_photo_path)
|
|
<img class="h-10 w-10 rounded-full profile-photo object-cover"
|
|
src="{{ url(Storage::url($reacter->profile_photo_path)) }}"
|
|
alt="{{ $reacter->name }}">
|
|
@else
|
|
<div class="h-10 w-10 rounded-full bg-theme-primary flex items-center justify-center text-white font-semibold">
|
|
{{ substr($reacter->name, 0, 1) }}
|
|
</div>
|
|
@endif
|
|
<div class="flex-1">
|
|
<div class="text-sm font-medium text-theme-primary">
|
|
<a href="{{ url(strtolower(class_basename($reacter)) . '/' . $reacter->id) }}"
|
|
class="hover:underline">
|
|
{{ $reacter->name }}
|
|
</a>
|
|
</div>
|
|
@php
|
|
$location = method_exists($reacter, 'getLocationFirst') ? $reacter->getLocationFirst() : null;
|
|
@endphp
|
|
@if($location && isset($location['name_short']))
|
|
<div class="text-xs text-theme-secondary">{{ $location['name_short'] }}</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
@endif
|
|
@endforeach
|
|
|
|
@if($reservationCount > 0)
|
|
<!-- Message All Reserved Participants -->
|
|
<div class="mt-6 pt-6 border-t border-theme-primary">
|
|
<h4 class="text-sm font-medium text-theme-secondary mb-3">{{ __('Send an update to all participants') }}</h4>
|
|
<div class="space-y-3">
|
|
<x-textarea
|
|
wire:model.live="messageToReserved"
|
|
rows="4"
|
|
maxlength="300"
|
|
placeholder="{{ __('Enter your message (max 300 characters)') }}"
|
|
class="mt-1 block w-full border-gray-300 rounded-md shadow-sm"
|
|
/>
|
|
|
|
<div class="flex justify-between items-center">
|
|
<span class="text-xs text-theme-secondary">
|
|
{{ strlen($messageToReserved ?? '') }}/300 {{ __('characters') }}
|
|
</span>
|
|
<x-jetstream.button
|
|
wire:click="sendMessageToReserved"
|
|
wire:loading.attr="disabled"
|
|
class="bg-theme-brand"
|
|
>
|
|
{{ __('Send Message') }}
|
|
</x-jetstream.button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</x-slot>
|
|
|
|
<x-slot name="footer">
|
|
<x-jetstream.secondary-button no-spinner wire:click="$set('showReservationsModal', false)">
|
|
{{ __('Close') }}
|
|
</x-jetstream.secondary-button>
|
|
</x-slot>
|
|
</x-jetstream.dialog-modal>
|
|
</div>
|