diff --git a/assets/controllers/sidebar_menu_controller.js b/assets/controllers/sidebar_menu_controller.js new file mode 100644 index 0000000..cdc4e48 --- /dev/null +++ b/assets/controllers/sidebar_menu_controller.js @@ -0,0 +1,27 @@ +import { Controller } from '@hotwired/stimulus' + +export default class extends Controller { + + static classes = ['closed', 'iconClosed', 'iconExpanded'] + static targets = ['submenu', 'button', 'icon'] + static values = { expanded: Boolean } + + toggleSubmenu() { + this.expandedValue = !this.expandedValue + } + + expandedValueChanged(expanded) { + this.submenuTarget.classList.toggle(this.closedClass, false === expanded) + this.buttonTarget.setAttribute('aria-expanded', expanded) + if (false === this.hasIconTarget) { + return + } + if (true === expanded) { + this.iconTarget.classList.add(...this.iconExpandedClasses) + this.iconTarget.classList.remove(...this.iconClosedClasses) + } else { + this.iconTarget.classList.add(...this.iconClosedClasses) + this.iconTarget.classList.remove(...this.iconExpandedClasses) + } + } +} \ No newline at end of file diff --git a/assets/images/icons.svg b/assets/images/icons.svg index 874d68c..a983aa5 100644 --- a/assets/images/icons.svg +++ b/assets/images/icons.svg @@ -141,6 +141,10 @@ + + + + diff --git a/assets/styles/_components.css b/assets/styles/_components.css index 372e606..3681dc0 100644 --- a/assets/styles/_components.css +++ b/assets/styles/_components.css @@ -1,5 +1,5 @@ @import "components/autocomplete.css"; @import "components/button.css"; +@import "components/datatable.css"; @import "components/datepicker.css"; -@import "components/menu.css"; @import "components/toast.css"; \ No newline at end of file diff --git a/assets/styles/components/button.css b/assets/styles/components/button.css index 10d045a..7bdd8a6 100644 --- a/assets/styles/components/button.css +++ b/assets/styles/components/button.css @@ -1,5 +1,5 @@ .btn { - @apply inline-flex justify-center rounded-lg text-sm uppercase font-semibold py-2.5 px-4 bg-primary text-white hover:bg-primary/80 w-full shadow-md; + @apply inline-flex justify-center rounded-lg text-sm uppercase font-semibold py-2.5 px-4 bg-primary text-white hover:bg-primary/80 shadow-md; } .btn--secondary { diff --git a/assets/styles/components/datatable.css b/assets/styles/components/datatable.css new file mode 100644 index 0000000..654e3a0 --- /dev/null +++ b/assets/styles/components/datatable.css @@ -0,0 +1,36 @@ +.data-table-wrapper { + @apply overflow-x-auto mb-8; +} + +.data-table-wrapper__inner { + @apply align-middle inline-block min-w-full overflow-hidden; +} + +table { + @apply min-w-full; +} + +tbody { + @apply bg-white; +} + +tr { + @apply border border-gray-300; +} + +th { + @apply px-4 py-2 bg-gray-200 text-left text-sm xl:text-base leading-4 font-bold text-primary align-top; +} + +td { + @apply px-4 py-2 text-sm leading-5 align-top; + +} + +table.horizontal td { + @apply py-4; +} + +.data-table tbody tr { + @apply hover:bg-gray-100; +} diff --git a/assets/styles/components/menu.css b/assets/styles/components/menu.css deleted file mode 100644 index 253bba7..0000000 --- a/assets/styles/components/menu.css +++ /dev/null @@ -1,46 +0,0 @@ -.menu--header { - @apply flex items-center space-x-4 h-8; -} - -.menu--main { - @apply flex flex-col divide-y divide-gray-200; -} - -.menu--main > li { - @apply py-4 first:pt-0 last:pb-0; -} - -.menu--mobile { - @apply flex-col space-x-0 h-auto divide-y divide-gray-200; -} - -.menu--mobile li { - @apply py-4 w-full; -} - -.menu a, -.menu div { - @apply uppercase hover:text-slate-700 text-slate-900 text-sm lg:text-base; -} - -.menu--mobile a { - @apply text-lg; -} - -.menu ul { - @apply pl-7 pt-1; -} - -.menu ul a { - @apply text-sm; -} - -.menu .current > a, -.menu .active > a { - @apply text-slate-900 font-bold; -} - -.menu .icon-link, -.menu .icon-section { - @apply flex items-center space-x-2; -} diff --git a/composer.json b/composer.json index d17b69d..1afb5b7 100644 --- a/composer.json +++ b/composer.json @@ -12,6 +12,7 @@ "doctrine/doctrine-migrations-bundle": "^3.2", "doctrine/orm": "^2.15", "knplabs/knp-menu-bundle": "^3.2", + "knplabs/knp-paginator-bundle": "^6.2", "liip/imagine-bundle": "^2.11", "nesbot/carbon": "^2.70", "oneup/uploader-bundle": "^4.0", diff --git a/composer.lock b/composer.lock index 711629a..cfa75d3 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "05df8d6ad31865116a5ac469c6e03b20", + "content-hash": "55a86e3af41172ce63979c655a409640", "packages": [ { "name": "doctrine/cache", @@ -1448,6 +1448,92 @@ }, "time": "2023-06-07T14:49:52+00:00" }, + { + "name": "knplabs/knp-components", + "version": "v4.2.0", + "source": { + "type": "git", + "url": "https://github.com/KnpLabs/knp-components.git", + "reference": "1f6560cc1247c8fe7ba75fe4f80f16ffcc9379a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/KnpLabs/knp-components/zipball/1f6560cc1247c8fe7ba75fe4f80f16ffcc9379a0", + "reference": "1f6560cc1247c8fe7ba75fe4f80f16ffcc9379a0", + "shasum": "" + }, + "require": { + "php": "^8.0", + "symfony/event-dispatcher-contracts": "^3.0" + }, + "conflict": { + "doctrine/dbal": "<3.1" + }, + "require-dev": { + "doctrine/mongodb-odm": "^2.4", + "doctrine/orm": "^2.12", + "doctrine/phpcr-odm": "^1.6", + "ext-pdo_sqlite": "*", + "jackalope/jackalope-doctrine-dbal": "^1.8", + "phpunit/phpunit": "^9.5", + "propel/propel1": "^1.7", + "ruflin/elastica": "^7.0", + "solarium/solarium": "^6.0", + "symfony/http-foundation": "^5.4 || ^6.0", + "symfony/http-kernel": "^5.4 || ^6.0", + "symfony/property-access": "^5.4 || ^6.0" + }, + "suggest": { + "doctrine/common": "to allow usage pagination with Doctrine ArrayCollection", + "doctrine/mongodb-odm": "to allow usage pagination with Doctrine ODM MongoDB", + "doctrine/orm": "to allow usage pagination with Doctrine ORM", + "doctrine/phpcr-odm": "to allow usage pagination with Doctrine ODM PHPCR", + "propel/propel1": "to allow usage pagination with Propel ORM", + "ruflin/elastica": "to allow usage pagination with ElasticSearch Client", + "solarium/solarium": "to allow usage pagination with Solarium Client", + "symfony/http-foundation": "to retrieve arguments from Request", + "symfony/property-access": "to allow sorting arrays" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + } + }, + "autoload": { + "psr-4": { + "Knp\\Component\\": "src/Knp/Component" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "KnpLabs Team", + "homepage": "https://knplabs.com" + }, + { + "name": "Symfony Community", + "homepage": "https://github.com/KnpLabs/knp-components/contributors" + } + ], + "description": "Knplabs component library", + "homepage": "https://github.com/KnpLabs/knp-components", + "keywords": [ + "components", + "knp", + "knplabs", + "pager", + "paginator" + ], + "support": { + "issues": "https://github.com/KnpLabs/knp-components/issues", + "source": "https://github.com/KnpLabs/knp-components/tree/v4.2.0" + }, + "time": "2023-05-09T10:21:13+00:00" + }, { "name": "knplabs/knp-menu", "version": "v3.4.0", @@ -1585,6 +1671,80 @@ }, "time": "2021-10-24T07:53:34+00:00" }, + { + "name": "knplabs/knp-paginator-bundle", + "version": "v6.2.0", + "source": { + "type": "git", + "url": "https://github.com/KnpLabs/KnpPaginatorBundle.git", + "reference": "8da698f0856b1d9c9c02dcacbfc382c5c9440c80" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/KnpLabs/KnpPaginatorBundle/zipball/8da698f0856b1d9c9c02dcacbfc382c5c9440c80", + "reference": "8da698f0856b1d9c9c02dcacbfc382c5c9440c80", + "shasum": "" + }, + "require": { + "knplabs/knp-components": "^4.1", + "php": "^8.0", + "symfony/config": "^6.0", + "symfony/dependency-injection": "^6.0", + "symfony/event-dispatcher": "^6.0", + "symfony/http-foundation": "^6.0", + "symfony/http-kernel": "^6.0", + "symfony/routing": "^6.0", + "symfony/translation": "^6.0", + "twig/twig": "^3.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.9", + "phpunit/phpunit": "^9.5", + "symfony/expression-language": "^6.0", + "symfony/templating": "^6.0" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "Knp\\Bundle\\PaginatorBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "KnpLabs Team", + "homepage": "https://knplabs.com" + }, + { + "name": "Symfony Community", + "homepage": "https://github.com/KnpLabs/KnpPaginatorBundle/contributors" + } + ], + "description": "Paginator bundle for Symfony to automate pagination and simplify sorting and other features", + "homepage": "https://github.com/KnpLabs/KnpPaginatorBundle", + "keywords": [ + "bundle", + "knp", + "knplabs", + "pager", + "pagination", + "paginator", + "symfony" + ], + "support": { + "issues": "https://github.com/KnpLabs/KnpPaginatorBundle/issues", + "source": "https://github.com/KnpLabs/KnpPaginatorBundle/tree/v6.2.0" + }, + "time": "2023-03-25T06:51:40+00:00" + }, { "name": "liip/imagine-bundle", "version": "2.11.0", diff --git a/config/bundles.php b/config/bundles.php index f4a7e4a..2be0c77 100644 --- a/config/bundles.php +++ b/config/bundles.php @@ -16,4 +16,5 @@ return [ Knp\Bundle\MenuBundle\KnpMenuBundle::class => ['all' => true], Oneup\UploaderBundle\OneupUploaderBundle::class => ['all' => true], Liip\ImagineBundle\LiipImagineBundle::class => ['all' => true], + Knp\Bundle\PaginatorBundle\KnpPaginatorBundle::class => ['all' => true], ]; diff --git a/config/packages/knp_paginator.yaml b/config/packages/knp_paginator.yaml new file mode 100644 index 0000000..c7ae852 --- /dev/null +++ b/config/packages/knp_paginator.yaml @@ -0,0 +1,11 @@ +knp_paginator: + default_options: + page_name: page + sort_field_name: sort + sort_direction_name: direction + distinct: true + filter_field_name: filterField + filter_value_name: filterValue + template: + pagination: 'paginator/sliding.html.twig' + sortable: 'paginator/sortable_link.html.twig' diff --git a/config/services.yaml b/config/services.yaml index 45a472b..e96e9a9 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -60,43 +60,25 @@ services: arguments: $factory: '@knp_menu.factory' tags: - - name: knp_menu.menu_builder - method: createHeaderMenu - alias: admin_header - name: knp_menu.menu_builder method: createMainMenu alias: admin_main - - name: knp_menu.menu_builder - method: createMobileMenu - alias: admin_mobile App\Menu\ManagerMenuBuilder: arguments: $factory: '@knp_menu.factory' tags: - - name: knp_menu.menu_builder - method: createHeaderMenu - alias: manager_header - name: knp_menu.menu_builder method: createMainMenu alias: manager_main - - name: knp_menu.menu_builder - method: createMobileMenu - alias: manager_mobile App\Menu\TeamerMenuBuilder: arguments: $factory: '@knp_menu.factory' tags: - - name: knp_menu.menu_builder - method: createHeaderMenu - alias: teamer_header - name: knp_menu.menu_builder method: createMainMenu alias: teamer_main - - name: knp_menu.menu_builder - method: createMobileMenu - alias: teamer_mobile App\Service\Upload\UploadHandler: arguments: diff --git a/src/Controller/Admin/System/JobProfile/CreateController.php b/src/Controller/Admin/System/JobProfile/CreateController.php new file mode 100644 index 0000000..e1bb2d1 --- /dev/null +++ b/src/Controller/Admin/System/JobProfile/CreateController.php @@ -0,0 +1,47 @@ +createForm(JobProfileType::class, $jobProfile); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $this->entityManager->persist($jobProfile); + $this->entityManager->flush(); + + $this->addFlash('success', 'Das Job-Profil wurde angelegt'); + $this->logger->info('Create Job profile', [ + 'job_profile' => $jobProfile->getName(), + ]); + + return $this->redirectToRoute('app_admin_system_job_profile_index'); + } + + return $this->render('admin/system/job_profile/create.html.twig', [ + 'form' => $form + ]); + } +} \ No newline at end of file diff --git a/src/Controller/Admin/System/JobProfile/IndexController.php b/src/Controller/Admin/System/JobProfile/IndexController.php new file mode 100644 index 0000000..aea0df9 --- /dev/null +++ b/src/Controller/Admin/System/JobProfile/IndexController.php @@ -0,0 +1,29 @@ +jobProfileRepository + ->getList() + ; + + return $this->render('admin/system/job_profile/index.html.twig', [ + 'jobProfiles' => $jobProfiles, + ]); + } +} \ No newline at end of file diff --git a/src/Controller/Admin/System/Training/CreateController.php b/src/Controller/Admin/System/Training/CreateController.php new file mode 100644 index 0000000..add1cd4 --- /dev/null +++ b/src/Controller/Admin/System/Training/CreateController.php @@ -0,0 +1,47 @@ +createForm(TrainingType::class, $training); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $this->entityManager->persist($training); + $this->entityManager->flush(); + + $this->addFlash('success', 'Die Fortbildung wurde angelegt'); + $this->logger->info('Create training', [ + 'training' => $training->getName(), + ]); + + return $this->redirectToRoute('app_admin_system_training_index'); + } + + return $this->render('admin/system/training/create.html.twig', [ + 'form' => $form + ]); + } +} \ No newline at end of file diff --git a/src/Controller/Admin/System/Training/EditController.php b/src/Controller/Admin/System/Training/EditController.php new file mode 100644 index 0000000..962f1b6 --- /dev/null +++ b/src/Controller/Admin/System/Training/EditController.php @@ -0,0 +1,45 @@ +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('Update training', [ + 'training' => $training->getName(), + ]); + + return $this->redirectToRoute('app_admin_system_training_index'); + } + + return $this->render('admin/system/training/edit.html.twig', [ + 'form' => $form + ]); + } +} \ No newline at end of file diff --git a/src/Controller/Admin/System/Training/IndexController.php b/src/Controller/Admin/System/Training/IndexController.php new file mode 100644 index 0000000..01af72e --- /dev/null +++ b/src/Controller/Admin/System/Training/IndexController.php @@ -0,0 +1,29 @@ +trainingRepository + ->getList() + ; + + return $this->render('admin/system/training/index.html.twig', [ + 'trainings' => $trainings, + ]); + } +} \ No newline at end of file diff --git a/src/Controller/Admin/Teamer/IndexController.php b/src/Controller/Admin/Teamer/IndexController.php new file mode 100644 index 0000000..e2f022c --- /dev/null +++ b/src/Controller/Admin/Teamer/IndexController.php @@ -0,0 +1,44 @@ +teamerRepository + ->getListQuery() + ; + + $pagination = $this->paginator->paginate( + $query, + $request->query->getInt('page', 1), + 10, + [ + 'defaultSortFieldName' => 'teamer.lastName', + 'defaultSortDirection' => 'asc', + ] + ); + + return $this->render('admin/teamer/index.html.twig', [ + 'pagination' => $pagination, + ]); + } +} \ No newline at end of file diff --git a/src/Controller/Teamer/Profile/AvailabilitiesController.php b/src/Controller/Teamer/Profile/AvailabilitiesController.php index 1a670c7..fc03401 100644 --- a/src/Controller/Teamer/Profile/AvailabilitiesController.php +++ b/src/Controller/Teamer/Profile/AvailabilitiesController.php @@ -13,6 +13,6 @@ class AvailabilitiesController extends AbstractController #[IsGranted('ROLE_TEAMER')] public function index(): Response { - return $this->render(''); + return $this->render('teamer/profile/availabilities.html.twig'); } } \ No newline at end of file diff --git a/src/Controller/Teamer/Profile/IndexController.php b/src/Controller/Teamer/Profile/IndexController.php index db802fd..0e5dd92 100644 --- a/src/Controller/Teamer/Profile/IndexController.php +++ b/src/Controller/Teamer/Profile/IndexController.php @@ -71,10 +71,10 @@ class IndexController extends AbstractController 'user' => $user->getUserIdentifier(), ]); - return $this->redirectToRoute('app_teamer_profile'); + return $this->redirectToRoute('app_teamer_profile_index'); } - return $this->render('teamer/profile.html.twig', [ + return $this->render('teamer/profile/index.html.twig', [ 'form' => $form->createView(), 'teamer' => $teamer, 'errors' => $errors, diff --git a/src/Controller/Teamer/Profile/SkillsController.php b/src/Controller/Teamer/Profile/SkillsController.php index 32f779b..4cdc8fa 100644 --- a/src/Controller/Teamer/Profile/SkillsController.php +++ b/src/Controller/Teamer/Profile/SkillsController.php @@ -13,6 +13,6 @@ class SkillsController extends AbstractController #[IsGranted('ROLE_TEAMER')] public function index(): Response { - return $this->render(''); + return $this->render('teamer/profile/skills.html.twig'); } } \ No newline at end of file diff --git a/src/Entity/JobProfile.php b/src/Entity/JobProfile.php index 3b8d4f6..6746812 100644 --- a/src/Entity/JobProfile.php +++ b/src/Entity/JobProfile.php @@ -8,6 +8,7 @@ use App\Repository\JobProfileRepository; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Uid\Uuid; +use Symfony\Component\Validator\Constraints as Assert; #[ORM\Entity(repositoryClass: JobProfileRepository::class)] class JobProfile implements BlameableEntityInterface, TimestampableEntityInterface @@ -24,6 +25,7 @@ class JobProfile implements BlameableEntityInterface, TimestampableEntityInterfa private string $uuid; #[ORM\Column(length: 255)] + #[Assert\NotBlank(message: 'Bitte gib die Bezeichnung an')] private ?string $name = null; #[ORM\ManyToOne] diff --git a/src/Entity/Teamer.php b/src/Entity/Teamer.php index 543b164..7d9b269 100644 --- a/src/Entity/Teamer.php +++ b/src/Entity/Teamer.php @@ -111,6 +111,9 @@ class Teamer implements TimestampableEntityInterface #[ORM\OneToMany(mappedBy: 'teamer', targetEntity: Disposition::class)] private Collection $dispositions; + #[ORM\OneToOne(mappedBy: 'teamer')] + private ?User $user = null; + public function __construct() { $this->uuid = Uuid::v4(); @@ -600,4 +603,16 @@ class Teamer implements TimestampableEntityInterface return $this; } + + public function getUser(): ?User + { + return $this->user; + } + + public function setUser(?User $user): static + { + $this->user = $user; + + return $this; + } } diff --git a/src/Entity/User.php b/src/Entity/User.php index 1ac1b4a..5ed164c 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -36,7 +36,7 @@ class User implements UserInterface, TimestampableEntityInterface #[ORM\Column(nullable: true)] private ?\DateTimeImmutable $lastLoginAt = null; - #[ORM\OneToOne(cascade: ['persist', 'remove'])] + #[ORM\OneToOne(inversedBy: 'user', cascade: ['persist', 'remove'])] private ?Teamer $teamer = null; public function __construct() diff --git a/src/Form/JobProfileType.php b/src/Form/JobProfileType.php new file mode 100644 index 0000000..e66af1a --- /dev/null +++ b/src/Form/JobProfileType.php @@ -0,0 +1,55 @@ +add('name', TextType::class, [ + 'label' => 'Bezeichnung', + ]) + ->add('requiredTraining', EntityType::class, [ + 'label' => 'vorausgesetzte Fortbildung', + 'required' => false, + 'placeholder' => 'keine', + 'class' => Training::class, + 'choice_label' => 'name', + 'query_builder' => function (EntityRepository $repository) { + return $repository->createQueryBuilder('job_profile') + ->orderBy('job_profile.name', 'ASC') + ; + }, + ]) + ->add('requiredLicenses', ChoiceType::class, [ + 'label' => 'vorausgesetzte Lizenzen', + 'required' => false, + 'expanded' => true, + 'multiple' => true, + 'choices' => [ + 'Skilehrer*in' => License::TYPE_SKI, + 'Snowboardlehrer*in' => License::TYPE_SNOWBOARD, + ], + ]) + ; + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => JobProfile::class, + ]); + } +} \ No newline at end of file diff --git a/src/Form/TrainingType.php b/src/Form/TrainingType.php new file mode 100644 index 0000000..7d629e2 --- /dev/null +++ b/src/Form/TrainingType.php @@ -0,0 +1,28 @@ +add('name', TextType::class, [ + 'label' => 'Bezeichnung', + ]) + ; + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => Training::class, + ]); + } +} \ No newline at end of file diff --git a/src/Menu/AbstractMenuBuilder.php b/src/Menu/AbstractMenuBuilder.php index b61efcb..90b8d8d 100644 --- a/src/Menu/AbstractMenuBuilder.php +++ b/src/Menu/AbstractMenuBuilder.php @@ -20,17 +20,9 @@ abstract class AbstractMenuBuilder ) { } - protected function assertMobile(array $options): bool + protected function createRootElement(): ItemInterface { - return isset($options['mobile']) && true === (bool) $options['mobile']; - } - - protected function createRootElement(string $class): ItemInterface - { - return $this - ->factory->createItem('root') - ->setChildrenAttribute('class', $class) - ; + return $this->factory->createItem('root'); } protected function getDefaultRouteParameters(string $parameter = 'id', string $default = '0'): array @@ -38,7 +30,40 @@ abstract class AbstractMenuBuilder return [$parameter => $this->requestStack->getMainRequest()->get($parameter, $default)]; } - protected function addLogoutItem(ItemInterface $menu, bool $isMobile = false): void + protected function addAdminItem(ItemInterface $menu): void + { + if ($this->security->isGranted('ROLE_ADMIN')) { + $menu + ->addChild('Adminbereich', ['route' => 'app_admin_index']) + ->setChildrenAttribute('title', 'Adminbereich') + ->setExtra('icon', 'user') + ; + } + } + + protected function addManagerItem(ItemInterface $menu): void + { + if ($this->security->isGranted('ROLE_MANAGER')) { + $menu + ->addChild('Managerbereich', ['route' => 'app_manager_index']) + ->setChildrenAttribute('title', 'Managerbereich') + ->setExtra('icon', 'user') + ; + } + } + + protected function addTeamerItem(ItemInterface $menu): void + { + if ($this->security->isGranted('ROLE_TEAMER')) { + $menu + ->addChild('Teamerbereich', ['route' => 'app_teamer_index']) + ->setChildrenAttribute('title', 'Teamerbereich') + ->setExtra('icon', 'user') + ; + } + } + + protected function addLogoutItem(ItemInterface $menu): void { $token = $this->security->getToken(); @@ -55,19 +80,20 @@ abstract class AbstractMenuBuilder 'class' => 'icon-link', ]) ->setExtra('icon', 'logout') - ->setExtra('icon_only', false === $isMobile) ; } else { $menu ->addChild('Logout', ['route' => 'app_security_logout']) ->setLinkAttributes([ 'title' => 'Logout', - 'class' => 'icon-link', ]) ->setExtra('icon', 'logout') - ->setExtra('icon_only', false === $isMobile) ; } + } + protected function addDivider(ItemInterface $menu): void + { + $menu->addChild('%DIVIDER%'); } } diff --git a/src/Menu/AdminMenuBuilder.php b/src/Menu/AdminMenuBuilder.php index 073f7f9..d472a7f 100644 --- a/src/Menu/AdminMenuBuilder.php +++ b/src/Menu/AdminMenuBuilder.php @@ -6,25 +6,104 @@ use Knp\Menu\ItemInterface; class AdminMenuBuilder extends AbstractMenuBuilder { - public function createHeaderMenu(array $options): ItemInterface - { - $menu = $this->createRootElement(); - $this->addLogoutItem($menu); - - return $menu; - } - public function createMainMenu(array $options): ItemInterface { $menu = $this->createRootElement(); - return $menu; - } + $menu + ->addChild('Dashboard', ['route' => 'app_admin_index']) + ->setChildrenAttribute('title', 'Dashboard') + ->setExtra('icon', 'lab') + ; - public function createMobileMenu(array $options): ItemInterface - { - $menu = $this->createRootElement(true); - $this->addLogoutItem($menu, true); + $menu + ->addChild('Einsatzübersicht', ['route' => 'app_admin_index']) + ->setChildrenAttribute('title', 'Einsatzübersicht') + ->setExtra('icon', 'calendar') + ; + + $menu + ->addChild('Bewerbungsübersicht', ['route' => 'app_admin_index']) + ->setChildrenAttribute('title', 'Bewerbungsübersicht') + ->setExtra('icon', 'mail') + ; + + $menu + ->addChild('Dokumentenübersicht', ['route' => 'app_admin_index']) + ->setChildrenAttribute('title', 'Dokumentenübersicht') + ->setExtra('icon', 'document') + ; + + $menu + ->addChild('Teamerübersicht', ['route' => 'app_admin_teamer_index']) + ->setChildrenAttribute('title', 'Teamerübersicht') + ->setExtra('icon', 'users') + ; + + $systemMenu = $menu + ->addChild('Einstellungen') + ->setExtra('icon', 'settings') + ; + $feeMenu = $systemMenu + ->addChild('Honorare', [ + 'route' => 'app_admin_system_fee_index', + 'linkAttributes' => [ + 'title' => 'Honorare', + ], + 'displayChildren' => false, + ]) + ; + $feeMenu + ->addChild('Honorar anlegen', [ + 'route' => 'app_admin_system_fee_create', + ]) + ; + $feeMenu + ->addChild('Honorar bearbeiten', [ + 'route' => 'app_admin_system_fee_edit', + 'routeParameters' => $this->getDefaultRouteParameters(), + ]) + ; + $trainingMenu = $systemMenu + ->addChild('Fortbildungen', [ + 'route' => 'app_admin_system_training_index', + 'linkAttributes' => [ + 'title' => 'Fortbildungen', + ], + 'displayChildren' => false, + ]) + ; + $trainingMenu + ->addChild('Fortbildung anlegen', [ + 'route' => 'app_admin_system_training_create', + ]) + ; + $trainingMenu + ->addChild('Fortbildung bearbeiten', [ + 'route' => 'app_admin_system_training_edit', + 'routeParameters' => $this->getDefaultRouteParameters(), + ]) + ; + $jobProfileMenu = $systemMenu + ->addChild('Job-Profile', [ + 'route' => 'app_admin_system_job_profile_index', + 'linkAttributes' => [ + 'title' => 'Fortbildungen', + ], + 'displayChildren' => false, + ]) + ; + $jobProfileMenu + ->addChild('Job-Profil anlegen', [ + 'route' => 'app_admin_system_job_profile_create', + ]) + ; + + $this->addDivider($menu); + + $this->addManagerItem($menu); + $this->addTeamerItem($menu); + $this->addLogoutItem($menu); return $menu; } diff --git a/src/Menu/ManagerMenuBuilder.php b/src/Menu/ManagerMenuBuilder.php index 4c2dd9f..a0d7ce7 100644 --- a/src/Menu/ManagerMenuBuilder.php +++ b/src/Menu/ManagerMenuBuilder.php @@ -6,27 +6,13 @@ use Knp\Menu\ItemInterface; class ManagerMenuBuilder extends AbstractMenuBuilder { - public function createHeaderMenu(array $options): ItemInterface - { - $menu = $this->createRootElement(); - - $this->addLogoutItem($menu); - - return $menu; - } - public function createMainMenu(array $options): ItemInterface { $menu = $this->createRootElement(); - return $menu; - } - - public function createMobileMenu(array $options): ItemInterface - { - $menu = $this->createRootElement(true); - - $this->addLogoutItem($menu, true); + $this->addAdminItem($menu); + $this->addTeamerItem($menu); + $this->addLogoutItem($menu); return $menu; } diff --git a/src/Menu/TeamerMenuBuilder.php b/src/Menu/TeamerMenuBuilder.php index 9ccb28f..8373690 100644 --- a/src/Menu/TeamerMenuBuilder.php +++ b/src/Menu/TeamerMenuBuilder.php @@ -6,86 +6,81 @@ use Knp\Menu\ItemInterface; class TeamerMenuBuilder extends AbstractMenuBuilder { - public function createHeaderMenu(array $options): ItemInterface - { - $menu = $this->createRootElement('menu menu--header'); - - $this->addLogoutItem($menu); - - return $menu; - } - public function createMainMenu(array $options): ItemInterface { - $menu = $this->createRootElement('menu menu--main'); - + $menu = $this->createRootElement(); $menu - ->addChild('Einsatzübersicht', ['route' => 'app_teamer_disposition_index']) - ->setLinkAttributes([ - 'title' => 'Einsatzübersicht', - 'class' => 'icon-link', - ]) + ->addChild('Einsatzübersicht', ['route' => 'app_teamer_index']) + ->setChildrenAttribute('title', 'Einsatzübersicht') ->setExtra('icon', 'calendar') - ->setExtra('icon_only', false) ; - $profileMenu = $menu ->addChild('Mein Profil') ->setExtra('icon', 'user') - ->setExtra('icon_only', false) + ->setLinkAttribute('title', 'Mein Profil') ; $profileMenu ->addChild('Stammdaten und Foto', ['route' => 'app_teamer_profile_index']) - ->setLinkAttributes([ - 'title' => 'Mein Profil', - ]) + ->setLinkAttribute('title', 'Stammdaten und Foto') ; $profileMenu ->addChild('Jobprofile & Skills', ['route' => 'app_teamer_profile_skills']) - ->setLinkAttributes([ - 'title' => 'Jobprofile & Skills', - ]) + ->setLinkAttribute('title', 'Jobprofile & Skills') ; $profileMenu ->addChild('Meine Verfügbarkeit', ['route' => 'app_teamer_profile_availabilities']) - ->setLinkAttributes([ - 'title' => 'Meine Verfügbarkeit', - ]) + ->setLinkAttribute('title', 'Meine Verfügbarkeit') ; - $dispositionMenu = $menu ->addChild('Meine Einsätze') - ->setExtra('icon', 'calendar') - ->setExtra('icon_only', false) + ->setExtra('icon', 'bus') ; $dispositionMenu ->addChild('Merkliste', ['route' => 'app_teamer_disposition_watchlist']) - ->setLinkAttributes([ - 'title' => 'Merkliste', - ]) + ->setLinkAttribute('title', 'Merkliste') + ; + $dispositionMenu + ->addChild('Offene Bewerbungen', ['route' => 'app_teamer_disposition_watchlist']) + ->setLinkAttribute('title', 'Offene Bewerbungen') + ; + $dispositionMenu + ->addChild('Nächste Einsätze', ['route' => 'app_teamer_disposition_watchlist']) + ->setLinkAttribute('title', 'Nächste Einsätze') + ; + $dispositionMenu + ->addChild('Letzte Einsätze', ['route' => 'app_teamer_disposition_watchlist']) + ->setLinkAttribute('title', 'Letzte Einsätze') + ; + $dispositionMenu + ->addChild('Meine Dokumente', ['route' => 'app_teamer_disposition_watchlist']) + ->setLinkAttribute('title', 'Meine Dokumente') + ; + $dispositionMenu + ->addChild('Mein Feedback', ['route' => 'app_teamer_disposition_watchlist']) + ->setLinkAttribute('title', 'Mein Feedback') ; - return $menu; - } - - public function createMobileMenu(array $options): ItemInterface - { - $menu = $this->createRootElement('menu menu--mobile'); - - $menu - ->addChild('Profil', ['route' => 'app_teamer_profile_index']) - ->setLinkAttributes([ - 'title' => 'Mein Profil', - 'class' => 'icon-link', - ]) - ->setExtra('icon', 'user') - ->setExtra('icon_only', false) + $faqMenu = $menu + ->addChild('FAQ & Kontakt') + ->setExtra('icon', 'info') + ; + $faqMenu + ->addChild('FAQ', ['route' => 'app_teamer_disposition_watchlist']) + ->setLinkAttribute('title', 'FAQ') + ; + $faqMenu + ->addChild('Kontakt', ['route' => 'app_teamer_disposition_watchlist']) + ->setLinkAttribute('title', 'Kontakt') ; - $this->addLogoutItem($menu, true); + $this->addDivider($menu); + + $this->addAdminItem($menu); + $this->addManagerItem($menu); + $this->addLogoutItem($menu); return $menu; } diff --git a/src/Repository/JobProfileRepository.php b/src/Repository/JobProfileRepository.php index dcd0f51..cb7b4d4 100644 --- a/src/Repository/JobProfileRepository.php +++ b/src/Repository/JobProfileRepository.php @@ -21,46 +21,16 @@ class JobProfileRepository extends ServiceEntityRepository parent::__construct($registry, JobProfile::class); } - public function save(JobProfile $entity, bool $flush = false): void + public function getList(): array { - $this->getEntityManager()->persist($entity); + $qb = $this->createQueryBuilder('job_profile'); - if ($flush) { - $this->getEntityManager()->flush(); - } + return $qb + ->select('job_profile', 'required_training') + ->leftJoin('job_profile.requiredTraining', 'required_training') + ->orderBy('job_profile.name', 'ASC') + ->getQuery() + ->getResult() + ; } - - public function remove(JobProfile $entity, bool $flush = false): void - { - $this->getEntityManager()->remove($entity); - - if ($flush) { - $this->getEntityManager()->flush(); - } - } - -// /** -// * @return JobProfile[] Returns an array of JobProfile objects -// */ -// public function findByExampleField($value): array -// { -// return $this->createQueryBuilder('j') -// ->andWhere('j.exampleField = :val') -// ->setParameter('val', $value) -// ->orderBy('j.id', 'ASC') -// ->setMaxResults(10) -// ->getQuery() -// ->getResult() -// ; -// } - -// public function findOneBySomeField($value): ?JobProfile -// { -// return $this->createQueryBuilder('j') -// ->andWhere('j.exampleField = :val') -// ->setParameter('val', $value) -// ->getQuery() -// ->getOneOrNullResult() -// ; -// } } diff --git a/src/Repository/TeamerRepository.php b/src/Repository/TeamerRepository.php index 23338e6..f09099c 100644 --- a/src/Repository/TeamerRepository.php +++ b/src/Repository/TeamerRepository.php @@ -4,6 +4,7 @@ namespace App\Repository; use App\Entity\Teamer; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\ORM\Query; use Doctrine\Persistence\ManagerRegistry; /** @@ -21,46 +22,13 @@ class TeamerRepository extends ServiceEntityRepository parent::__construct($registry, Teamer::class); } - public function save(Teamer $entity, bool $flush = false): void + public function getListQuery(): Query { - $this->getEntityManager()->persist($entity); + $qb = $this->createQueryBuilder('teamer'); - if ($flush) { - $this->getEntityManager()->flush(); - } + return $qb + ->select('teamer', 'user') + ->leftJoin('teamer.user', 'user') + ->getQuery(); } - - public function remove(Teamer $entity, bool $flush = false): void - { - $this->getEntityManager()->remove($entity); - - if ($flush) { - $this->getEntityManager()->flush(); - } - } - -// /** -// * @return Teamer[] Returns an array of Teamer objects -// */ -// public function findByExampleField($value): array -// { -// return $this->createQueryBuilder('t') -// ->andWhere('t.exampleField = :val') -// ->setParameter('val', $value) -// ->orderBy('t.id', 'ASC') -// ->setMaxResults(10) -// ->getQuery() -// ->getResult() -// ; -// } - -// public function findOneBySomeField($value): ?Teamer -// { -// return $this->createQueryBuilder('t') -// ->andWhere('t.exampleField = :val') -// ->setParameter('val', $value) -// ->getQuery() -// ->getOneOrNullResult() -// ; -// } } diff --git a/src/Repository/TrainingRepository.php b/src/Repository/TrainingRepository.php index 0b71986..707761b 100644 --- a/src/Repository/TrainingRepository.php +++ b/src/Repository/TrainingRepository.php @@ -21,46 +21,16 @@ class TrainingRepository extends ServiceEntityRepository parent::__construct($registry, Training::class); } - public function save(Training $entity, bool $flush = false): void + public function getList(): array { - $this->getEntityManager()->persist($entity); + $qb = $this->createQueryBuilder('training'); - if ($flush) { - $this->getEntityManager()->flush(); - } + return $qb + ->select('training', 'training_attendance') + ->leftJoin('training.trainingAttendances', 'training_attendance') + ->orderBy('training.name', 'ASC') + ->getQuery() + ->getResult() + ; } - - public function remove(Training $entity, bool $flush = false): void - { - $this->getEntityManager()->remove($entity); - - if ($flush) { - $this->getEntityManager()->flush(); - } - } - -// /** -// * @return Training[] Returns an array of Training objects -// */ -// public function findByExampleField($value): array -// { -// return $this->createQueryBuilder('t') -// ->andWhere('t.exampleField = :val') -// ->setParameter('val', $value) -// ->orderBy('t.id', 'ASC') -// ->setMaxResults(10) -// ->getQuery() -// ->getResult() -// ; -// } - -// public function findOneBySomeField($value): ?Training -// { -// return $this->createQueryBuilder('t') -// ->andWhere('t.exampleField = :val') -// ->setParameter('val', $value) -// ->getQuery() -// ->getOneOrNullResult() -// ; -// } } diff --git a/src/Twig/AppRuntime.php b/src/Twig/AppRuntime.php index 6feab02..b9bb483 100644 --- a/src/Twig/AppRuntime.php +++ b/src/Twig/AppRuntime.php @@ -45,7 +45,7 @@ class AppRuntime implements RuntimeExtensionInterface return $this->intlExtension->formatCurrency($amount, 'EUR'); } - public function renderIcon(Environment $environment, string $icon, string $classes = 'w-6 h-6'): string + public function renderIcon(Environment $environment, string $icon, string $classes = 'w-5 h-5'): string { return $environment->render('_partials/_icon.html.twig', [ 'icon' => $icon, diff --git a/symfony.lock b/symfony.lock index c7b0436..7009ce6 100644 --- a/symfony.lock +++ b/symfony.lock @@ -29,6 +29,9 @@ "knplabs/knp-menu-bundle": { "version": "v3.2.0" }, + "knplabs/knp-paginator-bundle": { + "version": "v6.2.0" + }, "liip/imagine-bundle": { "version": "2.11", "recipe": { diff --git a/templates/_partials/_confirmation_modal.html.twig b/templates/_partials/_confirmation_modal.html.twig index 59cad8f..0fa9a74 100644 --- a/templates/_partials/_confirmation_modal.html.twig +++ b/templates/_partials/_confirmation_modal.html.twig @@ -7,7 +7,7 @@
{{ icon('alert', 'w-8 h-8') }} - +
-
+
diff --git a/templates/_partials/_menu.html.twig b/templates/_partials/_menu.html.twig index 3c9ec3b..e23d7a9 100644 --- a/templates/_partials/_menu.html.twig +++ b/templates/_partials/_menu.html.twig @@ -1,27 +1,83 @@ {% extends 'knp_menu.html.twig' %} +{% block list %} + {% if item.hasChildren and options.depth is not same as(0) and item.displayChildren %} + {% if item.level == 0 %} +
+ +
+ {% else %} +
    + {{ block('children') }} +
