Feat: Add teamer info popup
This commit is contained in:
@@ -4,16 +4,26 @@ namespace App\Controller\Admin\Teamer;
|
|||||||
|
|
||||||
use App\Entity\Teamer;
|
use App\Entity\Teamer;
|
||||||
use App\Model\AjaxModalResponseDto;
|
use App\Model\AjaxModalResponseDto;
|
||||||
|
use App\Repository\DispositionRepository;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
|
||||||
class InfoController extends AbstractController
|
class InfoController extends AbstractController
|
||||||
{
|
{
|
||||||
|
public function __construct(private readonly DispositionRepository $dispositionRepository)
|
||||||
|
{}
|
||||||
|
|
||||||
#[Route('/admin/teamer/info/{uuid}', name: 'app_admin_teamer_info')]
|
#[Route('/admin/teamer/info/{uuid}', name: 'app_admin_teamer_info')]
|
||||||
public function index(Teamer $teamer): JsonResponse
|
public function index(Teamer $teamer): JsonResponse
|
||||||
{
|
{
|
||||||
|
$recentDispositions = $this->dispositionRepository->getRecentByTeamer($teamer);
|
||||||
|
|
||||||
$response = new AjaxModalResponseDto();
|
$response = new AjaxModalResponseDto();
|
||||||
|
$response->setContent($this->renderView('admin/teamer/info.html.twig', [
|
||||||
|
'teamer' => $teamer,
|
||||||
|
'recentDispositions' => $recentDispositions,
|
||||||
|
]));
|
||||||
|
|
||||||
return $this->json($response);
|
return $this->json($response);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace App\Repository;
|
namespace App\Repository;
|
||||||
|
|
||||||
use App\Entity\Application;
|
|
||||||
use App\Entity\Assignment;
|
use App\Entity\Assignment;
|
||||||
use App\Entity\Disposition;
|
use App\Entity\Disposition;
|
||||||
use App\Entity\Teamer;
|
use App\Entity\Teamer;
|
||||||
@@ -94,4 +93,20 @@ class DispositionRepository extends ServiceEntityRepository
|
|||||||
->getResult()
|
->getResult()
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getRecentByTeamer(Teamer $teamer, int $limit = 5): array
|
||||||
|
{
|
||||||
|
$qb = $this->createQueryBuilder('disposition');
|
||||||
|
|
||||||
|
return $qb
|
||||||
|
->select('disposition', 'assignment', 'destination')
|
||||||
|
->innerJoin('disposition.assignment', 'assignment')
|
||||||
|
->innerJoin('assignment.destination', 'destination')
|
||||||
|
->where($qb->expr()->eq('disposition.teamer', ':teamer'))
|
||||||
|
->setParameter('teamer', $teamer)
|
||||||
|
->orderBy('destination.dateFrom', 'DESC')
|
||||||
|
->getQuery()
|
||||||
|
->getResult()
|
||||||
|
;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
Busbegleitung
|
Busbegleitung
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
ab {{ assignment.pickup|bpn_pickup_label }}
|
{{ assignment.pickup|bpn_pickup_label }}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
Busbegleitung
|
Busbegleitung
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
ab {{ assignment.pickup|bpn_pickup_label }}
|
{{ assignment.pickup|bpn_pickup_label }}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="font-bold">
|
<div class="font-bold">
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<h3 class="text-lg font-bold">
|
||||||
|
Lizenzen
|
||||||
|
</h3>
|
||||||
|
<ul class="pb-4 divide-y divide-gray-200">
|
||||||
|
{% for license in teamer.licenses %}
|
||||||
|
<li class="py-2">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<span class="flex-1">{{ license.type|license_label }}</span>
|
||||||
|
<div class="flex items-center space-x-2">
|
||||||
|
{% if is_granted('DOWNLOAD', license.certificate) %}
|
||||||
|
<a href="{{ path('app_common_download', { 'uuid': license.certificate.uuid }) }}"
|
||||||
|
target="_blank"
|
||||||
|
title="Download Nachweis">
|
||||||
|
{{ icon('download', 'w-4 h-4') }}
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
<span>{{ license.date|date('m/Y') }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
<li class="py-2">
|
||||||
|
-
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<h3 class="text-lg font-bold">
|
||||||
|
Fortbildungen
|
||||||
|
</h3>
|
||||||
|
<ul class="pb-4 divide-y divide-gray-200">
|
||||||
|
{% for attendance in teamer.trainingAttendances %}
|
||||||
|
<li class="py-2">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<span class="flex-1">{{ attendance.training.name }}</span>
|
||||||
|
<span>{{ attendance.date|date('m/Y') }}</span>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
<li class="py-2">
|
||||||
|
-
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
@@ -34,9 +34,16 @@
|
|||||||
{% for application in applications %}
|
{% for application in applications %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ path('app_admin_teamer_profile', { 'uuid': application.teamer.uuid, 'r': return_url() }) }}">
|
<button type="button"
|
||||||
{{ application.teamer }}
|
class="flex items-center space-x-1"
|
||||||
</a>
|
{{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }}
|
||||||
|
{{ stimulus_action('modal-button', 'ajax', null, {
|
||||||
|
'title': 'Teamerinfo ' ~ application.teamer,
|
||||||
|
'url': path('app_admin_teamer_info', { 'uuid': application.teamer.uuid })
|
||||||
|
}) }}>
|
||||||
|
<span>{{ application.teamer }}</span>
|
||||||
|
{{ icon('info', 'w-4 h-4') }}
|
||||||
|
</button>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{ application.requests|nl2br|default('-') }}
|
{{ application.requests|nl2br|default('-') }}
|
||||||
@@ -117,9 +124,16 @@
|
|||||||
{% for disposition in dispositions %}
|
{% for disposition in dispositions %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ path('app_admin_teamer_profile', { 'uuid': disposition.teamer.uuid, 'r': return_url() }) }}">
|
<button type="button"
|
||||||
{{ disposition.teamer }}
|
class="flex items-center space-x-1"
|
||||||
</a>
|
{{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }}
|
||||||
|
{{ stimulus_action('modal-button', 'ajax', null, {
|
||||||
|
'title': 'Teamerinfo ' ~ disposition.teamer,
|
||||||
|
'url': path('app_admin_teamer_info', { 'uuid': disposition.teamer.uuid })
|
||||||
|
}) }}>
|
||||||
|
<span>{{ disposition.teamer }}</span>
|
||||||
|
{{ icon('info', 'w-4 h-4') }}
|
||||||
|
</button>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{ disposition.remarks|nl2br|default('-') }}
|
{{ disposition.remarks|nl2br|default('-') }}
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
<div class="flex items-start">
|
||||||
|
<div class="flex-1 pr-8">
|
||||||
|
{% include '_partials/_teamer_training_info.html.twig' %}
|
||||||
|
{% include '_partials/_teamer_license_info.html.twig' %}
|
||||||
|
<h2 class="text-lg font-bold">
|
||||||
|
Zustiege
|
||||||
|
</h2>
|
||||||
|
<ul class="pb-8 divide-y divide-gray-200">
|
||||||
|
{% for pickup in teamer.pickups %}
|
||||||
|
<li class="py-2">
|
||||||
|
{{ pickup|bpn_pickup_label }}
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
<h2 class="text-lg font-bold">
|
||||||
|
Letzte Einsätze
|
||||||
|
</h2>
|
||||||
|
<ul class="pb-4 divide-y divide-gray-200">
|
||||||
|
{% for disposition in recentDispositions %}
|
||||||
|
{% set destination = disposition.assignment.destination %}
|
||||||
|
<li class="py-2 flex items-start">
|
||||||
|
<span class="flex-1">{{ destination.product }}</span>
|
||||||
|
<span>{{ destination.dateFrom|date('d.m.y') }} -<br>{{ destination.dateTo|date('d.m.y') }}</span>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
<li class="py-2">
|
||||||
|
-
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{% if teamer.photo %}
|
||||||
|
<img src="{{ asset(teamer.photo.filename | imagine_filter('profile')) }}"
|
||||||
|
class="w-32 h-auto border-2 border-primary"
|
||||||
|
alt="{{ teamer.firstName }}">
|
||||||
|
{% else %}
|
||||||
|
<div class="border-2 border-primary">
|
||||||
|
{{ icon('user', 'w-32 h-32 text-gray-200') }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -50,30 +50,8 @@
|
|||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="pb-8 divide-y divide-gray-200">
|
|
||||||
{% for type in ['ski', 'snowboard'] %}
|
{% include '_partials/_teamer_license_info.html.twig' %}
|
||||||
<li class="py-2">
|
|
||||||
<div class="flex items-center justify-between">
|
|
||||||
<span class="flex-1">{{ type|license_label }}</span>
|
|
||||||
{% set license = teamer.licenseOfType(type) %}
|
|
||||||
{% if license %}
|
|
||||||
<div class="flex items-center space-x-2">
|
|
||||||
<span>{{ license.date|date('m/Y') }}</span>
|
|
||||||
{% if is_granted('DOWNLOAD', license.certificate) %}
|
|
||||||
<a href="{{ path('app_common_download', { 'uuid': license.certificate.uuid }) }}"
|
|
||||||
target="_blank"
|
|
||||||
title="Download Nachweis">
|
|
||||||
{{ icon('download', 'w-4 h-4') }}
|
|
||||||
</a>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
{{ icon('minus', 'w-4 h-4') }}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<div class="grid grid-cols-2 gap-8">
|
<div class="grid grid-cols-2 gap-8">
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
Reference in New Issue
Block a user