Add staff notes functionality
This commit is contained in:
parent
6b61d1a182
commit
5a531ae171
@ -2,21 +2,35 @@
|
|||||||
|
|
||||||
namespace App\Controller;
|
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\User;
|
||||||
|
use App\Entity\UserCase;
|
||||||
|
use App\Form\StaffNoteFormType;
|
||||||
use App\Libs\Breadcrumb;
|
use App\Libs\Breadcrumb;
|
||||||
use App\Libs\NavList;
|
use App\Libs\NavList;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
|
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
use Symfony\Component\Security\Http\Attribute\CurrentUser;
|
use Symfony\Component\Security\Http\Attribute\CurrentUser;
|
||||||
|
|
||||||
class StaffController extends AbstractController
|
class StaffController extends AbstractController
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Variable to store unread notification messages
|
||||||
|
*
|
||||||
|
* @var array <int, Message>
|
||||||
|
*/
|
||||||
|
private array $msgs;
|
||||||
|
|
||||||
|
private int $notificationCount;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly EntityManagerInterface $entityManager,
|
private readonly EntityManagerInterface $entityManager,
|
||||||
private readonly UserPasswordHasherInterface $userPasswordHasher,
|
|
||||||
private array $navLinks = []
|
private array $navLinks = []
|
||||||
) {
|
) {
|
||||||
$this->navLinks = NavList::LIST;
|
$this->navLinks = NavList::LIST;
|
||||||
@ -26,17 +40,203 @@ class StaffController extends AbstractController
|
|||||||
#[Route('/staff-dashboard', name: 'app_staff_dashboard')]
|
#[Route('/staff-dashboard', name: 'app_staff_dashboard')]
|
||||||
public function staffDashboard(#[CurrentUser()] User $user): Response
|
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(
|
return $this->render(
|
||||||
'internal/staff/staff-dashboard.html.twig',
|
'internal/staff/staff-dashboard.html.twig',
|
||||||
array_merge(
|
array_merge(
|
||||||
$this->navLinks,
|
$this->navLinks,
|
||||||
[
|
[
|
||||||
|
'staff' => $staff,
|
||||||
'breadcrumbs' => [
|
'breadcrumbs' => [
|
||||||
new Breadcrumb('', 'Staff Dashboard')
|
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 ">
|
<main class="main-content position-relative max-height-vh-100 h-100 border-radius-lg ">
|
||||||
{{ block('topnav', 'internal/libs/top-nav.html.twig') }}
|
{{ 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>
|
</main>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
Loading…
Reference in New Issue
Block a user