+ {% endif %} + {% endif %} +{% endblock %} + +{% block item %} + {% if item.displayed %} +
  • + {%- if item.hasChildren and item.displayChildren %} +
    + {%- endif %} + {%- if item.uri is not empty %} + {{ block('linkElement') }} + {%- else %} + {{ block('spanElement') }} + {%- endif %} + {{ block('list') }} + {%- if item.hasChildren and item.displayChildren %} +
    + {%- endif %} +
  • + {% endif %} +{% endblock %} + +{% block linkElement %} + {% import _self as knp_menu %} + + {{ block('label') }} + +{% endblock %} + +{% block spanElement %} + {% import _self as knp_menu %} + {% if item.hasChildren %} + + {% elseif item.label == '%DIVIDER%' %} +
    + {% else %} +
    + {{ block('label') }} +
    + {% endif %} +{% endblock %} + {% block label %} {% apply spaceless %} {% if item.extras.icon is defined %} - {{ icon(item.extras.icon, 'w-5 h-5') }} - {% if item.extras.icon_only is defined and false == item.extras.icon_only %} - {{ item.label|raw }} - {% endif %} + {{ icon(item.extras.icon, 'h-6 w-6 shrink-0 text-gray-400') }} + {{ item.label|raw }} {% else %} {{ item.label|raw }} {% endif %} {% endapply %} {% endblock %} -{% block spanElement %} -
    - {% if item.extras.icon is defined %} - {{ icon(item.extras.icon, 'w-5 h-5') }} - {% if item.extras.icon_only is defined and false == item.extras.icon_only %} - {{ item.label|raw }} - {% endif %} - {% else %} - {{ item.label|raw }} - {% endif %} -
    -{% endblock %} diff --git a/templates/_partials/_page_header.html.twig b/templates/_partials/_page_header.html.twig deleted file mode 100644 index 3238eea..0000000 --- a/templates/_partials/_page_header.html.twig +++ /dev/null @@ -1,18 +0,0 @@ -
    -
    - -
    - -
    -
    - - -
    -
    diff --git a/templates/_partials/_sidebar_menu.html.twig b/templates/_partials/_sidebar_menu.html.twig deleted file mode 100644 index c0129d0..0000000 --- a/templates/_partials/_sidebar_menu.html.twig +++ /dev/null @@ -1,68 +0,0 @@ -
    - -
    diff --git a/templates/admin/layout.html.twig b/templates/admin/layout.html.twig index 33b8ec7..1248458 100644 --- a/templates/admin/layout.html.twig +++ b/templates/admin/layout.html.twig @@ -1,9 +1,9 @@ {% extends 'layout.html.twig' %} -{% block header_menu %} - {{ knp_menu_render(knp_menu_get('admin_header'), { 'firstClass': null, 'lastClass': null, 'ancestorClass': 'active', 'compressed': true }) }} +{% block main_menu %} + {{ knp_menu_render(knp_menu_get('admin_main')) }} {% endblock %} {% block mobile_menu %} - {{ knp_menu_render(knp_menu_get('admin_mobile'), { 'firstClass': null, 'lastClass': null, 'ancestorClass': 'active', 'compressed': true }) }} -{% endblock %} \ No newline at end of file + {{ knp_menu_render(knp_menu_get('admin_main')) }} +{% endblock %} diff --git a/templates/admin/system/fee/_form.html.twig b/templates/admin/system/fee/_form.html.twig index 79bd00a..b40e1ee 100644 --- a/templates/admin/system/fee/_form.html.twig +++ b/templates/admin/system/fee/_form.html.twig @@ -3,8 +3,13 @@ {{ form_row(form.name) }} {{ form_row(form.value) }}
    - +
    + + + Abbrechen + +
    {{ form_rest(form) }} {{ form_end(form) }} diff --git a/templates/admin/system/fee/create.html.twig b/templates/admin/system/fee/create.html.twig index a13a649..fd4fe84 100644 --- a/templates/admin/system/fee/create.html.twig +++ b/templates/admin/system/fee/create.html.twig @@ -1,21 +1,12 @@ -{% extends 'layout.html.twig' %} +{% extends 'admin/layout.html.twig' %} -{% block title %}Honorare{% endblock %} +{% block title %}Einstellungen - Honorar anlegen{% endblock %} {% block content %} -
    - -
    -
    -

    - Honorar anlegen -

    - {% include 'admin/system/fee/_form.html.twig' %} -
    -
    +
    +

    + Honorar anlegen +

    + {% include 'admin/system/fee/_form.html.twig' %}
    {% endblock %} \ No newline at end of file diff --git a/templates/admin/system/fee/edit.html.twig b/templates/admin/system/fee/edit.html.twig index f82944e..6751296 100644 --- a/templates/admin/system/fee/edit.html.twig +++ b/templates/admin/system/fee/edit.html.twig @@ -1,21 +1,12 @@ -{% extends 'layout.html.twig' %} +{% extends 'admin/layout.html.twig' %} -{% block title %}Honorare{% endblock %} +{% block title %}Einstellungen - Honorar bearbeiten{% endblock %} {% block content %} -
    - -
    -
    -

    - Honorar bearbeiten -

    - {% include 'admin/system/fee/_form.html.twig' %} -
    -
    +
    +

    + Honorar bearbeiten +

    + {% include 'admin/system/fee/_form.html.twig' %}
    {% endblock %} \ No newline at end of file diff --git a/templates/admin/system/fee/index.html.twig b/templates/admin/system/fee/index.html.twig index b879928..7107406 100644 --- a/templates/admin/system/fee/index.html.twig +++ b/templates/admin/system/fee/index.html.twig @@ -1,47 +1,64 @@ -{% extends 'layout.html.twig' %} +{% extends 'admin/layout.html.twig' %} -{% block title %}Honorare{% endblock %} +{% block title %}Einstellungen - Honorare{% endblock %} {% block content %} -
    - -
    -

    - Honorare -

    -
    - {% for fee in fees %} -
    -
    - {{ fee.name }} -
    -
    - {{ fee.value|format_money }} -
    -
    - - - {{ icon('edit') }} - -
    -
    - {% else %} -
    Keine Daten...
    - {% endfor %} +

    + Honorare +

    +
    +
    + + + + + + + + + + {% for fee in fees %} + + + + + + {% else %} + + + + {% endfor %} + +
    + Bezeichnung + + Wert +
    + {{ fee.name }} + + {{ fee.value|format_money }} + +
    + + + {{ icon('edit') }} + +
    +
    +
    Keine Daten...
    +
    -
    + + Neu + {% endblock %} \ No newline at end of file diff --git a/templates/admin/system/job_profile/_form.html.twig b/templates/admin/system/job_profile/_form.html.twig new file mode 100644 index 0000000..538096e --- /dev/null +++ b/templates/admin/system/job_profile/_form.html.twig @@ -0,0 +1,16 @@ +{{ form_start(form) }} +
    + {{ form_row(form.name) }} + {{ form_row(form.requiredTraining) }} + {{ form_widget(form.requiredLicenses) }} +
    +
    + + + Abbrechen + +
    +{{ form_rest(form) }} +{{ form_end(form) }} diff --git a/templates/admin/system/job_profile/create.html.twig b/templates/admin/system/job_profile/create.html.twig new file mode 100644 index 0000000..e9682ca --- /dev/null +++ b/templates/admin/system/job_profile/create.html.twig @@ -0,0 +1,12 @@ +{% extends 'admin/layout.html.twig' %} + +{% block title %}Einstellungen - Job-Profil anlegen{% endblock %} + +{% block content %} +
    +

    + Job-Profil anlegen +

    + {% include 'admin/system/job_profile/_form.html.twig' %} +
    +{% endblock %} \ No newline at end of file diff --git a/templates/admin/system/job_profile/index.html.twig b/templates/admin/system/job_profile/index.html.twig new file mode 100644 index 0000000..9f7126f --- /dev/null +++ b/templates/admin/system/job_profile/index.html.twig @@ -0,0 +1,57 @@ +{% extends 'admin/layout.html.twig' %} + +{% block title %}Einstellungen - Jobprofile{% endblock %} + +{% block content %} +

    + Job-Profile +

    +
    +
    + + + + + + + + + + + {% for jobProfile in jobProfiles %} + + + + + + + {% else %} + + + + {% endfor %} + +
    + Bezeichnung + + Fortbildung + + Lizenzen +
    + {{ jobProfile.name }} + + {{ jobProfile.requiredTraining|default('-') }} + + {{ jobProfile.requiredLicenses|join(', ') }} + +
    +
    +
    +
    Keine Daten...
    +
    +
    +
    + + Neu + +{% endblock %} \ No newline at end of file diff --git a/templates/admin/system/training/_form.html.twig b/templates/admin/system/training/_form.html.twig new file mode 100644 index 0000000..ae500bf --- /dev/null +++ b/templates/admin/system/training/_form.html.twig @@ -0,0 +1,14 @@ +{{ form_start(form) }} +
    + {{ form_row(form.name) }} +
    +
    + + + Abbrechen + +
    +{{ form_rest(form) }} +{{ form_end(form) }} diff --git a/templates/admin/system/training/create.html.twig b/templates/admin/system/training/create.html.twig new file mode 100644 index 0000000..9cbcca2 --- /dev/null +++ b/templates/admin/system/training/create.html.twig @@ -0,0 +1,12 @@ +{% extends 'admin/layout.html.twig' %} + +{% block title %}Einstellungen - Fortbildung anlegen{% endblock %} + +{% block content %} +
    +

    + Fortbildung anlegen +

    + {% include 'admin/system/training/_form.html.twig' %} +
    +{% endblock %} \ No newline at end of file diff --git a/templates/admin/system/training/edit.html.twig b/templates/admin/system/training/edit.html.twig new file mode 100644 index 0000000..af8179b --- /dev/null +++ b/templates/admin/system/training/edit.html.twig @@ -0,0 +1,12 @@ +{% extends 'admin/layout.html.twig' %} + +{% block title %}Einstellungen - Fortbildung bearbeiten{% endblock %} + +{% block content %} +
    +

    + Fortbildung bearbeiten +

    + {% include 'admin/system/training/_form.html.twig' %} +
    +{% endblock %} \ No newline at end of file diff --git a/templates/admin/system/training/index.html.twig b/templates/admin/system/training/index.html.twig new file mode 100644 index 0000000..1ae0316 --- /dev/null +++ b/templates/admin/system/training/index.html.twig @@ -0,0 +1,51 @@ +{% extends 'admin/layout.html.twig' %} + +{% block title %}Einstellungen - Fortbildungen{% endblock %} + +{% block content %} +

    + Fortbildungen +

    +
    +
    + + + + + + + + + + {% for training in trainings %} + + + + + + {% else %} + + + + {% endfor %} + +
    + Bezeichnung + + Teilnahmen +
    + {{ training.name }} + + {{ training.trainingAttendances|length|default('-') }} + +
    +
    +
    +
    Keine Daten...
    +
    +
    +
    + + Neu + +{% endblock %} \ No newline at end of file diff --git a/templates/admin/teamer/index.html.twig b/templates/admin/teamer/index.html.twig new file mode 100644 index 0000000..41a4bda --- /dev/null +++ b/templates/admin/teamer/index.html.twig @@ -0,0 +1,69 @@ +{% extends 'admin/layout.html.twig' %} + +{% block title %}Teamerübersicht{% endblock %} + +{% block content %} +

    + Teamerübersicht +

    +
    +
    + + + + + + + + + + + + + {% for teamer in pagination %} + + + + + + + + + {% endfor %} + +
    + {{ knp_pagination_sortable(pagination, 'Name', 'teamer.lastName') }} + + Vorname + + {{ knp_pagination_sortable(pagination, 'Status', 'teamer.status') }} + + {{ knp_pagination_sortable(pagination, 'E-Mail', 'teamer.communication.email') }} + + {{ knp_pagination_sortable(pagination, 'Letzter Login', 'teamer.lastLoginAt') }} +
    + + {{ teamer.lastName }} + + + + {{ teamer.firstName }} + + + {{ teamer.status }} + + {{ teamer.communication.email }} + + {% if teamer.user.lastLoginAt is not null %} + {{ teamer.user.lastLoginAt | date('d.m.Y') }} + {% else %} + - + {% endif %} + +
    +
    +
    + {{ knp_pagination_render(pagination) }} +
    +
    +{% endblock %} \ No newline at end of file diff --git a/templates/base.html.twig b/templates/base.html.twig index b7a8dde..df7965d 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -14,7 +14,7 @@ {{ encore_entry_script_tags('app') }} {% endblock %} - + {% block body %}{% endblock %} {% include '_partials/_flashes.html.twig' %} diff --git a/templates/forms.html.twig b/templates/forms.html.twig index fd5e589..daff5f3 100644 --- a/templates/forms.html.twig +++ b/templates/forms.html.twig @@ -35,11 +35,11 @@ {%- block form_widget_simple -%} {%- set type = type|default('text') -%} {%- if type != 'hidden' -%} - {%- set attr = attr|merge({'class': (attr.class|default('') ~ ' mt-2 block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-primary sm:text-sm sm:leading-6')|trim }) -%} + {%- set attr = attr|merge({'class': (attr.class|default('') ~ ' mt-2 block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset sm:text-sm sm:leading-6')|trim }) -%} {%- if errors|length -%} {%- set attr = attr|merge({'class': attr.class|default('') ~ ' ring-red-500 placeholder-red-500 focus:ring-red-500' }) -%} {% else %} - {%- set attr = attr|merge({'class': attr.class|default('') ~ ' placeholder:text-slate-400 focus:ring-primary' }) -%} + {%- set attr = attr|merge({'class': attr.class|default('') ~ ' placeholder:text-gray-400 focus:ring-primary' }) -%} {%- endif -%} {%- if disabled is defined and disabled == true -%} {%- set attr = attr|merge({'class': attr.class|default('') ~ ' cursor-not-allowed' }) -%} @@ -52,11 +52,11 @@ {%- endblock form_widget_simple -%} {%- block textarea_widget -%} - {%- set attr = attr|merge({'class': (attr.class|default('') ~ ' mt-2 block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-primary sm:text-sm sm:leading-6')|trim }) -%} + {%- set attr = attr|merge({'class': (attr.class|default('') ~ ' mt-2 block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset sm:text-sm sm:leading-6')|trim }) -%} {%- if errors|length -%} {%- set attr = attr|merge({'class': attr.class|default('') ~ ' ring-red-500 placeholder-red-500 focus:ring-red-500' }) -%} {% else %} - {%- set attr = attr|merge({'class': attr.class|default('') ~ ' placeholder:text-slate-400 focus:ring-1 focus:ring-primary' }) -%} + {%- set attr = attr|merge({'class': attr.class|default('') ~ ' placeholder:text-gray-400 focus:ring-primary' }) -%} {%- endif -%} {%- if disabled is defined and disabled == true -%} {%- set attr = attr|merge({'class': attr.class|default('') ~ ' cursor-not-allowed' }) -%} @@ -68,11 +68,11 @@ {%- endblock textarea_widget -%} {%- block choice_widget_collapsed -%} - {%- set attr = attr|merge({'class': (attr.class|default('') ~ ' mt-2 block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-primary sm:text-sm sm:leading-6')|trim }) -%} + {%- set attr = attr|merge({'class': (attr.class|default('') ~ ' mt-2 block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset sm:text-sm sm:leading-6')|trim }) -%} {%- if errors|length -%} {%- set attr = attr|merge({'class': attr.class|default('') ~ ' ring-red-500 placeholder-red-500 focus:ring-red-500' }) -%} {% else %} - {%- set attr = attr|merge({'class': attr.class|default('') ~ ' placeholder:text-slate-400 focus:ring-1 focus:ring-primary' }) -%} + {%- set attr = attr|merge({'class': attr.class|default('') ~ ' placeholder:text-gray-400 focus:ring-primary' }) -%} {%- endif -%} {%- if disabled is defined and disabled == true -%} {%- set attr = attr|merge({'class': attr.class|default('') ~ ' cursor-not-allowed' }) -%} @@ -83,6 +83,30 @@ {%- endif -%} {%- endblock choice_widget_collapsed -%} +{%- block choice_widget_expanded -%} +
    + {% if form.vars.label %} + + {{ form.vars.label }} + + {% endif %} +
    + {%- for child in form %} +
    +
    + +
    +
    + +
    +
    + {% endfor -%} +
    +
    +{%- endblock choice_widget_expanded -%} + {%- block birthday_widget -%}
    {{ form_widget(form.children['day']) }} diff --git a/templates/layout.html.twig b/templates/layout.html.twig index 72d0292..8e34a68 100644 --- a/templates/layout.html.twig +++ b/templates/layout.html.twig @@ -1,12 +1,23 @@ {% extends 'base.html.twig' %} {% block body %} -
    -
    +
    +
    My E&P Team + +
    - {% include '_partials/_sidebar_menu.html.twig' %} -
    + +
    {% block content %}{% endblock %}
    @@ -17,14 +28,14 @@ {{ stimulus_controller('mobilenav', [], { 'closed': '-translate-x-full' }, { 'mobilenav': '#mobilenav' }) }} >
    -
    +
    -
    +
    {% block mobile_menu %}{% endblock %}
    diff --git a/templates/manager/index.html.twig b/templates/manager/index.html.twig index 19aa1c4..7b6109e 100644 --- a/templates/manager/index.html.twig +++ b/templates/manager/index.html.twig @@ -1,4 +1,4 @@ -{% extends 'layout.html.twig' %} +{% extends 'manager/layout.html.twig' %} {% block content %} {% endblock %} \ No newline at end of file diff --git a/templates/manager/layout.html.twig b/templates/manager/layout.html.twig index bae5209..039e670 100644 --- a/templates/manager/layout.html.twig +++ b/templates/manager/layout.html.twig @@ -1,9 +1,9 @@ {% extends 'layout.html.twig' %} -{% block header_menu %} - {{ knp_menu_render(knp_menu_get('manager_header'), { 'firstClass': null, 'lastClass': null, 'ancestorClass': 'active', 'compressed': true }) }} +{% block main_menu %} + {{ knp_menu_render(knp_menu_get('manager_main')) }} {% endblock %} {% block mobile_menu %} - {{ knp_menu_render(knp_menu_get('manager_mobile'), { 'firstClass': null, 'lastClass': null, 'ancestorClass': 'active', 'compressed': true }) }} -{% endblock %} \ No newline at end of file + {{ knp_menu_render(knp_menu_get('manager_main')) }} +{% endblock %} diff --git a/templates/paginator/sliding.html.twig b/templates/paginator/sliding.html.twig new file mode 100644 index 0000000..f152a03 --- /dev/null +++ b/templates/paginator/sliding.html.twig @@ -0,0 +1,42 @@ +
    +
    +
    +

    {{ 'label.paginator.info'|trans({ '{from}': firstItemNumber, '{to}': lastItemNumber, '{total}': totalCount })|raw }}

    +
    +
    + +
    +
    +
    diff --git a/templates/paginator/sortable_link.html.twig b/templates/paginator/sortable_link.html.twig new file mode 100644 index 0000000..8503005 --- /dev/null +++ b/templates/paginator/sortable_link.html.twig @@ -0,0 +1,15 @@ + + {{ title }} + {%- if sorted -%} + {%- if direction == 'desc' -%} + + + + {%- else -%} + + + + {%- endif -%} + {%- endif -%} + + diff --git a/templates/security/login.html.twig b/templates/security/login.html.twig index 12627c9..a29f266 100644 --- a/templates/security/login.html.twig +++ b/templates/security/login.html.twig @@ -19,15 +19,15 @@ - +
    - +
    - diff --git a/templates/teamer/layout.html.twig b/templates/teamer/layout.html.twig index 974a8d7..d8c58c8 100644 --- a/templates/teamer/layout.html.twig +++ b/templates/teamer/layout.html.twig @@ -1,13 +1,9 @@ {% extends 'layout.html.twig' %} -{% block header_menu %} - {{ knp_menu_render(knp_menu_get('teamer_header'), { 'firstClass': null, 'lastClass': null, 'ancestorClass': 'active', 'compressed': true }) }} -{% endblock %} - {% block main_menu %} - {{ knp_menu_render(knp_menu_get('teamer_main'), { 'firstClass': null, 'lastClass': null, 'ancestorClass': 'active', 'compressed': true }) }} + {{ knp_menu_render(knp_menu_get('teamer_main')) }} {% endblock %} {% block mobile_menu %} - {{ knp_menu_render(knp_menu_get('teamer_mobile'), { 'firstClass': null, 'lastClass': null, 'ancestorClass': 'active', 'compressed': true }) }} -{% endblock %} \ No newline at end of file + {{ knp_menu_render(knp_menu_get('teamer_main')) }} +{% endblock %} diff --git a/templates/teamer/profile/availabilities.html.twig b/templates/teamer/profile/availabilities.html.twig new file mode 100644 index 0000000..9306952 --- /dev/null +++ b/templates/teamer/profile/availabilities.html.twig @@ -0,0 +1,6 @@ +{% extends 'teamer/layout.html.twig' %} + +{% block title %}Meine Verfügbarkeit{% endblock %} + +{% block content %} +{% endblock %} \ No newline at end of file diff --git a/templates/teamer/profile.html.twig b/templates/teamer/profile/index.html.twig similarity index 69% rename from templates/teamer/profile.html.twig rename to templates/teamer/profile/index.html.twig index bc5c13e..0da560d 100644 --- a/templates/teamer/profile.html.twig +++ b/templates/teamer/profile/index.html.twig @@ -18,30 +18,34 @@ {{ form_start(form) }}
    -
    -
      -
    • - -
    • -
    • - -
    • -
    • - -
    • -
    • - -
    • -
    +
    +

    + Mein Profil +

    +
      +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    +
    {% if not form.vars.valid %}
    @@ -62,9 +66,9 @@
    {% endif %}
    -

    +

    Persönliche Daten -

    +
    {{ form_row(form.salutation) }} {{ form_row(form.academicTitle) }} @@ -77,18 +81,18 @@
    -

    +

    Anschrift -

    +
    {{ form_row(form.address.street) }} {{ form_row(form.address.postCode) }} {{ form_row(form.address.city) }} {{ form_row(form.address.country) }}
    -

    +

    Kontakt -

    +
    {{ form_row(form.communication.email) }} {{ form_row(form.communication.phone) }} @@ -97,9 +101,9 @@
    -

    +

    Bankverbindung -

    +
    {{ form_row(form.bankAccount.iban) }} {{ form_row(form.bankAccount.bic) }} @@ -109,17 +113,17 @@
    -

    +

    Sonstiges -

    +
    {{ form_row(form.taxId) }} {{ form_row(form.healthInsuranceCompany) }} {{ form_row(form.remarks) }}
    -

    +

    Fotoupload -

    +
    {% include '_partials/_upload_collection_form.html.twig' with { diff --git a/templates/teamer/profile/skills.html.twig b/templates/teamer/profile/skills.html.twig new file mode 100644 index 0000000..551691e --- /dev/null +++ b/templates/teamer/profile/skills.html.twig @@ -0,0 +1,6 @@ +{% extends 'teamer/layout.html.twig' %} + +{% block title %}Meine Jobprofile & Skills{% endblock %} + +{% block content %} +{% endblock %} \ No newline at end of file