Feat: Implement availabilities
This commit is contained in:
@@ -141,9 +141,15 @@
|
|||||||
<symbol id="icon-folder" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24">
|
<symbol id="icon-folder" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24">
|
||||||
<path d="M2.25 12.75V12A2.25 2.25 0 014.5 9.75h15A2.25 2.25 0 0121.75 12v.75m-8.69-6.44l-2.12-2.12a1.5 1.5 0 00-1.061-.44H4.5A2.25 2.25 0 002.25 6v12a2.25 2.25 0 002.25 2.25h15A2.25 2.25 0 0021.75 18V9a2.25 2.25 0 00-2.25-2.25h-5.379a1.5 1.5 0 01-1.06-.44z" stroke-linecap="round" stroke-linejoin="round"/>
|
<path d="M2.25 12.75V12A2.25 2.25 0 014.5 9.75h15A2.25 2.25 0 0121.75 12v.75m-8.69-6.44l-2.12-2.12a1.5 1.5 0 00-1.061-.44H4.5A2.25 2.25 0 002.25 6v12a2.25 2.25 0 002.25 2.25h15A2.25 2.25 0 0021.75 18V9a2.25 2.25 0 00-2.25-2.25h-5.379a1.5 1.5 0 01-1.06-.44z" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
</symbol>
|
</symbol>
|
||||||
<symbol id="icon-bus" fill="currentColor" stroke="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
<symbol id="icon-bus" xmlns="http://www.w3.org/2000/svg" stroke-width="1.5" viewBox="0 0 24 24" stroke="currentColor" fill="none">
|
||||||
<!-- Font Awesome Pro 5.15.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) -->
|
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
|
||||||
<path d="M488 128h-8V80c0-44.8-99.2-80-224-80S32 35.2 32 80v48h-8c-13.25 0-24 10.74-24 24v80c0 13.25 10.75 24 24 24h8v160c0 17.67 14.33 32 32 32v32c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32v-32h192v32c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32v-32h6.4c16 0 25.6-12.8 25.6-25.6V256h8c13.25 0 24-10.75 24-24v-80c0-13.26-10.75-24-24-24zM112 400c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm16-112c-17.67 0-32-14.33-32-32V128c0-17.67 14.33-32 32-32h256c17.67 0 32 14.33 32 32v128c0 17.67-14.33 32-32 32H128zm272 112c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32z"/>
|
<path d="M6 17m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" />
|
||||||
|
<path d="M18 17m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" />
|
||||||
|
<path d="M4 17h-2v-11a1 1 0 0 1 1 -1h14a5 7 0 0 1 5 7v5h-2m-4 0h-8" />
|
||||||
|
<path d="M16 5l1.5 7l4.5 0" />
|
||||||
|
<path d="M2 10l15 0" />
|
||||||
|
<path d="M7 5l0 5" />
|
||||||
|
<path d="M12 5l0 5" />
|
||||||
</symbol>
|
</symbol>
|
||||||
<symbol id="icon-ski" fill="currentColor" stroke="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
<symbol id="icon-ski" fill="currentColor" stroke="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
||||||
<!--! Font Awesome Pro 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. -->
|
<!--! Font Awesome Pro 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. -->
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
@@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller\Admin\System\Availability;
|
||||||
|
|
||||||
|
use App\Entity\Availability;
|
||||||
|
use App\Form\AvailabilityType;
|
||||||
|
use App\Model\AjaxModalResponseDto;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
||||||
|
|
||||||
|
class CreateController extends AbstractController
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private readonly EntityManagerInterface $entityManager,
|
||||||
|
private readonly LoggerInterface $logger
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route('/admin/system/availability/create', name: 'app_admin_system_availability_create')]
|
||||||
|
#[IsGranted('ROLE_ADMIN')]
|
||||||
|
public function index(Request $request): JsonResponse
|
||||||
|
{
|
||||||
|
$response = new AjaxModalResponseDto();
|
||||||
|
$action = $this->generateUrl('app_admin_system_availability_create');
|
||||||
|
|
||||||
|
$availability = new Availability();
|
||||||
|
$form = $this->createForm(AvailabilityType::class, $availability, ['action' => $action, 'ajax_submit' => true]);
|
||||||
|
$form->handleRequest($request);
|
||||||
|
|
||||||
|
if ($form->isSubmitted() && $form->isValid()) {
|
||||||
|
$this->entityManager->persist($availability);
|
||||||
|
$this->entityManager->flush();
|
||||||
|
|
||||||
|
$this->addFlash('success', 'Der Zeitraum wurde hinzugefügt.');
|
||||||
|
$this->logger->info('Add availability', [
|
||||||
|
'availability' => $availability,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$redirectUrl = $this->generateUrl('app_admin_system_availability_index');
|
||||||
|
$response->setCloseAndRedirect($redirectUrl);
|
||||||
|
} else {
|
||||||
|
$content = $this->renderView('admin/system/availability/create.html.twig', [
|
||||||
|
'form' => $form,
|
||||||
|
]);
|
||||||
|
$response->setContent($content);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json($response);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller\Admin\System\Availability;
|
||||||
|
|
||||||
|
use App\Entity\Availability;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
||||||
|
|
||||||
|
class DeleteController extends AbstractController
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private readonly EntityManagerInterface $entityManager,
|
||||||
|
private readonly LoggerInterface $logger
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route('/admin/system/availability/delete/{id}', name: 'app_admin_system_availability_delete', methods: ['POST'])]
|
||||||
|
#[IsGranted('ROLE_ADMIN')]
|
||||||
|
public function index(Availability $availability): Response
|
||||||
|
{
|
||||||
|
$this->entityManager->remove($availability);
|
||||||
|
$this->entityManager->flush();
|
||||||
|
|
||||||
|
$this->addFlash('success', 'Die Verfügbarkeit wurde gelöscht');
|
||||||
|
$this->logger->info('Delete availability', [
|
||||||
|
'availability' => $availability,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $this->redirectToRoute('app_admin_system_availability_index');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller\Admin\System\Availability;
|
||||||
|
|
||||||
|
use App\Repository\AvailabilityRepository;
|
||||||
|
use Knp\Component\Pager\PaginatorInterface;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
||||||
|
|
||||||
|
class IndexController extends AbstractController
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private readonly AvailabilityRepository $availabilityRepository,
|
||||||
|
private readonly PaginatorInterface $paginator
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route('/admin/system/availability', name: 'app_admin_system_availability_index')]
|
||||||
|
#[IsGranted('ROLE_ADMIN')]
|
||||||
|
public function index(Request $request): Response
|
||||||
|
{
|
||||||
|
$query = $this
|
||||||
|
->availabilityRepository
|
||||||
|
->getListQuery()
|
||||||
|
;
|
||||||
|
|
||||||
|
$pagination = $this->paginator->paginate(
|
||||||
|
$query,
|
||||||
|
$request->query->getInt('page', 1),
|
||||||
|
10,
|
||||||
|
[
|
||||||
|
'defaultSortFieldName' => 'availability.dateFrom',
|
||||||
|
'defaultSortDirection' => 'asc',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->render('admin/system/availability/index.html.twig', [
|
||||||
|
'pagination' => $pagination,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,11 +4,12 @@ namespace App\Controller\Admin\System\Fee;
|
|||||||
|
|
||||||
use App\Entity\Fee;
|
use App\Entity\Fee;
|
||||||
use App\Form\FeeType;
|
use App\Form\FeeType;
|
||||||
|
use App\Model\AjaxModalResponseDto;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
||||||
|
|
||||||
@@ -22,10 +23,13 @@ class CreateController extends AbstractController
|
|||||||
|
|
||||||
#[Route('/admin/system/fee/create', name: 'app_admin_system_fee_create')]
|
#[Route('/admin/system/fee/create', name: 'app_admin_system_fee_create')]
|
||||||
#[IsGranted('ROLE_ADMIN')]
|
#[IsGranted('ROLE_ADMIN')]
|
||||||
public function index(Request $request): Response
|
public function index(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
|
$response = new AjaxModalResponseDto();
|
||||||
|
$action = $this->generateUrl('app_admin_system_fee_create');
|
||||||
|
|
||||||
$fee = new Fee();
|
$fee = new Fee();
|
||||||
$form = $this->createForm(FeeType::class, $fee);
|
$form = $this->createForm(FeeType::class, $fee, ['action' => $action, 'ajax_submit' => true]);
|
||||||
$form->handleRequest($request);
|
$form->handleRequest($request);
|
||||||
|
|
||||||
if ($form->isSubmitted() && $form->isValid()) {
|
if ($form->isSubmitted() && $form->isValid()) {
|
||||||
@@ -37,11 +41,15 @@ class CreateController extends AbstractController
|
|||||||
'fee' => $fee->getName(),
|
'fee' => $fee->getName(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return $this->redirectToRoute('app_admin_system_fee_index');
|
$redirectUrl = $this->generateUrl('app_admin_system_fee_index');
|
||||||
|
$response->setCloseAndRedirect($redirectUrl);
|
||||||
|
} else {
|
||||||
|
$content = $this->renderView('admin/system/fee/create.html.twig', [
|
||||||
|
'form' => $form
|
||||||
|
]);
|
||||||
|
$response->setContent($content);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->render('admin/system/fee/create.html.twig', [
|
return $this->json($response);
|
||||||
'form' => $form
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Controller\Admin\System\Fee;
|
|
||||||
|
|
||||||
use App\Entity\Fee;
|
|
||||||
use App\Form\FeeType;
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
use Psr\Log\LoggerInterface;
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
|
||||||
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
|
||||||
|
|
||||||
class EditController extends AbstractController
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly EntityManagerInterface $entityManager,
|
|
||||||
private readonly LoggerInterface $logger
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
#[Route('/admin/system/fee/edit/{id}', name: 'app_admin_system_fee_edit')]
|
|
||||||
#[IsGranted('ROLE_ADMIN')]
|
|
||||||
public function index(Fee $fee, Request $request): Response
|
|
||||||
{
|
|
||||||
$form = $this->createForm(FeeType::class, $fee);
|
|
||||||
$form->handleRequest($request);
|
|
||||||
|
|
||||||
if ($form->isSubmitted() && $form->isValid()) {
|
|
||||||
$this->entityManager->persist($fee);
|
|
||||||
$this->entityManager->flush();
|
|
||||||
|
|
||||||
$this->addFlash('success', 'Das Honorar wurde aktualisiert');
|
|
||||||
$this->logger->info('Edit fee', [
|
|
||||||
'fee' => $fee->getName(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return $this->redirectToRoute('app_admin_system_fee_index');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->render('admin/system/fee/edit.html.twig', [
|
|
||||||
'form' => $form
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,11 +4,12 @@ namespace App\Controller\Admin\System\Training;
|
|||||||
|
|
||||||
use App\Entity\Training;
|
use App\Entity\Training;
|
||||||
use App\Form\TrainingType;
|
use App\Form\TrainingType;
|
||||||
|
use App\Model\AjaxModalResponseDto;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
||||||
|
|
||||||
@@ -22,10 +23,13 @@ class CreateController extends AbstractController
|
|||||||
|
|
||||||
#[Route('/admin/system/training/create', name: 'app_admin_system_training_create')]
|
#[Route('/admin/system/training/create', name: 'app_admin_system_training_create')]
|
||||||
#[IsGranted('ROLE_ADMIN')]
|
#[IsGranted('ROLE_ADMIN')]
|
||||||
public function index(Request $request): Response
|
public function index(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
|
$response = new AjaxModalResponseDto();
|
||||||
|
$action = $this->generateUrl('app_admin_system_training_create');
|
||||||
|
|
||||||
$training = new Training();
|
$training = new Training();
|
||||||
$form = $this->createForm(TrainingType::class, $training);
|
$form = $this->createForm(TrainingType::class, $training, ['action' => $action, 'ajax_submit' => true]);
|
||||||
$form->handleRequest($request);
|
$form->handleRequest($request);
|
||||||
|
|
||||||
if ($form->isSubmitted() && $form->isValid()) {
|
if ($form->isSubmitted() && $form->isValid()) {
|
||||||
@@ -37,11 +41,15 @@ class CreateController extends AbstractController
|
|||||||
'training' => $training->getName(),
|
'training' => $training->getName(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return $this->redirectToRoute('app_admin_system_training_index');
|
$redirectUrl = $this->generateUrl('app_admin_system_training_index');
|
||||||
|
$response->setCloseAndRedirect($redirectUrl);
|
||||||
|
} else {
|
||||||
|
$content = $this->renderView('admin/system/training/create.html.twig', [
|
||||||
|
'form' => $form
|
||||||
|
]);
|
||||||
|
$response->setContent($content);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->render('admin/system/training/create.html.twig', [
|
return $this->json($response);
|
||||||
'form' => $form
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Controller\Admin\System\Training;
|
|
||||||
|
|
||||||
use App\Entity\Training;
|
|
||||||
use App\Form\TrainingType;
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
use Psr\Log\LoggerInterface;
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
|
||||||
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
|
||||||
|
|
||||||
class EditController extends AbstractController
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly EntityManagerInterface $entityManager,
|
|
||||||
private readonly LoggerInterface $logger
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
#[Route('/admin/system/training/edit/{id}', name: 'app_admin_system_training_edit')]
|
|
||||||
#[IsGranted('ROLE_ADMIN')]
|
|
||||||
public function index(Training $training, Request $request): Response
|
|
||||||
{
|
|
||||||
$form = $this->createForm(TrainingType::class, $training);
|
|
||||||
$form->handleRequest($request);
|
|
||||||
|
|
||||||
if ($form->isSubmitted() && $form->isValid()) {
|
|
||||||
$this->entityManager->flush();
|
|
||||||
|
|
||||||
$this->addFlash('success', 'Die Fortbildung wurde aktualisiert');
|
|
||||||
$this->logger->info('Edit training', [
|
|
||||||
'training' => $training->getName(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return $this->redirectToRoute('app_admin_system_training_index');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->render('admin/system/training/edit.html.twig', [
|
|
||||||
'form' => $form
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Controller\Teamer\Profile;
|
|
||||||
|
|
||||||
use App\Entity\Availability;
|
|
||||||
use App\Entity\User;
|
|
||||||
use App\Repository\AvailabilityRepository;
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
|
||||||
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
|
||||||
|
|
||||||
class AvailabilitiesController extends AbstractController
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly AvailabilityRepository $availabilityRepository,
|
|
||||||
private readonly EntityManagerInterface $entityManager
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
#[Route('/teamer/profile/availabilities', name: 'app_teamer_profile_availabilities')]
|
|
||||||
#[IsGranted('ROLE_TEAMER')]
|
|
||||||
public function index(Request $request): Response
|
|
||||||
{
|
|
||||||
/** @var User $user */
|
|
||||||
$user = $this->getUser();
|
|
||||||
$teamer = $user->getTeamer();
|
|
||||||
|
|
||||||
$selectableAvailabilities = $this->availabilityRepository->getSelectable($teamer);
|
|
||||||
$form = $this->createFormBuilder($teamer)
|
|
||||||
->add('availabilities', EntityType::class, [
|
|
||||||
'label' => false,
|
|
||||||
'class' => Availability::class,
|
|
||||||
'choice_label' => function($choice) {
|
|
||||||
return sprintf('%s - %s', $choice->getDateFrom()->format('d.m.Y'), $choice->getDateTo()->format('d.m.Y'));
|
|
||||||
},
|
|
||||||
'choices' => $selectableAvailabilities,
|
|
||||||
'multiple' => true,
|
|
||||||
'expanded' => true,
|
|
||||||
])
|
|
||||||
->getForm()
|
|
||||||
;
|
|
||||||
$form->handleRequest($request);
|
|
||||||
|
|
||||||
if ($form->isSubmitted() && $form->isValid()) {
|
|
||||||
$this->entityManager->flush();
|
|
||||||
|
|
||||||
return $this->redirectToRoute('app_teamer_profile_availabilities');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->render('teamer/profile/availabilities.html.twig', [
|
|
||||||
'availabilities' => $teamer->getAvailabilities(),
|
|
||||||
'selectableAvailabilities' => $selectableAvailabilities,
|
|
||||||
'form' => $form,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller\Teamer\Profile\Availability;
|
||||||
|
|
||||||
|
use App\Entity\Availability;
|
||||||
|
use App\Entity\User;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
||||||
|
|
||||||
|
class AddController extends AbstractController
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private readonly EntityManagerInterface $entityManager,
|
||||||
|
private readonly LoggerInterface $logger
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route('/teamer/profile/availability/add/{id}', name: 'app_teamer_profile_availability_add')]
|
||||||
|
#[IsGranted('ROLE_TEAMER')]
|
||||||
|
public function index(Availability $availability): Response
|
||||||
|
{
|
||||||
|
/** @var User $user */
|
||||||
|
$user = $this->getUser();
|
||||||
|
$teamer = $user->getTeamer();
|
||||||
|
|
||||||
|
$teamer->addAvailability($availability);
|
||||||
|
$this->entityManager->flush();
|
||||||
|
|
||||||
|
$this->logger->info('Add availability', [
|
||||||
|
'user' => $user->getUserIdentifier(),
|
||||||
|
'availability' => $availability,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $this->redirectToRoute('app_teamer_profile_availability_index');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller\Teamer\Profile\Availability;
|
||||||
|
|
||||||
|
use App\Entity\Availability;
|
||||||
|
use App\Entity\User;
|
||||||
|
use App\Form\AvailabilityType;
|
||||||
|
use App\Model\AjaxModalResponseDto;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
||||||
|
|
||||||
|
class CreateController extends AbstractController
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private readonly EntityManagerInterface $entityManager,
|
||||||
|
private readonly LoggerInterface $logger
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route('/teamer/profile/availability/create', name: 'app_teamer_profile_availability_create')]
|
||||||
|
#[IsGranted('ROLE_TEAMER')]
|
||||||
|
public function index(Request $request): JsonResponse
|
||||||
|
{
|
||||||
|
$response = new AjaxModalResponseDto();
|
||||||
|
$action = $this->generateUrl('app_teamer_profile_availability_create');
|
||||||
|
|
||||||
|
$availability = new Availability();
|
||||||
|
|
||||||
|
$form = $this->createForm(AvailabilityType::class, $availability, ['action' => $action, 'ajax_submit' => true]);
|
||||||
|
$form->handleRequest($request);
|
||||||
|
|
||||||
|
if ($form->isSubmitted() && $form->isValid()) {
|
||||||
|
/** @var User $user */
|
||||||
|
$user = $this->getUser();
|
||||||
|
$teamer = $user->getTeamer();
|
||||||
|
$teamer
|
||||||
|
->addAvailability($availability)
|
||||||
|
->addCustomAvailability($availability)
|
||||||
|
;
|
||||||
|
|
||||||
|
$this->entityManager->persist($availability);
|
||||||
|
$this->entityManager->flush();
|
||||||
|
|
||||||
|
$this->addFlash('success', 'Der Zeitraum wurde hinzugefügt.');
|
||||||
|
$this->logger->info('Add availability', [
|
||||||
|
'availability' => $availability,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$redirectUrl = $this->generateUrl('app_teamer_profile_availability_index');
|
||||||
|
$response->setCloseAndRedirect($redirectUrl);
|
||||||
|
} else {
|
||||||
|
$content = $this->renderView('teamer/profile/availability/create.html.twig', [
|
||||||
|
'form' => $form,
|
||||||
|
]);
|
||||||
|
$response->setContent($content);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json($response);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller\Teamer\Profile\Availability;
|
||||||
|
|
||||||
|
use App\Entity\Availability;
|
||||||
|
use App\Entity\User;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
||||||
|
|
||||||
|
class DeleteController extends AbstractController
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private readonly EntityManagerInterface $entityManager,
|
||||||
|
private readonly LoggerInterface $logger
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route('/teamer/profile/availability/delete/{id}', name: 'app_teamer_profile_availability_delete')]
|
||||||
|
#[IsGranted('DELETE', subject: 'availability')]
|
||||||
|
public function index(Availability $availability): Response
|
||||||
|
{
|
||||||
|
/** @var User $user */
|
||||||
|
$user = $this->getUser();
|
||||||
|
$teamer = $user->getTeamer();
|
||||||
|
|
||||||
|
if (null === $availability->getOwner()) {
|
||||||
|
$teamer->removeAvailability($availability);
|
||||||
|
} elseif ($teamer === $availability->getOwner()) {
|
||||||
|
$this->entityManager->remove($availability);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->entityManager->flush();
|
||||||
|
|
||||||
|
$this->addFlash('success', 'Der Zeitraum wurde entfernt/gelöscht.');
|
||||||
|
$this->logger->info('Delete availability', [
|
||||||
|
'user' => $this->getUser()->getUserIdentifier(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $this->redirectToRoute('app_teamer_profile_availability_index');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller\Teamer\Profile\Availability;
|
||||||
|
|
||||||
|
use App\Entity\Availability;
|
||||||
|
use App\Entity\User;
|
||||||
|
use App\Repository\AvailabilityRepository;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
||||||
|
|
||||||
|
class IndexController extends AbstractController
|
||||||
|
{
|
||||||
|
public function __construct(private readonly AvailabilityRepository $availabilityRepository)
|
||||||
|
{}
|
||||||
|
|
||||||
|
#[Route('/teamer/profile/availabilities', name: 'app_teamer_profile_availability_index')]
|
||||||
|
#[IsGranted('ROLE_TEAMER')]
|
||||||
|
public function index(): Response
|
||||||
|
{
|
||||||
|
/** @var User $user */
|
||||||
|
$user = $this->getUser();
|
||||||
|
$teamer = $user->getTeamer();
|
||||||
|
|
||||||
|
$availabilities = $teamer->getAvailabilities()->toArray();
|
||||||
|
$selectedAvailabilities = $this->groupRecords($availabilities);
|
||||||
|
|
||||||
|
$availabilities = $this->availabilityRepository->getSelectableForTeamer($teamer);
|
||||||
|
$selectableAvailabilities = $this->groupRecords($availabilities);
|
||||||
|
|
||||||
|
return $this->render('teamer/profile/availability/index.html.twig', [
|
||||||
|
'selectedAvailabilities' => $selectedAvailabilities,
|
||||||
|
'selectableAvailabilities' => $selectableAvailabilities,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function groupRecords(array $records): array
|
||||||
|
{
|
||||||
|
$selectableAvailabilities = [];
|
||||||
|
|
||||||
|
foreach ($records as $record) {
|
||||||
|
/** @var Availability $record */
|
||||||
|
$dateFrom = $record->getDateFrom();
|
||||||
|
$year = $dateFrom->format('Y');
|
||||||
|
$month = (new Carbon($dateFrom))->locale('de_DE')->monthName;
|
||||||
|
|
||||||
|
if (false === isset($selectableAvailabilities[$year])) {
|
||||||
|
$selectableAvailabilities[$year] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false === isset($selectableAvailabilities[$year][$month])) {
|
||||||
|
$selectableAvailabilities[$year][$month] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$selectableAvailabilities[$year][$month][] = $record;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $selectableAvailabilities;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ use Doctrine\Common\Collections\ArrayCollection;
|
|||||||
use Doctrine\Common\Collections\Collection;
|
use Doctrine\Common\Collections\Collection;
|
||||||
use Doctrine\DBAL\Types\Types;
|
use Doctrine\DBAL\Types\Types;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
#[ORM\Entity(repositoryClass: AvailabilityRepository::class)]
|
#[ORM\Entity(repositoryClass: AvailabilityRepository::class)]
|
||||||
class Availability implements BlameableEntityInterface, TimestampableEntityInterface
|
class Availability implements BlameableEntityInterface, TimestampableEntityInterface
|
||||||
@@ -22,9 +23,12 @@ class Availability implements BlameableEntityInterface, TimestampableEntityInter
|
|||||||
private ?int $id = null;
|
private ?int $id = null;
|
||||||
|
|
||||||
#[ORM\Column(type: Types::DATE_IMMUTABLE)]
|
#[ORM\Column(type: Types::DATE_IMMUTABLE)]
|
||||||
|
#[Assert\NotNull(message: 'Bitte gib das Datum an')]
|
||||||
private ?\DateTimeImmutable $dateFrom = null;
|
private ?\DateTimeImmutable $dateFrom = null;
|
||||||
|
|
||||||
#[ORM\Column(type: Types::DATE_IMMUTABLE)]
|
#[ORM\Column(type: Types::DATE_IMMUTABLE)]
|
||||||
|
#[Assert\NotNull(message: 'Bitte gib das Datum an')]
|
||||||
|
#[Assert\GreaterThan(propertyPath: 'dateFrom', message: 'Das Datum muss nach dem Beginndatum liegen')]
|
||||||
private ?\DateTimeImmutable $dateTo = null;
|
private ?\DateTimeImmutable $dateTo = null;
|
||||||
|
|
||||||
#[ORM\ManyToOne(inversedBy: 'customAvailabilities')]
|
#[ORM\ManyToOne(inversedBy: 'customAvailabilities')]
|
||||||
@@ -38,6 +42,11 @@ class Availability implements BlameableEntityInterface, TimestampableEntityInter
|
|||||||
$this->teamers = new ArrayCollection();
|
$this->teamers = new ArrayCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
return sprintf('%s - %s', $this->getDateFrom()->format('d.m.Y'), $this->getDateTo()->format('d.m.Y'));
|
||||||
|
}
|
||||||
|
|
||||||
public function getId(): ?int
|
public function getId(): ?int
|
||||||
{
|
{
|
||||||
return $this->id;
|
return $this->id;
|
||||||
@@ -48,7 +57,7 @@ class Availability implements BlameableEntityInterface, TimestampableEntityInter
|
|||||||
return $this->dateFrom;
|
return $this->dateFrom;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setDateFrom(\DateTimeImmutable $dateFrom): static
|
public function setDateFrom(?\DateTimeImmutable $dateFrom): static
|
||||||
{
|
{
|
||||||
$this->dateFrom = $dateFrom;
|
$this->dateFrom = $dateFrom;
|
||||||
|
|
||||||
@@ -60,7 +69,7 @@ class Availability implements BlameableEntityInterface, TimestampableEntityInter
|
|||||||
return $this->dateTo;
|
return $this->dateTo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setDateTo(\DateTimeImmutable $dateTo): static
|
public function setDateTo(?\DateTimeImmutable $dateTo): static
|
||||||
{
|
{
|
||||||
$this->dateTo = $dateTo;
|
$this->dateTo = $dateTo;
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ class Teamer implements TimestampableEntityInterface
|
|||||||
private ?string $remarks = null;
|
private ?string $remarks = null;
|
||||||
|
|
||||||
#[ORM\ManyToMany(targetEntity: Availability::class, inversedBy: 'teamers')]
|
#[ORM\ManyToMany(targetEntity: Availability::class, inversedBy: 'teamers')]
|
||||||
|
#[ORM\OrderBy(['dateFrom' => 'ASC'])]
|
||||||
private Collection $availabilities;
|
private Collection $availabilities;
|
||||||
|
|
||||||
#[ORM\OneToMany(mappedBy: 'owner', targetEntity: Availability::class)]
|
#[ORM\OneToMany(mappedBy: 'owner', targetEntity: Availability::class)]
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Form;
|
||||||
|
|
||||||
|
use App\Entity\Availability;
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
|
class AvailabilityType extends AbstractType
|
||||||
|
{
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||||
|
{
|
||||||
|
$builder
|
||||||
|
->add('dateFrom', DatepickerType::class, [
|
||||||
|
'label' => 'Datum von',
|
||||||
|
'min_date' => new \DateTimeImmutable(),
|
||||||
|
])
|
||||||
|
->add('dateTo', DatepickerType::class, [
|
||||||
|
'label' => 'Datum bis',
|
||||||
|
'min_date' => new \DateTimeImmutable(),
|
||||||
|
])
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver): void
|
||||||
|
{
|
||||||
|
$resolver->setDefaults([
|
||||||
|
'data_class' => Availability::class,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -41,35 +41,17 @@ class AdminMenuBuilder extends AbstractMenuBuilder
|
|||||||
'title' => 'Einstellungen',
|
'title' => 'Einstellungen',
|
||||||
'icon' => 'settings',
|
'icon' => 'settings',
|
||||||
'children' => [
|
'children' => [
|
||||||
|
[
|
||||||
|
'route' => 'app_admin_system_availability_index',
|
||||||
|
'title' => 'Verfügbarkeiten',
|
||||||
|
],
|
||||||
[
|
[
|
||||||
'route' => 'app_admin_system_fee_index',
|
'route' => 'app_admin_system_fee_index',
|
||||||
'title' => 'Honorare',
|
'title' => 'Honorare',
|
||||||
'children' => [
|
|
||||||
[
|
|
||||||
'route' => 'app_admin_system_fee_create',
|
|
||||||
'title' => 'Honorar anlegen',
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'route' => 'app_admin_system_fee_edit',
|
|
||||||
'routeParameters' => $this->getDefaultRouteParameters(),
|
|
||||||
'title' => 'Honorar bearbeiten',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'route' => 'app_admin_system_training_index',
|
'route' => 'app_admin_system_training_index',
|
||||||
'title' => 'Fortbildungen',
|
'title' => 'Fortbildungen',
|
||||||
'children' => [
|
|
||||||
[
|
|
||||||
'route' => 'app_admin_system_training_create',
|
|
||||||
'title' => 'Fortbildung anlegen',
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'route' => 'app_admin_system_training_edit',
|
|
||||||
'routeParameters' => $this->getDefaultRouteParameters(),
|
|
||||||
'title' => 'Fortbildung bearbeiten',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'route' => 'app_admin_system_job_profile_index',
|
'route' => 'app_admin_system_job_profile_index',
|
||||||
@@ -79,6 +61,11 @@ class AdminMenuBuilder extends AbstractMenuBuilder
|
|||||||
'route' => 'app_admin_system_job_profile_create',
|
'route' => 'app_admin_system_job_profile_create',
|
||||||
'title' => 'Job-Profil anlegen',
|
'title' => 'Job-Profil anlegen',
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
'route' => 'app_admin_system_job_profile_edit',
|
||||||
|
'routeParameters' => $this->getDefaultRouteParameters(),
|
||||||
|
'title' => 'Job-Profil bearbeiten',
|
||||||
|
],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class TeamerMenuBuilder extends AbstractMenuBuilder
|
|||||||
'title' => 'Jobprofile & Skills',
|
'title' => 'Jobprofile & Skills',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'route' => 'app_teamer_profile_availabilities',
|
'route' => 'app_teamer_profile_availability_index',
|
||||||
'title' => 'Meine Verfügbarkeit',
|
'title' => 'Meine Verfügbarkeit',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ namespace App\Repository;
|
|||||||
use App\Entity\Availability;
|
use App\Entity\Availability;
|
||||||
use App\Entity\Teamer;
|
use App\Entity\Teamer;
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
|
use Doctrine\ORM\Query;
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -22,7 +23,22 @@ class AvailabilityRepository extends ServiceEntityRepository
|
|||||||
parent::__construct($registry, Availability::class);
|
parent::__construct($registry, Availability::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSelectable(Teamer $teamer): array
|
public function getListQuery(): Query
|
||||||
|
{
|
||||||
|
$qb = $this->createQueryBuilder('availability');
|
||||||
|
|
||||||
|
return $qb
|
||||||
|
->where($qb->expr()->andX(
|
||||||
|
$qb->expr()->gt('availability.dateFrom', ':today'),
|
||||||
|
$qb->expr()->isNull('availability.owner')
|
||||||
|
))
|
||||||
|
->orderBy('availability.dateFrom', 'ASC')
|
||||||
|
->setParameter('today', new \DateTimeImmutable())
|
||||||
|
->getQuery()
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSelectableForTeamer(Teamer $teamer): array
|
||||||
{
|
{
|
||||||
$qb = $this->createQueryBuilder('availability');
|
$qb = $this->createQueryBuilder('availability');
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Security\Voter;
|
||||||
|
|
||||||
|
use App\Entity\Availability;
|
||||||
|
use App\Entity\User;
|
||||||
|
use Symfony\Bundle\SecurityBundle\Security;
|
||||||
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||||
|
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
|
||||||
|
|
||||||
|
class AvailabilityVoter extends Voter
|
||||||
|
{
|
||||||
|
public const ASSIGN = 'ASSIGN';
|
||||||
|
public const DELETE = 'DELETE';
|
||||||
|
|
||||||
|
public function __construct(private readonly Security $security)
|
||||||
|
{}
|
||||||
|
|
||||||
|
protected function supports(string $attribute, mixed $subject): bool
|
||||||
|
{
|
||||||
|
if (!$subject instanceof Availability) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return in_array($attribute, [static::ASSIGN, static::DELETE]);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
|
||||||
|
{
|
||||||
|
/** @var Availability $availability */
|
||||||
|
$availability = $subject;
|
||||||
|
|
||||||
|
if (true === $this->security->isGranted('ROLE_ADMINISTRATIVE')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var User $user */
|
||||||
|
$user = $this->security->getUser();
|
||||||
|
$teamer = $user->getTeamer();
|
||||||
|
|
||||||
|
return null === $availability->getOwner() || $teamer === $availability->getOwner();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{{ form_start(form) }}
|
||||||
|
<div class="flex flex-col space-y-4 pb-8">
|
||||||
|
{{ form_row(form.dateFrom) }}
|
||||||
|
{{ form_row(form.dateTo) }}
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn">
|
||||||
|
Speichern
|
||||||
|
</button>
|
||||||
|
{{ form_rest(form) }}
|
||||||
|
{{ form_end(form) }}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
{% extends 'admin/layout.html.twig' %}
|
||||||
|
|
||||||
|
{% block title %}Einstellungen - Verfügbarkeiten/Zeiträume{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1 class="text-2xl font-bold pb-8">
|
||||||
|
Verfügbarkeiten/Zeiträume
|
||||||
|
</h1>
|
||||||
|
<div class="data-table-wrapper">
|
||||||
|
<div class="data-table-wrapper__inner">
|
||||||
|
<table class="data-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="w-1/3">
|
||||||
|
{{ knp_pagination_sortable(pagination, 'Datum von', 'availability.dateFrom') }}
|
||||||
|
</th>
|
||||||
|
<th class="w-1/3">
|
||||||
|
{{ knp_pagination_sortable(pagination, 'Datum bis', 'availability.dateTo') }}
|
||||||
|
</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for availability in pagination %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{{ availability.dateFrom|date('d.m.Y') }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ availability.dateTo|date('d.m.Y') }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="flex items-center space-x-2 justify-end">
|
||||||
|
<button type="button"
|
||||||
|
class="text-red-500"
|
||||||
|
{{ stimulus_controller('modal-button', [], [], {'confirmation-modal': '#confirmation-modal'}) }}
|
||||||
|
{{ stimulus_action('modal-button', 'confirmation', null, {
|
||||||
|
'title': 'Bist du sicher?',
|
||||||
|
'content': 'Möchtest du den Zeitraum wirklich löschen?',
|
||||||
|
'target-url': path('app_admin_system_availability_delete', { 'id': availability.id })
|
||||||
|
}) }}>
|
||||||
|
{{ icon('delete') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% else %}
|
||||||
|
<tr>
|
||||||
|
<td colspan="3">
|
||||||
|
<div class="text-sm">Keine Daten...</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{{ knp_pagination_render(pagination) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button type="button"
|
||||||
|
class="btn"
|
||||||
|
{{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }}
|
||||||
|
{{ stimulus_action('modal-button', 'ajax', null, {
|
||||||
|
'title': 'Zeitraum hinzufügen',
|
||||||
|
'url': path('app_admin_system_availability_create')
|
||||||
|
}) }}>
|
||||||
|
Zeitraum hinzufügen
|
||||||
|
</button>
|
||||||
|
{% endblock %}
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
{{ form_start(form) }}
|
|
||||||
<div class="flex flex-col space-y-4 pb-8">
|
|
||||||
{{ form_row(form.name) }}
|
|
||||||
{{ form_row(form.value) }}
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center space-x-2">
|
|
||||||
<button type="submit" class="btn">
|
|
||||||
Speichern
|
|
||||||
</button>
|
|
||||||
<a href="{{ path('app_admin_system_fee_index') }}" class="btn btn--secondary">
|
|
||||||
Abbrechen
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
{{ form_rest(form) }}
|
|
||||||
{{ form_end(form) }}
|
|
||||||
@@ -1,12 +1,10 @@
|
|||||||
{% extends 'admin/layout.html.twig' %}
|
{{ form_start(form) }}
|
||||||
|
<div class="flex flex-col space-y-4 pb-8">
|
||||||
{% block title %}Einstellungen - Honorar anlegen{% endblock %}
|
{{ form_row(form.name) }}
|
||||||
|
{{ form_row(form.value) }}
|
||||||
{% block content %}
|
</div>
|
||||||
<div class="max-w-screen-sm">
|
<button type="submit" class="btn">
|
||||||
<h1 class="text-2xl font-bold pb-8">
|
Speichern
|
||||||
Honorar anlegen
|
</button>
|
||||||
</h1>
|
{{ form_rest(form) }}
|
||||||
{% include 'admin/system/fee/_form.html.twig' %}
|
{{ form_end(form) }}
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
{% extends 'admin/layout.html.twig' %}
|
|
||||||
|
|
||||||
{% block title %}Einstellungen - Honorar bearbeiten{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<div class="max-w-screen-sm">
|
|
||||||
<h1 class="text-2xl font-bold pb-8">
|
|
||||||
Honorar bearbeiten
|
|
||||||
</h1>
|
|
||||||
{% include 'admin/system/fee/_form.html.twig' %}
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
@@ -3,62 +3,65 @@
|
|||||||
{% block title %}Einstellungen - Honorare{% endblock %}
|
{% block title %}Einstellungen - Honorare{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1 class="text-2xl font-bold pb-8">
|
<h1 class="text-2xl font-bold pb-8">
|
||||||
Honorare
|
Honorare
|
||||||
</h1>
|
</h1>
|
||||||
<div class="data-table-wrapper">
|
<div class="data-table-wrapper">
|
||||||
<div class="data-table-wrapper__inner">
|
<div class="data-table-wrapper__inner">
|
||||||
<table class="data-table">
|
<table class="data-table">
|
||||||
<thead>
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
Bezeichnung
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
Wert
|
||||||
|
</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for fee in fees %}
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<td>
|
||||||
Bezeichnung
|
{{ fee.name }}
|
||||||
</th>
|
</td>
|
||||||
<th>
|
<td>
|
||||||
Wert
|
{{ fee.value|format_money }}
|
||||||
</th>
|
</td>
|
||||||
<th></th>
|
<td>
|
||||||
|
<div class="flex items-center space-x-2 justify-end">
|
||||||
|
<button type="button"
|
||||||
|
class="text-red-500"
|
||||||
|
{{ stimulus_controller('modal-button', [], [], {'confirmation-modal': '#confirmation-modal'}) }}
|
||||||
|
{{ stimulus_action('modal-button', 'confirmation', null, {
|
||||||
|
'title': 'Bist du sicher?',
|
||||||
|
'content': 'Möchtest du das Honorar wirklich löschen?',
|
||||||
|
'target-url': path('app_admin_system_fee_delete', { 'id': fee.id })
|
||||||
|
}) }}>
|
||||||
|
{{ icon('delete') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
{% else %}
|
||||||
<tbody>
|
<tr>
|
||||||
{% for fee in fees %}
|
<td colspan="3">
|
||||||
<tr>
|
<div class="text-sm">Keine Daten...</div>
|
||||||
<td>
|
</td>
|
||||||
{{ fee.name }}
|
</tr>
|
||||||
</td>
|
{% endfor %}
|
||||||
<td>
|
</tbody>
|
||||||
{{ fee.value|format_money }}
|
</table>
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="flex items-center space-x-2 justify-end">
|
|
||||||
<button type="button"
|
|
||||||
class="text-red-500"
|
|
||||||
{{ stimulus_controller('modal-button', [], [], {'confirmation-modal': '#confirmation-modal'}) }}
|
|
||||||
{{ stimulus_action('modal-button', 'confirmation', null, {
|
|
||||||
'title': 'Bist du sicher?',
|
|
||||||
'content': 'Möchtest du das Honorar wirklich löschen?',
|
|
||||||
'target-url': path('app_admin_system_fee_delete', { 'id': fee.id })
|
|
||||||
}) }}>
|
|
||||||
{{ icon('delete') }}
|
|
||||||
</button>
|
|
||||||
<a href="{{ path('app_admin_system_fee_edit', { 'id': fee.id }) }}">
|
|
||||||
{{ icon('edit') }}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% else %}
|
|
||||||
<tr>
|
|
||||||
<td colspan="3">
|
|
||||||
<div class="text-sm">Keine Daten...</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<a href="{{ path('app_admin_system_fee_create') }}" class="btn">
|
</div>
|
||||||
Neu
|
<button type="button"
|
||||||
</a>
|
class="btn"
|
||||||
|
{{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }}
|
||||||
|
{{ stimulus_action('modal-button', 'ajax', null, {
|
||||||
|
'title': 'Honorar hinzufügen',
|
||||||
|
'url': path('app_admin_system_fee_create')
|
||||||
|
}) }}>
|
||||||
|
Honorar hinzufügen
|
||||||
|
</button>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
{{ form_start(form) }}
|
|
||||||
<div class="flex flex-col space-y-4 pb-8">
|
|
||||||
{{ form_row(form.name) }}
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center space-x-2">
|
|
||||||
<button type="submit" class="btn">
|
|
||||||
Speichern
|
|
||||||
</button>
|
|
||||||
<a href="{{ path('app_admin_system_training_index') }}" class="btn btn--secondary">
|
|
||||||
Abbrechen
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
{{ form_rest(form) }}
|
|
||||||
{{ form_end(form) }}
|
|
||||||
@@ -1,12 +1,9 @@
|
|||||||
{% extends 'admin/layout.html.twig' %}
|
{{ form_start(form) }}
|
||||||
|
<div class="flex flex-col space-y-4 pb-8">
|
||||||
{% block title %}Einstellungen - Fortbildung anlegen{% endblock %}
|
{{ form_row(form.name) }}
|
||||||
|
</div>
|
||||||
{% block content %}
|
<button type="submit" class="btn">
|
||||||
<div class="max-w-screen-sm">
|
Speichern
|
||||||
<h1 class="text-2xl font-bold pb-8">
|
</button>
|
||||||
Fortbildung anlegen
|
{{ form_rest(form) }}
|
||||||
</h1>
|
{{ form_end(form) }}
|
||||||
{% include 'admin/system/training/_form.html.twig' %}
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
{% extends 'admin/layout.html.twig' %}
|
|
||||||
|
|
||||||
{% block title %}Einstellungen - Fortbildung bearbeiten{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<div class="max-w-screen-sm">
|
|
||||||
<h1 class="text-2xl font-bold pb-8">
|
|
||||||
Fortbildung bearbeiten
|
|
||||||
</h1>
|
|
||||||
{% include 'admin/system/training/_form.html.twig' %}
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
@@ -3,62 +3,65 @@
|
|||||||
{% block title %}Einstellungen - Fortbildungen{% endblock %}
|
{% block title %}Einstellungen - Fortbildungen{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1 class="text-2xl font-bold pb-8">
|
<h1 class="text-2xl font-bold pb-8">
|
||||||
Fortbildungen
|
Fortbildungen
|
||||||
</h1>
|
</h1>
|
||||||
<div class="data-table-wrapper">
|
<div class="data-table-wrapper">
|
||||||
<div class="data-table-wrapper__inner">
|
<div class="data-table-wrapper__inner">
|
||||||
<table class="data-table">
|
<table class="data-table">
|
||||||
<thead>
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
Bezeichnung
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
Teilnahmen
|
||||||
|
</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for training in trainings %}
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<td>
|
||||||
Bezeichnung
|
{{ training.name }}
|
||||||
</th>
|
</td>
|
||||||
<th>
|
<td>
|
||||||
Teilnahmen
|
{{ training.trainingAttendances|length|default('-') }}
|
||||||
</th>
|
</td>
|
||||||
<th></th>
|
<td>
|
||||||
|
<div class="flex items-center space-x-2 justify-end">
|
||||||
|
<button type="button"
|
||||||
|
class="text-red-500"
|
||||||
|
{{ stimulus_controller('modal-button', [], [], {'confirmation-modal': '#confirmation-modal'}) }}
|
||||||
|
{{ stimulus_action('modal-button', 'confirmation', null, {
|
||||||
|
'title': 'Bist du sicher?',
|
||||||
|
'content': 'Möchtest du die Fortbildung wirklich löschen?',
|
||||||
|
'target-url': path('app_admin_system_training_delete', { 'id': training.id })
|
||||||
|
}) }}>
|
||||||
|
{{ icon('delete') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
{% else %}
|
||||||
<tbody>
|
<tr>
|
||||||
{% for training in trainings %}
|
<td colspan="3">
|
||||||
<tr>
|
<div class="text-sm">Keine Daten...</div>
|
||||||
<td>
|
</td>
|
||||||
{{ training.name }}
|
</tr>
|
||||||
</td>
|
{% endfor %}
|
||||||
<td>
|
</tbody>
|
||||||
{{ training.trainingAttendances|length|default('-') }}
|
</table>
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="flex items-center space-x-2 justify-end">
|
|
||||||
<button type="button"
|
|
||||||
class="text-red-500"
|
|
||||||
{{ stimulus_controller('modal-button', [], [], {'confirmation-modal': '#confirmation-modal'}) }}
|
|
||||||
{{ stimulus_action('modal-button', 'confirmation', null, {
|
|
||||||
'title': 'Bist du sicher?',
|
|
||||||
'content': 'Möchtest du die Fortbildung wirklich löschen?',
|
|
||||||
'target-url': path('app_admin_system_training_delete', { 'id': training.id })
|
|
||||||
}) }}>
|
|
||||||
{{ icon('delete') }}
|
|
||||||
</button>
|
|
||||||
<a href="{{ path('app_admin_system_training_edit', { 'id': training.id }) }}">
|
|
||||||
{{ icon('edit') }}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% else %}
|
|
||||||
<tr>
|
|
||||||
<td colspan="3">
|
|
||||||
<div class="text-sm">Keine Daten...</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<a href="{{ path('app_admin_system_training_create') }}" class="btn">
|
</div>
|
||||||
Neu
|
<button type="button"
|
||||||
</a>
|
class="btn"
|
||||||
|
{{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }}
|
||||||
|
{{ stimulus_action('modal-button', 'ajax', null, {
|
||||||
|
'title': 'Fortbildung hinzufügen',
|
||||||
|
'url': path('app_admin_system_training_create')
|
||||||
|
}) }}>
|
||||||
|
Fortbildung hinzufügen
|
||||||
|
</button>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<div class="bg-gray-100 border border-gray-300 border-t-0 px-4 py-3 flex items-center justify-between sm:px-4">
|
<div class="bg-gray-100 border border-gray-300 border-t-0 px-4 py-3 flex items-center justify-between sm:px-4">
|
||||||
<div class="flex-1 flex items-center justify-between">
|
<div class="flex-1 flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<p class="text-sm leading-5 text-gray-700">{{ 'label.paginator.info'|trans({ '{from}': firstItemNumber, '{to}': lastItemNumber, '{total}': totalCount })|raw }}</p>
|
<p class="text-sm leading-5 text-gray-700">{{ 'paginator.info'|trans({ '{from}': firstItemNumber, '{to}': lastItemNumber, '{total}': totalCount })|raw }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<nav class="relative z-0 inline-flex">
|
<nav class="relative z-0 inline-flex">
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
{% extends 'teamer/layout.html.twig' %}
|
|
||||||
|
|
||||||
{% block title %}Meine Verfügbarkeit{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<h1 class="text-2xl font-bold pb-4">
|
|
||||||
Meine Vergfügbarkeit
|
|
||||||
</h1>
|
|
||||||
<p class="pb-8">
|
|
||||||
Hier kannst du angeben, wann du allgemein Zeit und Lust hättest, Einsätze zu absolvieren. Wenn wir in diesem
|
|
||||||
Zeitraum einen Einsatz zu vergeben haben, dann nehmen wir telefonisch oder per E-Mail Kontakt zu dir auf.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2 class="text-xl font-bold pb-2">
|
|
||||||
Ich bin verfügbar
|
|
||||||
</h2>
|
|
||||||
<ul class="list-disc pl-4 pb-8">
|
|
||||||
{% for availability in availabilities %}
|
|
||||||
<li>
|
|
||||||
{{ availability.dateFrom|date('d.m.Y') }} - {{ availability.dateTo|date('d.m.Y') }}
|
|
||||||
</li>
|
|
||||||
{% else %}
|
|
||||||
<li class="text-sm">
|
|
||||||
Du hast bisher keine Verfügbarkeiten hinterlegt.
|
|
||||||
</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h2 class="text-xl font-bold pb-2">
|
|
||||||
Weitere Verfügbarkeiten
|
|
||||||
</h2>
|
|
||||||
{{ form_start(form) }}
|
|
||||||
{{ form_row(form.availabilities) }}
|
|
||||||
<button type="submit" class="btn">
|
|
||||||
Aktualisieren
|
|
||||||
</button>
|
|
||||||
{{ form_rest(form) }}
|
|
||||||
{{ form_end(form) }}
|
|
||||||
{% endblock %}
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{{ form_start(form) }}
|
||||||
|
<div class="flex flex-col space-y-4 pb-8">
|
||||||
|
{{ form_row(form.dateFrom) }}
|
||||||
|
{{ form_row(form.dateTo) }}
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn">
|
||||||
|
Speichern
|
||||||
|
</button>
|
||||||
|
{{ form_rest(form) }}
|
||||||
|
{{ form_end(form) }}
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
{% extends 'teamer/layout.html.twig' %}
|
||||||
|
|
||||||
|
{% block title %}Meine Verfügbarkeit{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1 class="text-2xl font-bold pb-4">
|
||||||
|
Meine Vergfügbarkeit
|
||||||
|
</h1>
|
||||||
|
<p class="pb-8">
|
||||||
|
Hier kannst du angeben, wann du allgemein Zeit und Lust hättest, Einsätze zu absolvieren. Wenn wir in diesem
|
||||||
|
Zeitraum einen Einsatz zu vergeben haben, dann nehmen wir telefonisch oder per E-Mail Kontakt zu dir auf.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2 class="text-xl font-bold pb-2">
|
||||||
|
Ich bin verfügbar
|
||||||
|
</h2>
|
||||||
|
<div class="grid md:grid-cols-2 gap-8 pb-8">
|
||||||
|
{% for year, months in selectedAvailabilities %}
|
||||||
|
<div>
|
||||||
|
<h3 class="text-lg font-bold">
|
||||||
|
{{ year }}
|
||||||
|
</h3>
|
||||||
|
<div class="flex flex-col space-y-3">
|
||||||
|
{% for month, availabilities in months %}
|
||||||
|
<div>
|
||||||
|
<h4 class="font-bold">
|
||||||
|
{{ month }}
|
||||||
|
</h4>
|
||||||
|
{% for availability in availabilities %}
|
||||||
|
<div class="flex items-center space-x-2">
|
||||||
|
<span>{{ availability }}</span>
|
||||||
|
{% if is_granted('DELETE', availability) %}
|
||||||
|
<button type="button"
|
||||||
|
title="Zeitraum entfernen/löschen"
|
||||||
|
{{ stimulus_controller('modal-button', [], [], {'confirmation-modal': '#confirmation-modal'}) }}
|
||||||
|
{{ stimulus_action('modal-button', 'confirmation', null, {
|
||||||
|
'title': 'Bist du sicher?',
|
||||||
|
'content': 'Möchtest du den Zeitraum wirklich löschen?',
|
||||||
|
'target-url': path('app_teamer_profile_availability_delete', { 'id': availability.id })
|
||||||
|
}) }}>
|
||||||
|
{{ icon('delete', 'w-5 h-5') }}
|
||||||
|
</button>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="md:col-span-2 text-sm">
|
||||||
|
Du hast bisher keine Verfügbarkeiten hinterlegt.
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<h2 class="text-xl font-bold pb-2">
|
||||||
|
Weitere Verfügbarkeiten
|
||||||
|
</h2>
|
||||||
|
<div class="grid md:grid-cols-2 gap-8 pb-8">
|
||||||
|
{% for year, months in selectableAvailabilities %}
|
||||||
|
<div>
|
||||||
|
<h3 class="text-lg font-bold">
|
||||||
|
{{ year }}
|
||||||
|
</h3>
|
||||||
|
<div class="flex flex-col space-y-3">
|
||||||
|
{% for month, availabilities in months %}
|
||||||
|
<div>
|
||||||
|
<h4 class="font-bold">
|
||||||
|
{{ month }}
|
||||||
|
</h4>
|
||||||
|
{% for availability in availabilities %}
|
||||||
|
<div class="flex items-center space-x-2">
|
||||||
|
<span>{{ availability }}</span>
|
||||||
|
<a href="{{ path('app_teamer_profile_availability_add', { 'id': availability.id }) }}"
|
||||||
|
title="Zeitraum hinzufügen">
|
||||||
|
{{ icon('plus', 'w-5 h-5') }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="md:col-span-2 text-sm">
|
||||||
|
Es sind keine weiteren Zeiträume verfügbar.
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<button type="button"
|
||||||
|
class="btn"
|
||||||
|
{{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }}
|
||||||
|
{{ stimulus_action('modal-button', 'ajax', null, {
|
||||||
|
'title': 'Zeitraum hinzufügen',
|
||||||
|
'url': path('app_teamer_profile_availability_create')
|
||||||
|
}) }}>
|
||||||
|
Eigenen Zeitraum hinzufügen
|
||||||
|
</button>
|
||||||
|
{% endblock %}
|
||||||
@@ -3,4 +3,8 @@ uploader:
|
|||||||
click_here: hier klicken
|
click_here: hier klicken
|
||||||
file_too_big: Die maximale Dateigröße beträgt %maxFilesize%MB
|
file_too_big: Die maximale Dateigröße beträgt %maxFilesize%MB
|
||||||
invalid_file_type: Der Dateityp ist nicht erlaubt
|
invalid_file_type: Der Dateityp ist nicht erlaubt
|
||||||
max_files_exceeded: Die maximale Anzahl von Dateien is %maxFilesExceeded%
|
max_files_exceeded: Die maximale Anzahl von Dateien is %maxFilesExceeded%
|
||||||
|
paginator:
|
||||||
|
previous: vorherige
|
||||||
|
next: nächste
|
||||||
|
info: 'Einträge <span class="font-medium">{from}</span> bis <span class="font-medium">{to}</span> von {total}'
|
||||||
|
|||||||
Reference in New Issue
Block a user