diff --git a/migrations/Version20240623161718.php b/migrations/Version20240623161718.php new file mode 100644 index 0000000..8981031 --- /dev/null +++ b/migrations/Version20240623161718.php @@ -0,0 +1,31 @@ +addSql('CREATE TABLE news (id INT AUTO_INCREMENT NOT NULL, status SMALLINT NOT NULL, message LONGTEXT NOT NULL, created_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', updated_at DATETIME DEFAULT NULL COMMENT \'(DC2Type:datetime_immutable)\', created_by VARCHAR(255) DEFAULT NULL, updated_by VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('DROP TABLE news'); + } +} diff --git a/src/Controller/Administrative/System/News/CreateController.php b/src/Controller/Administrative/System/News/CreateController.php new file mode 100644 index 0000000..f6564b4 --- /dev/null +++ b/src/Controller/Administrative/System/News/CreateController.php @@ -0,0 +1,50 @@ +createForm(NewsType::class, $news, [ + 'hx_post' => $request->getUri(), + ]); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $this->entityManager->persist($news); + $this->entityManager->flush(); + + $this->addFlash('success', 'News wurden erstellt'); + $this->logger->info('Create news', [ + 'news_id' => $news->getId(), + ]); + + return new HxRedirectResponse($this->generateUrl('app_administrative_system_news_index')); + } + + return $this->render('administrative/system/news/modal_create.html.twig', [ + 'form' => $form->createView(), + ]); + } +} \ No newline at end of file diff --git a/src/Controller/Administrative/System/News/DeleteController.php b/src/Controller/Administrative/System/News/DeleteController.php new file mode 100644 index 0000000..584dbfd --- /dev/null +++ b/src/Controller/Administrative/System/News/DeleteController.php @@ -0,0 +1,43 @@ +isMethod('POST')) { + $this->entityManager->remove($news); + $this->entityManager->flush(); + + $this->addFlash('success', 'Die Nachricht wurde gelöscht'); + $this->logger->info('Delete news', [ + 'news' => $news->getMessage(), + ]); + + return new HxRedirectResponse($this->generateUrl('app_administrative_system_news_index')); + } + + return $this->render('administrative/system/news/modal_delete.html.twig', [ + 'news' => $news, + ]); + } +} \ No newline at end of file diff --git a/src/Controller/Administrative/System/News/EditController.php b/src/Controller/Administrative/System/News/EditController.php new file mode 100644 index 0000000..9c26cf5 --- /dev/null +++ b/src/Controller/Administrative/System/News/EditController.php @@ -0,0 +1,49 @@ +createForm(NewsType::class, $news, [ + 'hx_post' => $request->getUri(), + ]); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $this->entityManager->persist($news); + $this->entityManager->flush(); + + $this->addFlash('success', 'News wurden aktualisiert.'); + $this->logger->info('Edit news', [ + 'news_id' => $news->getId(), + ]); + + return new HxRedirectResponse($this->generateUrl('app_administrative_system_news_index')); + } + + return $this->render('administrative/system/news/modal_edit.html.twig', [ + 'form' => $form->createView(), + ]); + } +} \ No newline at end of file diff --git a/src/Controller/Administrative/System/News/IndexController.php b/src/Controller/Administrative/System/News/IndexController.php new file mode 100644 index 0000000..43db302 --- /dev/null +++ b/src/Controller/Administrative/System/News/IndexController.php @@ -0,0 +1,36 @@ +repository + ->findBy([], ['createdAt' => 'DESC']) + ; + + $activeNews = $this + ->repository + ->getLatestForDashboard() + ; + + return $this->render('administrative/system/news/index.html.twig', [ + 'news' => $news, + 'activeNews' => $activeNews, + ]); + } +} \ No newline at end of file diff --git a/src/Controller/Teamer/IndexController.php b/src/Controller/Teamer/IndexController.php index 1e6898b..fbc40cb 100644 --- a/src/Controller/Teamer/IndexController.php +++ b/src/Controller/Teamer/IndexController.php @@ -6,6 +6,7 @@ use App\Entity\Application; use App\Entity\Assignment; use App\Entity\Disposition; use App\Entity\Feedback; +use App\Entity\News; use App\Entity\User; use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -27,6 +28,12 @@ class IndexController extends AbstractController $user = $this->getUser(); $teamer = $user->getTeamer(); + $news = $this + ->entityManager + ->getRepository(News::class) + ->getLatestForDashboard() + ; + $matchingAssignments = $this ->entityManager ->getRepository(Assignment::class) @@ -60,6 +67,7 @@ class IndexController extends AbstractController $dispositionDocuments = $this->processDocuments($upcomingDispositions); return $this->render('teamer/index.html.twig', [ + 'news' => $news, 'teamer' => $teamer, 'matchingAssignments' => $matchingAssignments, 'recentFeedback' => $recentFeedback, diff --git a/src/Entity/News.php b/src/Entity/News.php new file mode 100644 index 0000000..0666752 --- /dev/null +++ b/src/Entity/News.php @@ -0,0 +1,65 @@ +status = static::STATUS_DEACTIVATED; + } + + public function getId(): ?int + { + return $this->id; + } + + public function getStatus(): ?int + { + return $this->status; + } + + public function setStatus(?int $status): static + { + $this->status = $status; + + return $this; + } + + public function getMessage(): ?string + { + return $this->message; + } + + public function setMessage(?string $message): static + { + $this->message = $message; + + return $this; + } +} diff --git a/src/Form/NewsType.php b/src/Form/NewsType.php new file mode 100644 index 0000000..c836d98 --- /dev/null +++ b/src/Form/NewsType.php @@ -0,0 +1,40 @@ +add('status', ChoiceType::class, [ + 'label' => 'Status', + 'choices' => [ + 'label.news.status.0' => News::STATUS_DEACTIVATED, + 'label.news.status.1' => News::STATUS_ACTIVE, + 'label.news.status.2' => News::STATUS_IMPORTANT, + ], + ]) + ->add('message', TextareaType::class, [ + 'label' => 'Nachricht', + 'attr' => [ + 'rows' => 5, + ], + ]) + ; + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => News::class, + ]); + } +} \ No newline at end of file diff --git a/src/Menu/AdminMenuBuilder.php b/src/Menu/AdminMenuBuilder.php index 614a6ed..a9580b5 100644 --- a/src/Menu/AdminMenuBuilder.php +++ b/src/Menu/AdminMenuBuilder.php @@ -159,6 +159,17 @@ class AdminMenuBuilder extends AbstractMenuBuilder ], ], ]); + $settingsMenu->addChild('News', [ + 'route' => 'app_administrative_system_news_index', + 'linkAttributes' => [ + 'title' => 'News', + ], + 'extras' => [ + 'routes' => [ + ['pattern' => '/^app_administrative_system_news_/'] + ], + ], + ]); $settingsMenu->addChild('Dokumente', [ 'route' => 'app_administrative_system_document_index', 'linkAttributes' => [ diff --git a/src/Menu/ManagerMenuBuilder.php b/src/Menu/ManagerMenuBuilder.php index 3f4cd59..1ffb0b9 100644 --- a/src/Menu/ManagerMenuBuilder.php +++ b/src/Menu/ManagerMenuBuilder.php @@ -94,6 +94,17 @@ class ManagerMenuBuilder extends AbstractMenuBuilder ], ], ]); + $settingsMenu->addChild('News', [ + 'route' => 'app_administrative_system_news_index', + 'linkAttributes' => [ + 'title' => 'News', + ], + 'extras' => [ + 'routes' => [ + ['pattern' => '/^app_administrative_system_news_/'] + ], + ], + ]); $settingsMenu->addChild('Dokumente', [ 'route' => 'app_administrative_system_document_index', 'linkAttributes' => [ diff --git a/src/Repository/NewsRepository.php b/src/Repository/NewsRepository.php new file mode 100644 index 0000000..41f0400 --- /dev/null +++ b/src/Repository/NewsRepository.php @@ -0,0 +1,33 @@ + + */ +class NewsRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, News::class); + } + + public function getLatestForDashboard(): ?News + { + $qb = $this->createQueryBuilder('news'); + + return $qb + ->where($qb->expr()->neq('news.status', ':status')) + ->orderBy('news.status', 'DESC') + ->addOrderBy('news.createdAt', 'DESC') + ->setParameter('status', News::STATUS_DEACTIVATED) + ->setMaxResults(1) + ->getQuery() + ->getOneOrNullResult() + ; + } +} diff --git a/templates/administrative/system/news/form.html.twig b/templates/administrative/system/news/form.html.twig new file mode 100644 index 0000000..d3d99bc --- /dev/null +++ b/templates/administrative/system/news/form.html.twig @@ -0,0 +1,10 @@ +{{ form_start(form) }} +
+ {{ form_row(form.status) }} + {{ form_row(form.message) }} +
+ +{{ form_rest(form) }} +{{ form_end(form) }} diff --git a/templates/administrative/system/news/index.html.twig b/templates/administrative/system/news/index.html.twig new file mode 100644 index 0000000..ae75da2 --- /dev/null +++ b/templates/administrative/system/news/index.html.twig @@ -0,0 +1,84 @@ +{% extends 'administrative/layout.html.twig' %} + +{% block title %}News{% endblock %} + +{% block content %} +

+ News +

+
+
+ + + + + + + + + + + + {% for item in news %} + + + + + + + + {% else %} + + + + {% endfor %} + +
+ {{ icon('eye', 'w-4 h-4') }} + + Nachricht + + Status + + erstellt +
+ {% if item == activeNews %} + + + + {% endif %} + + {{ item.message | u.truncate(48, '...') }} + + {{ ('label.news.status.' ~ item.status) | trans }} + + {{ item.createdAt | date('d.m.Y') }} + +
+ + +
+
+ Keine Daten... +
+
+
+ +{% endblock %} \ No newline at end of file diff --git a/templates/administrative/system/news/modal_create.html.twig b/templates/administrative/system/news/modal_create.html.twig new file mode 100644 index 0000000..11a89c1 --- /dev/null +++ b/templates/administrative/system/news/modal_create.html.twig @@ -0,0 +1,7 @@ +{% extends 'htmx_modal.html.twig' %} + +{% block title %}News anlegen{% endblock %} + +{% block content %} + {% include 'administrative/system/news/form.html.twig' %} +{% endblock %} \ No newline at end of file diff --git a/templates/administrative/system/news/modal_delete.html.twig b/templates/administrative/system/news/modal_delete.html.twig new file mode 100644 index 0000000..5dab3ab --- /dev/null +++ b/templates/administrative/system/news/modal_delete.html.twig @@ -0,0 +1,7 @@ +{% extends 'htmx_confirmation_modal.html.twig' %} + +{% block content %} +
+ Möchtest du die News wirklich löschen? +
+{% endblock %} \ No newline at end of file diff --git a/templates/administrative/system/news/modal_edit.html.twig b/templates/administrative/system/news/modal_edit.html.twig new file mode 100644 index 0000000..fed0242 --- /dev/null +++ b/templates/administrative/system/news/modal_edit.html.twig @@ -0,0 +1,7 @@ +{% extends 'htmx_modal.html.twig' %} + +{% block title %}News bearbeiten{% endblock %} + +{% block content %} + {% include 'administrative/system/news/form.html.twig' %} +{% endblock %} \ No newline at end of file diff --git a/templates/teamer/index.html.twig b/templates/teamer/index.html.twig index b7484eb..4289039 100644 --- a/templates/teamer/index.html.twig +++ b/templates/teamer/index.html.twig @@ -11,6 +11,14 @@ {% if not teamer.photo %} {% include '_partials/_toast.html.twig' with { level: 'info', messages: ['Bitte lade ein Foto von dir hoch'] } %} {% endif %} + {% if news is not null %} +
+ {{ icon('alert', 'w-5 h-5 flex-shrink-0') }} +
+ {{ news.message | nl2br }} +
+
+ {% endif %}

diff --git a/translations/messages.de.yaml b/translations/messages.de.yaml index 917fc10..16ea2f3 100644 --- a/translations/messages.de.yaml +++ b/translations/messages.de.yaml @@ -29,6 +29,11 @@ label: hr: Personalplanung management: Reisemanagement house_management: Hausmanagement + news: + status: + 0: deaktiviert + 1: aktiv + 2: wichtig message: confirm_contract: