<?php
namespace JanusHercules\Shared\Presentation\Component\Header;
use App\Entity\User;
use App\Service\Membership\MembershipService;
use Exception;
use JanusHercules\Shared\Presentation\Entity\GroupNavigationItem;
use JanusHercules\Shared\Presentation\Entity\NavigationGroupList;
use JanusHercules\Shared\Presentation\Entity\NavigationItem;
use JanusHercules\Shared\Presentation\Service\HeaderPresentationService;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
use Symfony\UX\LiveComponent\Attribute\LiveAction;
use Symfony\UX\LiveComponent\Attribute\LiveProp;
use Symfony\UX\LiveComponent\ComponentToolsTrait;
use Symfony\UX\LiveComponent\DefaultActionTrait;
#[AsLiveComponent(
'NavSide',
'@janus_hercules.shared.presentation/header/nav_side_live_component.html.twig'
)]
class NavSideLiveComponent extends AbstractController
{
use DefaultActionTrait;
use ComponentToolsTrait;
public LoggerInterface $logger;
#[LiveProp(writable: true)]
public bool $showJoboffererHeader = false;
#[LiveProp]
public string $digitalEstateUrlContent = '';
#[LiveProp]
public bool $userCanSeeWebsiteNavigationItems = false;
#[LiveProp(writable: true)]
public string $profileLabel = '';
public string $direction = '';
public string $view = '';
public bool $inJoboffererRegisterFlow = false;
private KernelInterface $kernel;
public function __construct(
private readonly HeaderPresentationService $headerService,
private readonly RequestStack $request,
LoggerInterface $logger,
KernelInterface $kernel,
private readonly MembershipService $membershipService,
) {
$this->kernel = $kernel;
$this->logger = $logger;
}
// @phpstan-ignore-next-line
public function getSideNavbarItems(): array|NavigationGroupList
{
/** @var array|NavigationGroupList[] $rightNavbarItems */
$rightNavbarItems = [];
try {
if ($this->direction === 'right') {
if ($this->view == 'Desktop') {
/** @var ?User $user */
$user = $this->getUser();
if (!is_null($user)) {
if ($user->hasAtLeastOneAdminRole()) {
$rightNavbarItems[] = $this->getAdminDropdownContent();
}
$rightNavbarItems[] = $this->getUserDropdownItems($user, $this->getUrl($user));
return $rightNavbarItems;
} else {
return [
new NavigationItem('', 'Für Arbeitgeber', '', $this->generateUrl('digitalEstate.pro-joboo-de')),
new NavigationGroupList('Login', '', [
new GroupNavigationItem('', [
new NavigationItem('', 'Login', '', $this->generateUrl('fos_user_security_login')),
new NavigationItem('', 'Registrieren', '', $this->generateUrl('fos_user_registration_register', ['createWithRole' => User::ROLE_NAME_JOBSEEKER])),
new NavigationItem('', 'Registrieren als Arbeitgeber', '', $this->generateUrl('fos_user_registration_register', ['createWithRole' => User::ROLE_NAME_JOBOFFERER]))
])
])
];
}
}
} elseif ($this->direction == 'left') {
return $this->getLeftMenuItems();
}
} catch (Exception $e) {
$this->logger->error('Error occurred while fetching navbar Items ' . $e->getMessage());
}
return $rightNavbarItems;
}
public function getAdminDropdownContent(): NavigationGroupList
{
$adminItemsArray = $this->getItems();
return new NavigationGroupList('Admin', 'assets/icons/settings.svg', [new GroupNavigationItem('Admin', $adminItemsArray)]);
}
private function getUserDropdownItems(User $user, string $url): ?NavigationGroupList
{
try {
$inRegistrationFlow = $this
->headerService
->isInJoboffererReregistration($this->request->getCurrentRequest());
if ($user->isJobofferer() && $inRegistrationFlow) {
return new NavigationGroupList(
$this->profileLabel,
'assets/icons/user-avatar.svg',
[]
);
}
return new NavigationGroupList($this->profileLabel, 'assets/icons/user-avatar.svg', [
new GroupNavigationItem('Profil', $this->getProfilGroupItems($user)),
new GroupNavigationItem('Konto', $this->getJoboffererAccountItems($user, $url)),
new GroupNavigationItem('', [
new NavigationItem('', 'Abmelden', '', $this->generateUrl('fos_user_security_logout')),
])
]);
} catch (Exception $e) {
$this->logger->error('Error occurred while fetching right User dropdown items for desktop: ' . $e->getMessage());
return null;
}
}
/**
* @return NavigationItem[]
*
* @throws Exception
*/
private function getProfilGroupItems(User $user): array
{
$profilGroupItems = [];
try {
if ($user->getDefaultJobseekerProfile() && $user->getDefaultJobseekerProfile()->getId()) {
$profilGroupItems[] = new NavigationItem('', 'Suchaufträge', '', $this->generateUrl('account.wanted_jobs.index', ['id' => $user->getDefaultJobseekerProfile()->getId()]));
}
$profilGroupItems[] = new NavigationItem('', 'Profil bearbeiten', '', $this->generateUrl('account.profiles.index'));
$profilGroupItems[] = new NavigationItem('', 'Merkliste', '', $this->generateUrl('account.favorites.index_router'));
} catch (Exception $e) {
$this->logger->error('Error occurred while fetching the profile group items: ' . $e->getMessage());
}
return $profilGroupItems;
}
/**
* @throws Exception
*/
public function getUrl(?User $user): string
{
if (!$user) {
return '';
}
try {
$url = '';
if ($this->headerService->userCanSeeWebsiteNavigationItems($user)) {
$url = $this->generateUrl('account.subscription.jobofferer.index');
if ($user->hasJoboffererProfile() || $user->hasJobseekerProfile()) {
if ($user->getBillwerkCustomerId() && !$this->headerService->userHasActiveJoboffererMembership($user)) {
$url = $this->generateUrl('account.subscription.jobofferer.index', ['state' => 'notrial']);
}
}
}
return $url;
} catch (Exception $e) {
$this->logger->error('Error occurred while fetching the url: ' . $e->getMessage());
return '';
}
}
/**
* @return GroupNavigationItem[]
*
* @throws Exception
*/
#[LiveAction]
public function getRightNavItemsForMobile(): array
{
/** @var ?User $user */
$user = $this->getUser();
if (!$user) {
return $this->getAnonymousItems();
}
try {
$url = $this->getUrl($user);
if ($user->hasJobseekerProfile()) {
if ($user->hasAtLeastOneAdminRole()) {
return array_merge($this->getAdminItems(), $this->getJobseekerItems($user, $url));
}
return $this->getJobseekerItems($user, $url);
} elseif ($user->hasJoboffererProfile()) {
if ($user->hasAtLeastOneAdminRole()) {
return array_merge($this->getAdminItems(), $this->getJoboffererItems($user, $url));
}
return $this->getJoboffererItems($user, $url);
}
} catch (Exception $e) {
$this->logger->error('Error occurred while fetching right navigation items for mobile: ' . $e->getMessage());
return [];
}
return [];
}
/**
* @return GroupNavigationItem[]
*/
private function getJobseekerItems(
User $user,
string $url
): array {
try {
$carrierGroupItems = [];
if ($user->getDefaultJobseekerProfile() && $user->getDefaultJobseekerProfile()->getId() && $user->isJobseeker() && count($user->getDefaultJobseekerProfile()->getWantedJobs()) > 0) {
$carrierGroupItems[] = new NavigationItem('', 'Job-Radar', '', $this->generateUrl('janus_hercules.jobradar.presentation.overviewpage', ['jobseekerProfileId' => $user->getDefaultJobseekerProfile()->getId()]) . '?page=1&wantedJobId=');
}
$carrierGroupItems[] = new NavigationItem('', 'Bewerbungen', '', $this->generateUrl('account.conversations.index_router', ['page' => 1]));
if ($user->isJobseeker()) {
$carrierGroupItems[] = new NavigationItem('', 'Jobs finden', '', $this->generateUrl('recurrent_jobs_search.form'));
}
return [
new GroupNavigationItem('Karriere', $carrierGroupItems),
new GroupNavigationItem('Profil', $this->getProfilGroupItems($user)),
new GroupNavigationItem('Konto', [
new NavigationItem('', 'Passwort ändern', '', $this->generateUrl('fos_user_change_password')),
new NavigationItem('', 'Mitgliedschaft', '', $url),
]),
new GroupNavigationItem('', [
new NavigationItem('', 'Abmelden', '', $this->generateUrl('fos_user_security_logout')),
])
];
} catch (Exception $e) {
$this->logger->error('Error occurred while fetching right jobseeker items for desktop: ' . $e->getMessage());
return [];
}
}
/**
* @return GroupNavigationItem[]
*
* @throws Exception
*/
private function getJoboffererItems(
User $user,
string $url
): array {
try {
$personalSearchItems = [new NavigationItem('', 'Bewerbungen', '', $this->generateUrl('account.conversations.index_router', ['page' => 1]))];
if ($user->getDefaultJoboffererProfile() && $user->getDefaultJoboffererProfile()->getId()) {
$personalSearchItems[] = new NavigationItem('', 'Stellenanzeigen', '', $this->generateUrl('account.recurrent_jobs.index', ['id' => $user->getDefaultJoboffererProfile()->getId()]));
}
if ($user->isJobofferer()) {
$personalSearchItems[] = new NavigationItem('', 'Arbeitskräfte finden', '', $this->generateUrl('wanted_jobs_search.form'));
}
return [
new GroupNavigationItem('Personal finden', $personalSearchItems),
new GroupNavigationItem('Profil', [
new NavigationItem('', 'Profil bearbeiten', '', $this->generateUrl('account.profiles.index')),
new NavigationItem('', 'Merkliste', '', $this->generateUrl('account.favorites.index_router')),
]),
new GroupNavigationItem('Konto', $this->getJoboffererAccountItems($user, $url)),
new GroupNavigationItem('', [
new NavigationItem('', 'Abmelden', '', $this->generateUrl('fos_user_security_logout')),
])
];
} catch (Exception $e) {
$this->logger->error('Error occurred while fetching right jobseeker items for desktop: ' . $e->getMessage());
return [];
}
}
/**
* @return GroupNavigationItem[]
*
* @throws Exception
*/
private function getAnonymousItems(): array
{
try {
return [
new GroupNavigationItem('Karriere', [
new NavigationItem('', 'Jobs finden', '', $this->generateUrl('recurrent_jobs_search.form')),
new NavigationItem('', "So geht's", '', $this->generateUrl('content', ['content' => 'so-geht-es'])),
new NavigationItem('', 'Vorteile', '', $this->generateUrl('fos_user_registration_register', ['createWithRole' => User::ROLE_NAME_JOBSEEKER]))
]),
new GroupNavigationItem('Profil', [
new NavigationItem('', 'Login', '', $this->generateUrl('fos_user_security_login')),
new NavigationItem('', 'Registrieren', '', $this->generateUrl('fos_user_registration_register', ['createWithRole' => User::ROLE_NAME_JOBSEEKER])),
]),
new GroupNavigationItem('Für Arbeitgeber', [
new NavigationItem('', 'Arbeitskräfte finden', '', $this->generateUrl('wanted_jobs_search.form')),
new NavigationItem('', 'Für Arbeitgeber', '', $this->generateUrl('digitalEstate.pro-joboo-de')),
new NavigationItem('', 'Registrieren als Arbeitgeber', '', $this->generateUrl('fos_user_registration_register', ['createWithRole' => User::ROLE_NAME_JOBOFFERER]))
]),
];
} catch (Exception $e) {
$this->logger->error('Error occurred while fetching right anonymous items for desktop: ' . $e->getMessage());
return [];
}
}
/**
* @return NavigationItem[]
*
* @throws Exception
*/
public function getJoboffererAccountItems(User $user, string $url): array
{
$accountItems = [new NavigationItem('', 'Passwort ändern', '', $this->generateUrl('fos_user_change_password')),
new NavigationItem('', 'Mitgliedschaft', '', $url)];
if ($user->hasJoboffererProfile() && $this->membershipService->userHasOrHadMembership($user)) {
$accountItems[] = new NavigationItem('', 'Zahlart & Rechnungen', '', $this->generateUrl('account.subscription.manage'));
}
if ($user->hasJoboffererProfile() && $this->headerService->userCanDeleteProfile($user)) {
$accountItems[] = new NavigationItem('', 'Konto verwalten', '', $this->generateUrl('account.deletion.index'));
}
return $accountItems;
}
/**
* @return GroupNavigationItem[]
*/
public function getAdminItems(): array
{
$adminItemsArray = $this->getItems();
return [
new GroupNavigationItem('Admin', $adminItemsArray)
];
}
/**
* @return NavigationItem[]
*
* @throws Exception
*/
public function getLeftMenuItems(): array
{
try {
/** @var ?User $user */
$user = $this->getUser();
if ($user && $this->userCanSeeWebsiteNavigationItems) {
if ($user->hasJobseekerProfile()) {
return $this->getLeftJobseekerItems($user);
} elseif ($user->hasJoboffererProfile()) {
return $this->getLeftJoboffererItems($user);
}
}
} catch (Exception $e) {
$this->logger->error('Error occurred while fetching left navigation items: ' . $e->getMessage());
}
return $this->getAnonymousLeftMenu();
}
/**
* @return NavigationItem[]
*
* @throws Exception
*/
private function getLeftJobseekerItems(User $user): array
{
$jobseekerLeftItems = [];
try {
if ($user->getDefaultJobseekerProfile() && $user->isJobseeker() && count($user->getDefaultJobseekerProfile()->getWantedJobs()) > 0) {
$jobseekerLeftItems[] = new NavigationItem('RADAR', 'Job-Radar', 'assets/icons/radar.svg', $this->generateUrl('janus_hercules.jobradar.presentation.overviewpage', ['jobseekerProfileId' => $user->getDefaultJobseekerProfile()->getId()]) . '?page=1&wantedJobId=');
}
$jobseekerLeftItems[] = new NavigationItem('MESSAGE', 'Bewerbungen', 'assets/icons/mail.svg', $this->generateUrl('account.conversations.index_router', ['page' => 1]));
if ($user->isJobseeker()) {
$jobseekerLeftItems[] = new NavigationItem('', 'Jobs finden', 'assets/icons/jobs-finden.svg', $this->generateUrl('recurrent_jobs_search.form'));
}
} catch (Exception $e) {
$this->logger->error('Error occurred while fetching left jobseeker items: ' . $e->getMessage());
}
return $jobseekerLeftItems;
}
/**
* @return NavigationItem[]
*
* @throws Exception
*/
private function getLeftJoboffererItems(
User $user
): array {
$joboffererLeftItems = [];
$inRegistrationFlow = $this
->headerService
->isInJoboffererReregistration($this->request->getCurrentRequest());
if ($inRegistrationFlow) {
return $joboffererLeftItems;
}
try {
$joboffererLeftItems[] = new NavigationItem('MESSAGE', 'Bewerbungen', 'assets/icons/mail.svg', $this->generateUrl('account.conversations.index_router', ['page' => 1]));
if ($user->getDefaultJoboffererProfile() && $user->getDefaultJoboffererProfile()->getId()) {
$joboffererLeftItems[] = new NavigationItem('', 'Stellenanzeigen', 'assets/icons/user-screen.svg', $this->generateUrl('account.recurrent_jobs.index', ['id' => $user->getDefaultJoboffererProfile()->getId()]));
}
if ($user->isJobofferer()) {
$joboffererLeftItems[] = new NavigationItem('', 'Arbeitskräfte finden', 'assets/icons/user-search.svg', $this->generateUrl('wanted_jobs_search.form'));
}
} catch (Exception $e) {
$this->logger->error('Error occurred while fetching left jobofferer items: ' . $e->getMessage());
}
$hideNavigation = $user->getDefaultJoboffererProfile()?->getState() === 0;
if ($hideNavigation) {
$joboffererLeftItems = [];
}
return $joboffererLeftItems;
}
/**
* @return NavigationItem[]
*/
private function getAnonymousLeftMenu(): array
{
return [
new NavigationItem('', 'Jobs finden', '', $this->generateUrl('recurrent_jobs_search.form')),
new NavigationItem('', 'Arbeitskräfte finden', '', $this->generateUrl('wanted_jobs_search.form')),
new NavigationItem('', "So geht's", '', $this->generateUrl('content', ['content' => 'so-geht-es'])),
new NavigationItem('', 'Vorteile', '', $this->generateUrl('fos_user_registration_register', ['createWithRole' => User::ROLE_NAME_JOBSEEKER]))
];
}
/**
* @return NavigationItem[]
*/
private function getItems(): array
{
$isProd = $this->kernel->getEnvironment() === 'prod';
$billwerk = $isProd ? 'app' : 'sandbox';
$adminItemsArray = [
new NavigationItem('', 'Admin-Portale', '', $this->generateUrl('admin.portals'))
];
if ($isProd) {
$adminItemsArray[] = new NavigationItem('', 'Google Analytics', '', 'https://analytics.google.com/analytics/web/');
$adminItemsArray[] = new NavigationItem('', 'Google Search Console', '', 'https://www.google.com/webmasters/tools/dashboard?hl=de&siteUrl=https%3A%2F%2Fwww.go-gastro.com%2F');
$adminItemsArray[] = new NavigationItem('', 'Pingdom Uptime', '', 'https://my.pingdom.com/reports/uptime');
$adminItemsArray[] = new NavigationItem('', 'Pingdom Page Speed', '', 'https://my.pingdom.com/reports/rbc/4566471');
}
$adminItemsArray[] = new NavigationItem('', 'Munin', '', 'https://operations.' . $this->kernel->getEnvironment() . '.go-gastro.com/munin/localdomain/localhost.localdomain/index.html');
$adminItemsArray[] = new NavigationItem('', 'Kibana', '', 'https://operations.' . $this->kernel->getEnvironment() . '.go-gastro.com/kibana');
$adminItemsArray[] = new NavigationItem('', 'Datadog', '', 'https://app.datadoghq.com/dash/integration/1/system---overview?live=true&page=0&is_auto=false&tile_size=m&tpl_var_scope=stage%3A' . $this->kernel->getEnvironment());
$adminItemsArray[] = new NavigationItem('', 'Billwerk', '', 'https://' . $billwerk . '.billwerk.com/');
$adminItemsArray[] = new NavigationItem('', 'AWS Kosten', '', 'https://console.aws.amazon.com/cost-reports/home?#/custom?groupBy=Service&forecastTimeRangeOption=None&hasBlended=false&hasAmortized=false&excludeDiscounts=false&excludeRefund=false&excludeCredit=false&excludeRIUpfrontFees=false&excludeRIRecurringCharges=false&excludeOtherSubscriptionCosts=false&excludeSupportCharges=false&excludeTax=true&excludeTaggedResources=false&chartStyle=Stack&timeRangeOption=MonthToDate&granularity=Daily&reportName=Daily costs month-to-date w%2Fo taxes&reportType=CostUsage&isTemplate=false&filter=[]&reportId=5a7e6351-e19b-49c0-b371-78cb8702d482');
$adminItemsArray[] = new NavigationItem('', 'Login mit QR-code', '', $this->generateUrl('admin.login_qr'));
return $adminItemsArray;
}
}