Add staff notes functionality
This commit is contained in:
		| @@ -2,21 +2,35 @@ | ||||
|  | ||||
| namespace App\Controller; | ||||
|  | ||||
| use App\Entity\MemberCase; | ||||
| use App\Entity\Messages; | ||||
| use App\Entity\StaffNote; | ||||
| use App\Entity\Supervision; | ||||
| use App\Entity\User; | ||||
| use App\Entity\UserCase; | ||||
| use App\Form\StaffNoteFormType; | ||||
| use App\Libs\Breadcrumb; | ||||
| use App\Libs\NavList; | ||||
| use Doctrine\ORM\EntityManagerInterface; | ||||
| use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; | ||||
| use Symfony\Component\HttpFoundation\Request; | ||||
| use Symfony\Component\HttpFoundation\Response; | ||||
| use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface; | ||||
| use Symfony\Component\Routing\Annotation\Route; | ||||
| use Symfony\Component\Security\Http\Attribute\CurrentUser; | ||||
|  | ||||
| class StaffController extends AbstractController | ||||
| { | ||||
|     /** | ||||
|      * Variable to store unread notification messages | ||||
|      * | ||||
|      * @var array <int, Message> | ||||
|      */ | ||||
|     private array $msgs; | ||||
|  | ||||
|     private int $notificationCount; | ||||
|  | ||||
|     public function __construct( | ||||
|         private readonly EntityManagerInterface $entityManager, | ||||
|         private readonly UserPasswordHasherInterface $userPasswordHasher, | ||||
|         private array $navLinks = [] | ||||
|     ) { | ||||
|         $this->navLinks = NavList::LIST; | ||||
| @@ -26,17 +40,203 @@ class StaffController extends AbstractController | ||||
|     #[Route('/staff-dashboard', name: 'app_staff_dashboard')] | ||||
|     public function staffDashboard(#[CurrentUser()] User $user): Response | ||||
|     { | ||||
|         $this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user); | ||||
|         $this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user); | ||||
|  | ||||
|         $sups = $this->entityManager->getRepository(Supervision::class)->findBy(['supervisor' => $user]); | ||||
|         $staff = []; | ||||
|  | ||||
|         foreach ($sups as $sup) { | ||||
|             $staff[] = $sup->getWorker(); | ||||
|         } | ||||
|  | ||||
|         return $this->render( | ||||
|             'internal/staff/staff-dashboard.html.twig', | ||||
|             array_merge( | ||||
|                 $this->navLinks, | ||||
|                 [ | ||||
|                     'staff' => $staff, | ||||
|                     'breadcrumbs' => [ | ||||
|                         new Breadcrumb('', 'Staff Dashboard') | ||||
|                     ], | ||||
|                     'notifications' => $user->retrieveUnreadNotifications(), | ||||
|                     'notifications' => $this->msgs, | ||||
|                     'notificationCount' => $this->notificationCount, | ||||
|                 ] | ||||
|             ) | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     #[Route('/staff/my-cases', name:'app_staff_my_cases')] | ||||
|     public function staffMyCases(#[CurrentUser()] User $user): Response | ||||
|     { | ||||
|         $this->denyAccessUnlessGranted('IS_FULLY_AUTHENTICATED'); | ||||
|         $this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user); | ||||
|         $this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user); | ||||
|  | ||||
|         $ucs = $this->entityManager->getRepository(UserCase::class)->findBy(['user' => $user]); | ||||
|         $cases = []; | ||||
|         $this->navLinks['staff_dashboard'] = 'nav-link text-dark'; | ||||
|         $this->navLinks['staff_notes'] = NavList::PRESENT_LINK; | ||||
|  | ||||
|         foreach ($ucs as $uc) { | ||||
|             $cases[] = $uc->getMemberCase(); | ||||
|         } | ||||
|  | ||||
|         return $this->render( | ||||
|             'internal/staff/cases/my-cases.html.twig', | ||||
|             array_merge( | ||||
|                 $this->navLinks, | ||||
|                 [ | ||||
|                     'cases' => $cases, | ||||
|                     'user' => $user, | ||||
|                     'breadcrumbs' => [ | ||||
|                         new Breadcrumb($this->generateUrl('app_staff_dashboard'), 'Staff Dashboard'), | ||||
|                         new Breadcrumb('', 'Staff Cases') | ||||
|                     ], | ||||
|                     'notifications' => $this->msgs, | ||||
|                     'notificationCount' => $this->notificationCount, | ||||
|                 ] | ||||
|             ) | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     #[Route('/staff/{staffId}', name: 'app_staff_cases')] | ||||
|     public function staffCases(string $staffId, #[CurrentUser()] User $user): Response | ||||
|     { | ||||
|         $this->denyAccessUnlessGranted(['ROLE_ADMIN', 'ROLE_CASE_MANAGER']); | ||||
|         $this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user); | ||||
|         $this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user); | ||||
|  | ||||
|         $staff = $this->entityManager->getRepository(User::class)->find($staffId); | ||||
|         $ucs = $this->entityManager->getRepository(UserCase::class)->findBy(['user' => $staff]); | ||||
|         $cases = []; | ||||
|  | ||||
|         foreach ($ucs as $case) { | ||||
|             /** @var UserCase $case */ | ||||
|             $cases[] = $case->getMemberCase(); | ||||
|         } | ||||
|  | ||||
|         return $this->render( | ||||
|             'internal/staff/cases/staff-cases.html.twig', | ||||
|             array_merge( | ||||
|                 $this->navLinks, | ||||
|                 [ | ||||
|                     'staffId' => $staffId, | ||||
|                     'cases' => $cases, | ||||
|                     'breadcrumbs' => [ | ||||
|                         new Breadcrumb($this->generateUrl('app_staff_dashboard'), 'Staff Dashboard'), | ||||
|                         new Breadcrumb('', 'Staff Cases') | ||||
|                     ], | ||||
|                     'notifications' => $this->msgs, | ||||
|                     'notificationCount' => $this->notificationCount, | ||||
|                 ] | ||||
|             ) | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     #[Route('/staff/{staffId}/case/{caseId}/list-notes', name: 'app_staff_list_notes')] | ||||
|     public function staffListNotes(string $staffId, string $caseId, #[CurrentUser()] User $user): Response | ||||
|     { | ||||
|         $this->denyAccessUnlessGranted('IS_FULLY_AUTHENTICATED'); | ||||
|         $this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user); | ||||
|         $this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user); | ||||
|  | ||||
|         $staff = $this->entityManager->getRepository(User::class)->find($staffId); | ||||
|         $case = $this->entityManager->getRepository(MemberCase::class)->find($caseId); | ||||
|         $staffNotes = $this->entityManager->getRepository(StaffNote::class)->findBy(['memberCase' => $case]); | ||||
|  | ||||
|         return $this->render( | ||||
|             'internal/staff/notes/list-notes.html.twig', | ||||
|             array_merge( | ||||
|                 $this->navLinks, | ||||
|                 [ | ||||
|                     'staffId' => $staffId, | ||||
|                     'staff' => $staff, | ||||
|                     'case' => $case, | ||||
|                     'staffNotes' => $staffNotes, | ||||
|                     'breadcrumbs' => [ | ||||
|                         new Breadcrumb($this->generateUrl('app_staff_dashboard'), 'Staff Dashboard'), | ||||
|                         new Breadcrumb( | ||||
|                             $this->generateUrl( | ||||
|                                 ($staffId == $user->getId()->toHex() ? 'app_staff_my_cases' : 'app_staff_cases'), | ||||
|                                 ['staffId' => $staffId] | ||||
|                             ), | ||||
|                             ($staffId == $user->getId()->toHex() ? 'My Cases' : 'Staff Cases') | ||||
|                         ), | ||||
|                         new Breadcrumb('', 'List Notes') | ||||
|                     ], | ||||
|                     'notifications' => $this->msgs, | ||||
|                     'notificationCount' => $this->notificationCount, | ||||
|                 ] | ||||
|             ) | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     #[Route('/staff/add-note/{caseId}', name: 'app_staff_add_note')] | ||||
|     public function addNote(string $caseId, #[CurrentUser()] User $user, Request $request): Response | ||||
|     { | ||||
|         $this->denyAccessUnlessGranted('IS_FULLY_AUTHENTICATED'); | ||||
|         $this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user); | ||||
|         $this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user); | ||||
|  | ||||
|         $case = $this->entityManager->getRepository(MemberCase::class)->find($caseId); | ||||
|         $form = $this->createForm(StaffNoteFormType::class); | ||||
|         $this->navLinks['staff_dashboard'] = 'nav-link text-dark'; | ||||
|         $this->navLinks['staff_notes'] = NavList::PRESENT_LINK; | ||||
|  | ||||
|         $form->handleRequest($request); | ||||
|  | ||||
|         if ($form->isSubmitted() && $form->isValid()) { | ||||
|             $note = $form->getData(); | ||||
|             $note->setMemberCase($case); | ||||
|  | ||||
|             $this->entityManager->persist($note); | ||||
|             $this->entityManager->flush(); | ||||
|  | ||||
|             return $this->redirectToRoute('app_staff_list_notes', ['staffId' => $user->getId()->toHex(), 'caseId' => $caseId]); | ||||
|         } | ||||
|  | ||||
|         return $this->render( | ||||
|             'internal/staff/notes/add-note.html.twig', | ||||
|             array_merge( | ||||
|                 $this->navLinks, | ||||
|                 [ | ||||
|                     'case' => $case, | ||||
|                     'form' => $form, | ||||
|                     'breadcrumbs' => [ | ||||
|                         new Breadcrumb($this->generateUrl('app_staff_dashboard'), 'Staff Dashboard'), | ||||
|                         new Breadcrumb($this->generateUrl('app_staff_list_notes', ['staffId' => $user->getId()->toHex(), 'caseId' => $caseId]), 'My Cases'), | ||||
|                         new Breadcrumb('', 'Add Note'), | ||||
|                     ], | ||||
|                     'notifications' => $this->msgs, | ||||
|                     'notificationCount' => $this->notificationCount, | ||||
|                 ] | ||||
|             ) | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     #[Route('/staff/edit-note/{noteId}', name: 'app_staff_edit_note')] | ||||
|     public function editNote(string $noteId, #[CurrentUser()] User $user, Request $request): Response | ||||
|     { | ||||
|         $this->denyAccessUnlessGranted('IS_FULLY_AUTHENTICATED'); | ||||
|         $this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user); | ||||
|         $this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user); | ||||
|  | ||||
|         $note = $this->entityManager->getRepository(StaffNote::class)->find($noteId); | ||||
|         $case = $note->getMemberCase(); | ||||
|  | ||||
|         $form = $this->createForm(StaffNoteFormType::class, $note); | ||||
|  | ||||
|         $form->handleRequest($request); | ||||
|  | ||||
|         if ($form->isSubmitted() && $form->isValid()) { | ||||
|             $this->entityManager->flush(); | ||||
|  | ||||
|             $this->addFlash('info', 'Staff notes updated'); | ||||
|  | ||||
|             $this->redirectToRoute('app_staff_list_note', ['staffId' => $user->getId()->toHex(), 'caseId' => $case->getId()->toHex()]); | ||||
|         } | ||||
|  | ||||
|         return new Response(); | ||||
|     } | ||||
| } | ||||
|   | ||||
							
								
								
									
										101
									
								
								src/Entity/StaffNote.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								src/Entity/StaffNote.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | ||||
| <?php | ||||
|  | ||||
| namespace App\Entity; | ||||
|  | ||||
| use App\Enums\ReferralServiceType; | ||||
| use App\Repository\StaffNoteRepository; | ||||
| use Doctrine\DBAL\Types\Types; | ||||
| use Doctrine\ORM\Mapping as ORM; | ||||
|  | ||||
| #[ORM\Entity(repositoryClass: StaffNoteRepository::class)] | ||||
| class StaffNote | ||||
| { | ||||
|     #[ORM\Id] | ||||
|     #[ORM\GeneratedValue] | ||||
|     #[ORM\Column] | ||||
|     private ?int $id = null; | ||||
|  | ||||
|     #[ORM\Column(type: Types::DATE_MUTABLE)] | ||||
|     private ?\DateTimeInterface $date = null; | ||||
|  | ||||
|     #[ORM\ManyToOne(inversedBy: 'staffNotes')] | ||||
|     #[ORM\JoinColumn(nullable: false)] | ||||
|     private ?MemberCase $memberCase = null; | ||||
|  | ||||
|     #[ORM\Column(type: Types::SIMPLE_ARRAY, enumType: ReferralServiceType::class)] | ||||
|     private array $servicesProvided = []; | ||||
|  | ||||
|     #[ORM\Column(type: Types::TEXT)] | ||||
|     private ?string $note = null; | ||||
|  | ||||
|     #[ORM\Column(length: 500, nullable: true)] | ||||
|     private ?string $recommendations = null; | ||||
|  | ||||
|     public function getId(): ?int | ||||
|     { | ||||
|         return $this->id; | ||||
|     } | ||||
|  | ||||
|     public function getDate(): ?\DateTimeInterface | ||||
|     { | ||||
|         return $this->date; | ||||
|     } | ||||
|  | ||||
|     public function setDate(\DateTimeInterface $date): static | ||||
|     { | ||||
|         $this->date = $date; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function getMemberCase(): ?MemberCase | ||||
|     { | ||||
|         return $this->memberCase; | ||||
|     } | ||||
|  | ||||
|     public function setMemberCase(?MemberCase $memberCase): static | ||||
|     { | ||||
|         $this->memberCase = $memberCase; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return ReferralServiceType[] | ||||
|      */ | ||||
|     public function getServicesProvided(): array | ||||
|     { | ||||
|         return $this->servicesProvided; | ||||
|     } | ||||
|  | ||||
|     public function setServicesProvided(array $servicesProvided): static | ||||
|     { | ||||
|         $this->servicesProvided = $servicesProvided; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function getNote(): ?string | ||||
|     { | ||||
|         return $this->note; | ||||
|     } | ||||
|  | ||||
|     public function setNote(string $note): static | ||||
|     { | ||||
|         $this->note = $note; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function getRecommendations(): ?string | ||||
|     { | ||||
|         return $this->recommendations; | ||||
|     } | ||||
|  | ||||
|     public function setRecommendations(string $recommendations): static | ||||
|     { | ||||
|         $this->recommendations = $recommendations; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										38
									
								
								src/Form/StaffNoteFormType.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/Form/StaffNoteFormType.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| <?php | ||||
|  | ||||
| namespace App\Form; | ||||
|  | ||||
| use App\Entity\Member; | ||||
| use App\Entity\StaffNote; | ||||
| use App\Enums\ReferralServiceType; | ||||
| use Symfony\Component\Form\AbstractType; | ||||
| use Symfony\Component\Form\Extension\Core\Type\EnumType; | ||||
| use Symfony\Component\Form\Extension\Core\Type\TextareaType; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use Symfony\Component\OptionsResolver\OptionsResolver; | ||||
|  | ||||
| class StaffNoteFormType extends AbstractType | ||||
| { | ||||
|     public function buildForm(FormBuilderInterface $builder, array $options): void | ||||
|     { | ||||
|         $builder | ||||
|             ->add('date', null, [ | ||||
|                 'widget' => 'single_text', | ||||
|             ]) | ||||
|             ->add('servicesProvided', EnumType::class, [ | ||||
|                 'class' => ReferralServiceType::class, | ||||
|                 'expanded' => true, | ||||
|                 'multiple' => true, | ||||
|             ]) | ||||
|             ->add('note', TextareaType::class) | ||||
|             ->add('recommendations') | ||||
|         ; | ||||
|     } | ||||
|  | ||||
|     public function configureOptions(OptionsResolver $resolver): void | ||||
|     { | ||||
|         $resolver->setDefaults([ | ||||
|             'data_class' => StaffNote::class, | ||||
|         ]); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										43
									
								
								src/Repository/StaffNoteRepository.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/Repository/StaffNoteRepository.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| <?php | ||||
|  | ||||
| namespace App\Repository; | ||||
|  | ||||
| use App\Entity\StaffNote; | ||||
| use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; | ||||
| use Doctrine\Persistence\ManagerRegistry; | ||||
|  | ||||
| /** | ||||
|  * @extends ServiceEntityRepository<StaffNote> | ||||
|  */ | ||||
| class StaffNoteRepository extends ServiceEntityRepository | ||||
| { | ||||
|     public function __construct(ManagerRegistry $registry) | ||||
|     { | ||||
|         parent::__construct($registry, StaffNote::class); | ||||
|     } | ||||
|  | ||||
|     //    /** | ||||
|     //     * @return StaffNote[] Returns an array of StaffNote objects | ||||
|     //     */ | ||||
|     //    public function findByExampleField($value): array | ||||
|     //    { | ||||
|     //        return $this->createQueryBuilder('s') | ||||
|     //            ->andWhere('s.exampleField = :val') | ||||
|     //            ->setParameter('val', $value) | ||||
|     //            ->orderBy('s.id', 'ASC') | ||||
|     //            ->setMaxResults(10) | ||||
|     //            ->getQuery() | ||||
|     //            ->getResult() | ||||
|     //        ; | ||||
|     //    } | ||||
|  | ||||
|     //    public function findOneBySomeField($value): ?StaffNote | ||||
|     //    { | ||||
|     //        return $this->createQueryBuilder('s') | ||||
|     //            ->andWhere('s.exampleField = :val') | ||||
|     //            ->setParameter('val', $value) | ||||
|     //            ->getQuery() | ||||
|     //            ->getOneOrNullResult() | ||||
|     //        ; | ||||
|     //    } | ||||
| } | ||||
							
								
								
									
										44
									
								
								templates/internal/staff/cases/my-cases.html.twig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								templates/internal/staff/cases/my-cases.html.twig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| {% extends 'base.html.twig' %} | ||||
|  | ||||
| {% block body %} | ||||
| 	{{ block('nav', 'internal/libs/nav.html.twig') }} | ||||
|  | ||||
| 	<main class="main-content position-relative max-height-vh-100 h-100 border-radius-lg "> | ||||
| 		{{ block('topnav', 'internal/libs/top-nav.html.twig') }} | ||||
| 		<div class='container-fluid py-2'> | ||||
| 			<div class='row'> | ||||
| 				<div class='ms-3'> | ||||
| 					<h3 class='mb-0 h4 font-weight-bolder'>My Cases</h3> | ||||
| 					<p class='mb-4'></p> | ||||
| 				</div> | ||||
| 				{% for c in cases %} | ||||
| 					<div class='col-xl-3 col-sm-6 mb-xl-0 mb-4'> | ||||
| 						<div class='card'> | ||||
| 							<div class='card-header p-2 ps-3'> | ||||
| 								<div class='d-flex justify-content-between'> | ||||
| 									<div> | ||||
| 										<h4 class='mb-0'>{{ c.caseName }}</h4> | ||||
| 										<p class='text-sm mb-0 text-capitalize'> | ||||
| 											<a href='tel:'></a> | ||||
| 										</p> | ||||
| 									</div> | ||||
| 									<div class="icon icon-md icon-shape bg-gradient-dark shadow-dark shadow text-center border-radius-lg"> | ||||
| 										<i class="material-symbols-rounded opacity-10">weekend</i> | ||||
| 									</div> | ||||
| 								</div> | ||||
| 							</div> | ||||
| 							<hr class='dark horizontal my-0'> | ||||
| 							<div class='card-footer p-2 ps-3'> | ||||
| 								<p class='mb-0 text-sm'> | ||||
| 									<span class='text-info font-weight-bolder'> | ||||
| 										<a href='{{ path('app_staff_list_notes', {staffId: user.id, caseId: c.id}) }}'>Staff Notes</a> | ||||
| 									</span> | ||||
| 								</p> | ||||
| 							</div> | ||||
| 						</div> | ||||
| 					</div> | ||||
| 				{% endfor %} | ||||
| 			</div> | ||||
| 		</div> | ||||
| 	</main> | ||||
| {% endblock %} | ||||
							
								
								
									
										44
									
								
								templates/internal/staff/cases/staff-cases.html.twig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								templates/internal/staff/cases/staff-cases.html.twig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| {% extends 'base.html.twig' %} | ||||
|  | ||||
| {% block body %} | ||||
| 	{{ block('nav', 'internal/libs/nav.html.twig') }} | ||||
|  | ||||
| 	<main class="main-content position-relative max-height-vh-100 h-100 border-radius-lg "> | ||||
| 		{{ block('topnav', 'internal/libs/top-nav.html.twig') }} | ||||
| 		<div class='container-fluid py-2'> | ||||
| 			<div class='row'> | ||||
| 				<div class='ms-3'> | ||||
| 					<h3 class='mb-0 h4 font-weight-bolder'>Staff Cases</h3> | ||||
| 					<p class='mb-4'></p> | ||||
| 				</div> | ||||
| 				{% for c in cases %} | ||||
| 					<div class='col-xl-3 col-sm-6 mb-xl-0 mb-4'> | ||||
| 						<div class='card'> | ||||
| 							<div class='card-header p-2 ps-3'> | ||||
| 								<div class='d-flex justify-content-between'> | ||||
| 									<div> | ||||
| 										<h4 class='mb-0'>{{ c.caseName }}</h4> | ||||
| 										<p class='text-sm mb-0 text-capitalize'> | ||||
| 											<a href='tel:'></a> | ||||
| 										</p> | ||||
| 									</div> | ||||
| 									<div class="icon icon-md icon-shape bg-gradient-dark shadow-dark shadow text-center border-radius-lg"> | ||||
| 										<i class="material-symbols-rounded opacity-10">weekend</i> | ||||
| 									</div> | ||||
| 								</div> | ||||
| 							</div> | ||||
| 							<hr class='dark horizontal my-0'> | ||||
| 							<div class='card-footer p-2 ps-3'> | ||||
| 								<p class='mb-0 text-sm'> | ||||
| 									<span class='text-info font-weight-bolder'> | ||||
| 										<a href='{{ path('app_staff_list_notes', {staffId: staffId, caseId: c.id}) }}'>Staff Notes</a> | ||||
| 									</span> | ||||
| 								</p> | ||||
| 							</div> | ||||
| 						</div> | ||||
| 					</div> | ||||
| 				{% endfor %} | ||||
| 			</div> | ||||
| 		</div> | ||||
| 	</main> | ||||
| {% endblock %} | ||||
							
								
								
									
										56
									
								
								templates/internal/staff/notes/add-note.html.twig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								templates/internal/staff/notes/add-note.html.twig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| {% extends 'base.html.twig' %} | ||||
|  | ||||
| {% block body %} | ||||
| 	{{ block('nav', 'internal/libs/nav.html.twig') }} | ||||
|  | ||||
| 	<main class="main-content position-relative max-height-vh-100 h-100 border-radius-lg "> | ||||
| 		{{ block('topnav', 'internal/libs/top-nav.html.twig') }} | ||||
|  | ||||
| 		<section> | ||||
|  | ||||
| 			<div class="card card-plain"> | ||||
| 				<div class="card-header"> | ||||
| 					<h4 class="font-weight-bolder">Case Info</h4> | ||||
| 					<p class="mb-0"></p> | ||||
| 				</div> | ||||
| 				<div class="card-body"> | ||||
| 					<div class="container"> | ||||
| 						{{ form_errors(form) }} | ||||
|  | ||||
| 						{{ form_start(form) }} | ||||
| 						<div class="row"> | ||||
| 							<div class='col'> | ||||
|                                 <div class='input-group input-group-outline mb-3'> | ||||
|                                     <label for='note_form_date'></label> | ||||
|                                     <input type='date' name='{{ field_name(form.date) }}' id='note_form_date' class='form-control'/> | ||||
|                                 </div> | ||||
|  | ||||
|                                 <div class='input-group input-group-outline mb-3'> | ||||
|                                     {{ form_row(form.servicesProvided) }} | ||||
|                                 </div> | ||||
|  | ||||
|                                 <div class='input-group input-group-outline mb-3'> | ||||
|                                     <label for='note_form_recommendation' class='form-label'>Recommendation</label> | ||||
|                                     <input type='text' name='{{ field_name(form.recommendations) }}' id='note_form_recommendation' class='form-control'/> | ||||
|                                 </div> | ||||
|                             </div> | ||||
|  | ||||
|                             <div class='col'> | ||||
|                                 <div class='input-group input-group-outline mb-3'> | ||||
|                                     <textarea name='{{ field_name(form.note) }}' id='note_form_note' class='form-control' placeholder='Note' style='width:100%;height:200px;'></textarea> | ||||
|                                 </div> | ||||
|                             </div> | ||||
|                         </div> | ||||
|  | ||||
| 						<div class='row'> | ||||
| 							<div class="text-center"> | ||||
| 								<button type="submit" class="btn btn-lg bg-gradient-dark btn-lg w-100 mt-4 mb-0">Save Staff Note</button> | ||||
| 							</div> | ||||
| 						</div> | ||||
|                         {{ form_end(form) }} | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </section> | ||||
|     </main> | ||||
| {% endblock %} | ||||
							
								
								
									
										60
									
								
								templates/internal/staff/notes/list-notes.html.twig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								templates/internal/staff/notes/list-notes.html.twig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | ||||
| {% extends 'base.html.twig' %} | ||||
|  | ||||
| {% block body %} | ||||
| 	{{ block('nav', 'internal/libs/nav.html.twig') }} | ||||
|  | ||||
| 	<main class="main-content position-relative max-height-vh-100 h-100 border-radius-lg "> | ||||
| 		{{ block('topnav', 'internal/libs/top-nav.html.twig') }} | ||||
|  | ||||
| 		<div class="container-fluid py-2"> | ||||
| 			<div class="row"> | ||||
| 				<div class="col-12"> | ||||
| 					<div class="card my-4"> | ||||
| 						<div class="card-header p-0 position-relative mt-n4 mx-3 z-index-2"> | ||||
| 							<div class="d-flex justify-content-between bg-gradient-dark shadow-dark border-radius-lg pt-4 pb-3 ps-3 p-2"> | ||||
| 								<div> | ||||
| 									<h6 class="text-white text-capitalize ps-3">{{ case.caseName }}</h6> | ||||
| 								</div> | ||||
| 								{% if app.user.id == staffId %} | ||||
| 								<div> | ||||
| 									<button type="button" class="btn btn-block btn-light mb-3" onclick="window.open('{{ path('app_staff_add_note', {caseId: case.id}) }}', '_self')">Add Staff Note</button> | ||||
| 								</div> | ||||
| 								{% endif %} | ||||
| 							</div> | ||||
| 						</div> | ||||
| 						<div class="card-body px-0 pb-2"> | ||||
| 							<div class="table-responsive p-0"> | ||||
| 								<table class="table align-items-center mb-0"> | ||||
| 									<thead> | ||||
| 										<tr> | ||||
| 											<th class="text-uppercase text-secondary text-xxs font-weight-bolder opacity-7">Date</th> | ||||
| 											<th class="text-secondary opacity-7"></th> | ||||
| 										</tr> | ||||
| 									</thead> | ||||
| 									<tbody id='case-list'> | ||||
| 										{% for n in staffNotes %} | ||||
| 											<tr> | ||||
| 												<td> | ||||
| 													<div class='d-flex px-2 py-1'> | ||||
| 														<div class='d-flex flex-column justify-content-center'> | ||||
| 															<h6 class='mb-0 text-small'>{{ n.date|date('F j, Y') }}</h6> | ||||
| 														</div> | ||||
| 													</div> | ||||
| 												</td> | ||||
| 												<td class='align-right'> | ||||
| 													<a href='{{ path('app_staff_edit_note', {noteId: n.id}) }}' title='Edit Note'> | ||||
| 														<i class='material-symbols-rounded opacity-5'>edit</i> | ||||
| 													</a> | ||||
| 												</td> | ||||
| 											</tr> | ||||
| 										{% endfor %} | ||||
| 									</tbody> | ||||
| 								</table> | ||||
| 							</div> | ||||
| 						</div> | ||||
| 					</div> | ||||
| 				</div> | ||||
| 			</div> | ||||
| 		</div> | ||||
| 	</main> | ||||
| {% endblock %} | ||||
| @@ -5,5 +5,40 @@ | ||||
|  | ||||
| 	<main class="main-content position-relative max-height-vh-100 h-100 border-radius-lg "> | ||||
| 		{{ block('topnav', 'internal/libs/top-nav.html.twig') }} | ||||
| 		<div class='container-fluid py-2'> | ||||
| 			<div class='row'> | ||||
| 				<div class='ms-3'> | ||||
| 					<h3 class='mb-0 h4 font-weight-bolder'>Staff Dashboard</h3> | ||||
| 					<p class='mb-4'></p> | ||||
| 				</div> | ||||
| 				{% for s in staff %} | ||||
| 					<div class='col-xl-3 col-sm-6 mb-xl-0 mb-4'> | ||||
| 						<div class='card'> | ||||
| 							<div class='card-header p-2 ps-3'> | ||||
| 								<div class='d-flex justify-content-between'> | ||||
| 									<div> | ||||
| 										<h4 class='mb-0'>{{ s.name }}</h4> | ||||
| 										<p class='text-sm mb-0 text-capitalize'> | ||||
| 											<a href='tel:'></a> | ||||
| 										</p> | ||||
| 									</div> | ||||
| 									<div class="icon icon-md icon-shape bg-gradient-dark shadow-dark shadow text-center border-radius-lg"> | ||||
| 										<i class="material-symbols-rounded opacity-10">weekend</i> | ||||
| 									</div> | ||||
| 								</div> | ||||
| 							</div> | ||||
| 							<hr class='dark horizontal my-0'> | ||||
| 							<div class='card-footer p-2 ps-3'> | ||||
| 								<p class='mb-0 text-sm'> | ||||
| 									<span class='text-info font-weight-bolder'> | ||||
| 										<a href='{{ path('app_staff_cases', {staffId: s.id}) }}'>Staff Cases</a> | ||||
| 									</span> | ||||
| 								</p> | ||||
| 							</div> | ||||
| 						</div> | ||||
| 					</div> | ||||
| 				{% endfor %} | ||||
| 			</div> | ||||
| 		</div> | ||||
| 	</main> | ||||
| {% endblock %} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user