<?php
namespace App\Controller\Admin;
use App\Entity\Donation;
use App\Entity\Event;
use App\Entity\FilmProject;
use App\Entity\FilmProjectUpdate;
use App\Entity\Product;
use App\Entity\ProjectNotification;
use App\Entity\Setting;
use App\Entity\User;
use App\Repository\DonationRepository;
use App\Repository\FilmProjectRepository;
use App\Repository\ProjectNotificationRepository;
use App\String\Constant;
use App\Utility\ChartBuilder;
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Assets;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Config\Dashboard;
use EasyCorp\Bundle\EasyAdminBundle\Config\MenuItem;
use EasyCorp\Bundle\EasyAdminBundle\Config\UserMenu;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractDashboardController;
use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator;
use Symfony\Component\Asset\Packages;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\UX\Chartjs\Builder\ChartBuilderInterface;
use Symfony\UX\Chartjs\Model\Chart;
use App\Controller\Admin\PendingFilmProjectMemberCrudController;
use App\Entity\EmailTemplate;
use App\Entity\FilmProjectProgressReport;
class DashboardController extends AbstractDashboardController
{
private Packages $packages;
private FilmProjectRepository $filmProjectRepository;
private DonationRepository $donationRepository;
private AdminUrlGenerator $adminUrlGenerator;
private Security $security;
private ProjectNotificationRepository $projectNotificationRepository;
public function __construct(Packages $packages, FilmProjectRepository $filmProjectRepository, DonationRepository $donationRepository, AdminUrlGenerator $adminUrlGenerator, Security $security, ProjectNotificationRepository $projectNotificationRepository)
{
$this->packages = $packages;
$this->filmProjectRepository = $filmProjectRepository;
$this->donationRepository = $donationRepository;
$this->adminUrlGenerator = $adminUrlGenerator;
$this->security = $security;
$this->projectNotificationRepository = $projectNotificationRepository;
}
#[Route('/admin', name: 'admin')]
public function index(ChartBuilderInterface $chartBuilder = null): Response
{
if (isset($_GET['return'])) {
if ($_GET['return'] == 'invitation') {
$invitationUrlController = $this->adminUrlGenerator
->setController(PendingFilmProjectMemberCrudController::class)
->setAction(Action::INDEX)
->setDashboard(DashboardController::class)
->unset('entityId')
->generateUrl();
}
return $this->redirect($invitationUrlController);
}
$user = $this->security->getUser();
if ($user->isAdmin()) { // ADMIN DASHBOARD HERE~~
$projects = $this->filmProjectRepository->findPendingApprovalProjects();
$donations = $this->donationRepository->findDonationsWithLimit(10);
$activeCampaignProjects = $this->filmProjectRepository->findAllActiveCampaignProjects($user);
$chart = null;
$totalDonator = 0;
$totalDonation = 0;
$totalFollowers = 0;
if ($activeCampaignProjects) {
$chartBuilder = new ChartBuilder($chartBuilder, $this->donationRepository);
$chart = $chartBuilder->createChartFromAllProject();
foreach ($activeCampaignProjects as $activeProject) {
$activeProjectId = $activeProject->getId();
// Get total donator number
$currentDonations = $this->donationRepository->findDonationsByFiscalYear($activeProjectId);
foreach ($currentDonations as $currentDonation) {
$orderDetails = $currentDonation->getOrderDetails();
$totalDonation += $orderDetails->getTotal() / 100;
}
$totalDonator += count($this->donationRepository->findTotalDonatorByFiscalYear($activeProjectId));
$totalFollowers += count($activeProject->getUsers());
}
}
return $this->render('adminPortal/dashboard.html.twig', [
'projects' => $projects,
'donations' => $donations,
'activeCampaignProjects' => $activeCampaignProjects,
'chart' => $chart,
'totalDonation' => '0.00',
'totalDonator' => $totalDonator,
'totalFollowers' => $totalFollowers,
]);
}
if (!$user->isFilmmaker()) {
return $this->redirectToRoute('supporter_dashboard');
}
$projects = $this->filmProjectRepository->findDraftAndActiveProjects($user);
$activeCampaignProjects = $this->filmProjectRepository->findActiveCampaignProjects($user);
$chart = null;
$totalDonator = 0;
$totalDonation = 0;
$totalFollowers = 0;
if ($activeCampaignProjects) {
$filmProject = $activeCampaignProjects[0];
$chartBuilder = new ChartBuilder($chartBuilder, $this->donationRepository);
$chart = $chartBuilder->createChartFromProject($filmProject);
$totalDonation = $filmProject->getTotalDonation() / 100;
$totalDonator = $this->getTotalDonator($filmProject);
$totalFollowers = count($filmProject->getUsers());
}
$viewProjectLink = $this->adminUrlGenerator->setController(FilmProjectCrudController::class)->setAction(Action::INDEX)->generateUrl();
return $this->render('userPortal/dashboard.html.twig', [
'projects' => $projects,
'activeCampaignProjects' => $activeCampaignProjects,
'viewProjectLink' => $viewProjectLink,
'chart' => $chart,
'totalDonation' => '0.00',
'totalDonator' => $totalDonator,
'totalFollowers' => $totalFollowers,
]);
}
#[Route('/admin/supporter', name: 'supporter_dashboard')]
public function supporterDashboard(ChartBuilderInterface $chartBuilder = null): Response
{
$user = $this->security->getUser();
if ($user->isAdmin()) {
$projects = $this->filmProjectRepository->findPendingApprovalProjects();
$donations = $this->donationRepository->findDonationsWithLimit(10);
return $this->render('adminPortal/dashboard.html.twig', [
'projects' => $projects,
'donations' => $donations,
]);
}
$projects = $this->filmProjectRepository->findDraftAndActiveProjects($user);
$viewProjectLink = $this->adminUrlGenerator->setController(FilmProjectCrudController::class)->setAction(Action::INDEX)->generateUrl();
$followedProjects = $user->getFollowedFilmProjects();
$donations = $this->donationRepository->findDonationsByUser($user);
return $this->render('userPortal/dashboard_supporter.html.twig', [
'projects' => $projects,
'viewProjectLink' => $viewProjectLink,
'followedProjects' => $followedProjects,
'donations' => $donations,
]);
}
public function configureDashboard(): Dashboard
{
$imageUrl = $this->packages->getUrl('build/images/logo.svg');
return Dashboard::new()
->setTitle('<img src="'.$imageUrl.'" alt="logo">')
->disableDarkMode()
;
}
public function configureCrud(): Crud
{
return parent::configureCrud()
->overrideTemplate('flash_messages', 'admin/crud/flash_messages_alt.html.twig')
;
}
public function configureMenuItems(): iterable
{
$user = $this->getUser();
$dashboardName = 'FILMMAKER PORTAL';
if ($user->isAdmin()) {
$dashboardName = 'ADMIN PORTAL';
}
return [
MenuItem::section($dashboardName)->setPermission(Constant::ROLE_FILMMAKER)->setCssClass('filmmaker-portal'),
MenuItem::linkToDashboard('Dashboard', 'fa fa-list')->setPermission(Constant::ROLE_FILMMAKER),
MenuItem::linkToUrl('Resources', 'fa fa-list', Constant::MY_FILMS_URL)->setLinkTarget('_blank')->setPermission(Constant::ROLE_FILMMAKER),
// MenuItem::linkToUrl('My Projects', 'fa fa-list', Constant::MY_FILMS_URL)->setLinkTarget('_blank'),
MenuItem::section('SUPPORTER')->setPermission(Constant::ROLE_DONOR),
MenuItem::linkToUrl('Dashboard', 'fa fa-list', '/admin/supporter')->setPermission(Constant::ROLE_DONOR),
MenuItem::linkToCrud('Donations', 'fa fa-list', FilmProject::class)
->setController(DonationCrudController::class)
->setPermission(Constant::ROLE_DONOR),
MenuItem::linkToCrud('Projects You\'re Following', 'fa fa-list', FilmProject::class)
->setController(FollowingProjectCrudController::class)
->setPermission(Constant::PORTAL_USER_ROLE),
MenuItem::section('USERS')->setPermission(Constant::ADMIN_ROLE),
MenuItem::linkToCrud('Manage Users', 'fa fa-list', User::class)
->setController(UserAdminCrudController::class)
->setPermission(Constant::ADMIN_ROLE),
MenuItem::section('YOUR PROFILE')->setPermission(Constant::PORTAL_USER_ROLE),
MenuItem::linkToCrud('Your Account Details', 'fa fa-list', User::class)
->setAction('edit')
->setEntityId($user->getId())
->setController(UserCrudController::class)
->setPermission(Constant::PORTAL_USER_ROLE),
MenuItem::linkToCrud('Your Billing Details', 'fa fa-list', User::class)
->setController(UserBillingCrudController::class)
->setPermission(Constant::PORTAL_USER_ROLE),
MenuItem::section('PROJECTS')->setPermission(Constant::ROLE_FILMMAKER),
MenuItem::linkToCrud('Manage Projects', 'fa fa-list', FilmProject::class)
->setController(FilmProjectCrudController::class)
->setPermission(Constant::ROLE_FILMMAKER),
// MenuItem::linkToCrud('Manage Draft Projects', 'fa fa-list', FilmProject::class)
// ->setController(DraftFilmProjectCrudController::class)
// ->setPermission(Constant::ROLE_FILMMAKER),
MenuItem::linkToCrud('Pending Approval', 'fa fa-list', FilmProject::class)
->setController(PendingFilmProjectCrudController::class)
->setPermission(Constant::ROLE_FILMMAKER),
MenuItem::linkToCrud('Linked Projects', 'fa fa-list', FilmProject::class)
->setController(LinkedFilmProjectCrudController::class)
->setPermission(Constant::ROLE_FILMMAKER),
MenuItem::linkToCrud('Manage Project Updates', 'fa fa-list', FilmProjectUpdate::class)
->setController(FilmProjectAdminUpdateCrudController::class)
->setPermission(Constant::ADMIN_ROLE),
MenuItem::linkToCrud('Manage Progress Reports', 'fa fa-list', FilmProjectProgressReport::class)
->setController(FilmProjectProgressReportCrudController::class)
->setPermission(Constant::ADMIN_ROLE),
MenuItem::section('EVENT')->setPermission(Constant::ADMIN_ROLE),
MenuItem::linkToCrud('Manage Events', 'fa fa-list', Event::class)
->setController(EventCrudController::class)
->setPermission(Constant::ADMIN_ROLE),
MenuItem::section('PRODUCTS')->setPermission(Constant::ROLE_FINANCE),
MenuItem::linkToCrud('Manage Products', 'fa fa-list', Product::class)
->setController(ProductCrudController::class)
->setPermission(Constant::ROLE_FINANCE),
MenuItem::section('TRANSACTIONS'),
MenuItem::linkToCrud('View Receipts', 'fa fa-list', Donation::class)
->setController(OrderDetailsCrudController::class),
// Need to double up "donations" menu because easyadmin can only enable one permission
// at a time (Easyadmin is shiet)
// Changed my mind: Easyadmin is great as long as you know how to make config works with role hierarchy
MenuItem::section('DONATIONS')->setPermission(Constant::ADMIN_ROLE),
MenuItem::linkToCrud('View Donations', 'fa fa-list', Donation::class)
->setController(DonationCrudController::class)
->setPermission(Constant::ADMIN_ROLE),
MenuItem::section('NOTIFICATIONS')
->setPermission(Constant::PORTAL_USER_ROLE),
MenuItem::linkToCrud('Notifications', 'fa fa-bell', ProjectNotification::class)
->setController(ProjectNotificationCrudController::class)
->setPermission(Constant::PORTAL_USER_ROLE),
MenuItem::section('SETTINGS')->setPermission(Constant::ADMIN_ROLE),
// TODO: LAUNCH
MenuItem::linkToCrud('Manage Email Template', 'fa fa-list', EmailTemplate::class)
->setController(EmailTemplateCrudController::class)
->setPermission(Constant::ADMIN_ROLE),
MenuItem::linkToCrud('Manage Global Settings', 'fa fa-list', Setting::class)
->setController(SettingCrudController::class)
->setPermission(Constant::ADMIN_ROLE),
MenuItem::linkToCrud('Manage User Category', 'fa fa-list', User::class)
->setController(UserCategoryCrudController::class)
->setPermission(Constant::ADMIN_ROLE),
];
}
public function configureAssets(): Assets
{
$user = $this->getUser();
$notifications = $this->projectNotificationRepository->findNotificationsByUserAndNotRead($user);
$assets = Assets::new()->addWebpackEncoreEntry('app');
if (count($notifications) > 0) {
$assets = Assets::new()->addWebpackEncoreEntry('app')
->addHtmlContentToHead("<style>
a.user-details::before {content: '';width: 6px;height: 6px;background-color: #e15426;display: block;margin-right: 15px;border-radius: 20px;}
a.dropdown-item.user-action.user-notification-action::after { content: ''; width: 6px; height: 6px; background-color: #e15426; display: block; margin-left: 10px; border-radius: 20px; top: 7px; position: relative; }
</style>")
;
}
return $assets;
}
public function configureUserMenu(UserInterface $user): UserMenu
{
$userProfile = $user->getUserProfile();
return parent::configureUserMenu($user)
->displayUserName(false)
->setAvatarUrl($userProfile->getProfilePictureUrl())
->addMenuItems([
MenuItem::linkToCrud('Notifications', 'fa fa-bell', ProjectNotification::class)
->setController(ProjectNotificationCrudController::class)
->setCssClass('user-notification-action'),
])
;
}
protected function getTotalDonator(FilmProject $project): ?int
{
$donationEmailArr = [];
// $donations = $project->getDonations();
$donations = $this->donationRepository->findDonationsByProjectOrderDate($project->getId());
foreach ($donations as $donation) {
$orderDetails = $donation->getOrderDetails();
$orderBillingDetails = $orderDetails->getOrderBillingDetails();
$email = $orderBillingDetails->getEmailAddress();
if (!in_array($email, $donationEmailArr)) {
array_push($donationEmailArr, $email);
}
}
$totalDonator = count($donationEmailArr);
return $totalDonator;
}
}