Add community resource content and associated pages, links, forms, etc
This commit is contained in:
		
							
								
								
									
										138
									
								
								src/Controller/CommunityResourceController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								src/Controller/CommunityResourceController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,138 @@ | ||||
| <?php | ||||
|  | ||||
| namespace App\Controller; | ||||
|  | ||||
| use App\Entity\CommunityResource; | ||||
| use App\Entity\User; | ||||
| use App\Form\ResourceFormType; | ||||
| 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\Routing\Attribute\Route; | ||||
| use Symfony\Component\Security\Http\Attribute\CurrentUser; | ||||
| use Symfony\Component\Validator\Constraints\Regex; | ||||
|  | ||||
| class CommunityResourceController extends AbstractController | ||||
| { | ||||
|     public function __construct( | ||||
|         private readonly EntityManagerInterface $entityManager, | ||||
|         private array $navLinks = [] | ||||
|     ) { | ||||
|         $this->navLinks = NavList::LIST; | ||||
|         $this->navLinks['community_resources'] = NavList::PRESENT_LINK; | ||||
|     } | ||||
|  | ||||
|     #[Route('/resource/list', name: 'app_community_resource')] | ||||
|     public function list(#[CurrentUser()] User $user): Response | ||||
|     { | ||||
|         $rsc = $this->entityManager->getRepository(CommunityResource::class)->findAll(); | ||||
|  | ||||
|         return $this->render( | ||||
|             'internal/community_resource/list.html.twig', | ||||
|             array_merge( | ||||
|                 $this->navLinks, | ||||
|                 [ | ||||
|                     'breadcrumbs' => [ | ||||
|                         new Breadcrumb('#', 'Community Resources') | ||||
|                     ], | ||||
|                     'resources' => $rsc, | ||||
|                     'notifications' => $user->retrieveUnreadNotifications(), | ||||
|                 ] | ||||
|             ) | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     #[Route('/resource/map', name: 'app_community_resource_map')] | ||||
|     public function map(): Response | ||||
|     { | ||||
|         return $this->render('internal/community_resource/map.html.twig', [ | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     #[Route('/resource/add', name: 'app_community_resource_add')] | ||||
|     public function add(#[CurrentUser()] User $user, Request $request): Response | ||||
|     { | ||||
|         $form = $this->createForm(ResourceFormType::class); | ||||
|         $form->handleRequest($request); | ||||
|  | ||||
|         if ($form->isSubmitted() && $form->isValid()) { | ||||
|             $rsc = $form->getData(); | ||||
|             $this->entityManager->persist($rsc); | ||||
|             $this->entityManager->flush(); | ||||
|  | ||||
|             return $this->redirectToRoute('app_community_resource'); | ||||
|         } | ||||
|  | ||||
|         return $this->render( | ||||
|             'internal/community_resource/add.html.twig', | ||||
|             array_merge( | ||||
|                 $this->navLinks, | ||||
|                 [ | ||||
|                     'form' => $form, | ||||
|                     'breadcrumbs' => [ | ||||
|                         new Breadcrumb($this->generateUrl('app_community_resource'), 'List Resources'), | ||||
|                         new Breadcrumb('#', 'Add Resource') | ||||
|                     ], | ||||
|                     'notifications' => $user->retrieveUnreadNotifications(), | ||||
|                 ] | ||||
|             ) | ||||
|         ); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     #[Route('/resource/edit/{id}', name: 'app_community_resource_edit')] | ||||
|     public function edit(string $id, #[CurrentUser()] User $user, Request $request): Response | ||||
|     { | ||||
|         $rsc = $this->entityManager->getRepository(CommunityResource::class)->find($id); | ||||
|         $form = $this->createForm(ResourceFormType::class, $rsc); | ||||
|  | ||||
|         $form->handleRequest($request); | ||||
|  | ||||
|         if ($form->isSubmitted() && $form->isValid()) { | ||||
|             $this->entityManager->flush(); | ||||
|  | ||||
|             return $this->redirectToRoute('app_community_resource'); | ||||
|         } | ||||
|  | ||||
|         return $this->render( | ||||
|             'internal/community_resource/edit.html.twig', | ||||
|             array_merge( | ||||
|                 $this->navLinks, | ||||
|                 [ | ||||
|                     'form' => $form, | ||||
|                     'breadcrumbs' => [ | ||||
|                         new Breadcrumb($this->generateUrl('app_community_resource'), 'List Resources'), | ||||
|                         new Breadcrumb('#', 'Edit Resource') | ||||
|                     ], | ||||
|                     'notifications' => $user->retrieveUnreadNotifications(), | ||||
|                 ] | ||||
|             ) | ||||
|         ); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     #[Route('/resource/download/{id}', name: 'app_community_resource_download')] | ||||
|     public function download(string $id): Response | ||||
|     { | ||||
|         /** @var CommunityResource $rsc */ | ||||
|         $rsc = $this->entityManager->getRepository(CommunityResource::class)->find($id); | ||||
|  | ||||
|         if (!$rsc) { | ||||
|             $this->addFlash('error', 'Resource not found.'); | ||||
|             return $this->redirectToRoute('app_community_resource'); | ||||
|         } | ||||
|  | ||||
|         return new Response($rsc->generateVCard(), 200, [ | ||||
|             'Content-Type' => 'text/vcf', | ||||
|             'Content-Disposition' => 'attachment; filename="' . str_replace(' ', '', $rsc->getName()) . '.vcf"', | ||||
|             'Content-Length' => strlen($rsc->generateVCard()), | ||||
|             'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0', | ||||
|             'Expires' => '0', | ||||
|             'Pragma' => 'public', | ||||
|             'Content-Transfer-Encoding' => 'binary' | ||||
|         ]); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										626
									
								
								src/Entity/CommunityResource.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										626
									
								
								src/Entity/CommunityResource.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,626 @@ | ||||
| <?php | ||||
|  | ||||
| namespace App\Entity; | ||||
|  | ||||
| use App\Enums\County; | ||||
| use App\Enums\State; | ||||
| use App\Repository\CommunityResourceRepository; | ||||
| use DateTime; | ||||
| use DateTimeZone; | ||||
| use Doctrine\DBAL\Types\Types; | ||||
| use Doctrine\ORM\Mapping as ORM; | ||||
| use Symfony\Bridge\Doctrine\Types\UuidType; | ||||
| use Symfony\Component\Uid\Uuid; | ||||
|  | ||||
| #[ORM\Entity(repositoryClass: CommunityResourceRepository::class)] | ||||
| class CommunityResource | ||||
| { | ||||
|     #[ORM\Id] | ||||
|     #[ORM\Column(type: UuidType::NAME, unique: true)] | ||||
|     #[ORM\GeneratedValue(strategy: 'CUSTOM')] | ||||
|     #[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')] | ||||
|     private ?Uuid $id = null; | ||||
|  | ||||
|     #[ORM\Column(length: 255)] | ||||
|     private ?string $name = null; | ||||
|  | ||||
|     #[ORM\Column(length: 255)] | ||||
|     private ?string $address = null; | ||||
|  | ||||
|     #[ORM\Column(length: 255, nullable: true)] | ||||
|     private ?string $address2 = null; | ||||
|  | ||||
|     #[ORM\Column(length: 255)] | ||||
|     private ?string $city = null; | ||||
|  | ||||
|     #[ORM\Column(enumType: State::class)] | ||||
|     private ?State $state = null; | ||||
|  | ||||
|     #[ORM\Column] | ||||
|     private ?int $zip = null; | ||||
|  | ||||
|     #[ORM\Column(enumType: County::class)] | ||||
|     private ?County $county = null; | ||||
|  | ||||
|     #[ORM\Column(length: 15, nullable: true)] | ||||
|     private ?string $phone = null; | ||||
|  | ||||
|     #[ORM\Column(length: 64, nullable: true)] | ||||
|     private ?string $email = null; | ||||
|  | ||||
|     #[ORM\Column(length: 255, nullable: true)] | ||||
|     private ?string $url = null; | ||||
|  | ||||
|     #[ORM\Column(type: Types::TIME_MUTABLE, nullable: true)] | ||||
|     private ?\DateTimeInterface $monOpen = null; | ||||
|  | ||||
|     #[ORM\Column(type: Types::TIME_MUTABLE, nullable: true)] | ||||
|     private ?\DateTimeInterface $monClose = null; | ||||
|  | ||||
|     #[ORM\Column(type: Types::TIME_MUTABLE, nullable: true)] | ||||
|     private ?\DateTimeInterface $tueOpen = null; | ||||
|  | ||||
|     #[ORM\Column(type: Types::TIME_MUTABLE, nullable: true)] | ||||
|     private ?\DateTimeInterface $tueClose = null; | ||||
|  | ||||
|     #[ORM\Column(type: Types::TIME_MUTABLE, nullable: true)] | ||||
|     private ?\DateTimeInterface $wedOpen = null; | ||||
|  | ||||
|     #[ORM\Column(type: Types::TIME_MUTABLE, nullable: true)] | ||||
|     private ?\DateTimeInterface $wedClose = null; | ||||
|  | ||||
|     #[ORM\Column(type: Types::TIME_MUTABLE, nullable: true)] | ||||
|     private ?\DateTimeInterface $thuOpen = null; | ||||
|  | ||||
|     #[ORM\Column(type: Types::TIME_MUTABLE, nullable: true)] | ||||
|     private ?\DateTimeInterface $thuClose = null; | ||||
|  | ||||
|     #[ORM\Column(type: Types::TIME_MUTABLE, nullable: true)] | ||||
|     private ?\DateTimeInterface $friOpen = null; | ||||
|  | ||||
|     #[ORM\Column(type: Types::TIME_MUTABLE, nullable: true)] | ||||
|     private ?\DateTimeInterface $friClose = null; | ||||
|  | ||||
|     #[ORM\Column(type: Types::TIME_MUTABLE, nullable: true)] | ||||
|     private ?\DateTimeInterface $satOpen = null; | ||||
|  | ||||
|     #[ORM\Column(type: Types::TIME_MUTABLE, nullable: true)] | ||||
|     private ?\DateTimeInterface $satClose = null; | ||||
|  | ||||
|     #[ORM\Column(type: Types::TIME_MUTABLE, nullable: true)] | ||||
|     private ?\DateTimeInterface $sunOpen = null; | ||||
|  | ||||
|     #[ORM\Column(type: Types::TIME_MUTABLE, nullable: true)] | ||||
|     private ?\DateTimeInterface $sunClose = null; | ||||
|  | ||||
|     #[ORM\Column(type: Types::TEXT, nullable: true)] | ||||
|     private ?string $notes = null; | ||||
|  | ||||
|     #[ORM\Column(length: 255, nullable: true)] | ||||
|     private ?string $servicesAvailable = null; | ||||
|  | ||||
|     public function __construct( | ||||
|         private DateTime $today | ||||
|     ) { | ||||
|         $this->today = new DateTime('now', new DateTimeZone('America/New_York')); | ||||
|     } | ||||
|  | ||||
|     public function getId(): ?Uuid | ||||
|     { | ||||
|         return $this->id; | ||||
|     } | ||||
|  | ||||
|     public function getName(): ?string | ||||
|     { | ||||
|         return $this->name; | ||||
|     } | ||||
|  | ||||
|     public function setName(string $name): static | ||||
|     { | ||||
|         $this->name = $name; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function getAddress(): ?string | ||||
|     { | ||||
|         return $this->address; | ||||
|     } | ||||
|  | ||||
|     public function setAddress(string $address): static | ||||
|     { | ||||
|         $this->address = $address; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function getAddress2(): ?string | ||||
|     { | ||||
|         return $this->address2; | ||||
|     } | ||||
|  | ||||
|     public function setAddress2(?string $address2): static | ||||
|     { | ||||
|         $this->address2 = $address2; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function getCity(): ?string | ||||
|     { | ||||
|         return $this->city; | ||||
|     } | ||||
|  | ||||
|     public function setCity(string $city): static | ||||
|     { | ||||
|         $this->city = $city; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function getState(): ?State | ||||
|     { | ||||
|         return $this->state; | ||||
|     } | ||||
|  | ||||
|     public function setState(State $state): static | ||||
|     { | ||||
|         $this->state = $state; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function getZip(): ?int | ||||
|     { | ||||
|         return $this->zip; | ||||
|     } | ||||
|  | ||||
|     public function setZip(int $zip): static | ||||
|     { | ||||
|         $this->zip = $zip; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function getCounty(): ?County | ||||
|     { | ||||
|         return $this->county; | ||||
|     } | ||||
|  | ||||
|     public function setCounty(County $county): static | ||||
|     { | ||||
|         $this->county = $county; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function getFormattedAddress(): ?string | ||||
|     { | ||||
|         return $this->address . | ||||
|             ($this->address2 ? ' ' . $this->address2 : '') . '<br/>' . | ||||
|             $this->city . ', ' . $this->state->value . ' ' . $this->zip; | ||||
|     } | ||||
|  | ||||
|     public function getPhone(): ?string | ||||
|     { | ||||
|         return $this->phone; | ||||
|     } | ||||
|  | ||||
|     public function setPhone(?string $phone): static | ||||
|     { | ||||
|         $this->phone = $phone; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function getEmail(): ?string | ||||
|     { | ||||
|         return $this->email; | ||||
|     } | ||||
|  | ||||
|     public function setEmail(?string $email): static | ||||
|     { | ||||
|         $this->email = $email; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function getUrl(): ?string | ||||
|     { | ||||
|         return $this->url; | ||||
|     } | ||||
|  | ||||
|     public function setUrl(?string $url): static | ||||
|     { | ||||
|         $this->url = $url; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function urlString(): ?string | ||||
|     { | ||||
|         if (preg_match("/facebook/i", $this->url)) { | ||||
|             return "<a href='$this->url' target='_blank'><i class='fa-brands fa-facebook'></i></a>"; | ||||
|         } else { | ||||
|             return "<a href='$this->url' target='_blank'><i class='fa-solid fa-globe'></i></a>"; | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function getContactCard(): ?string | ||||
|     { | ||||
|         $formattedPhone = ($this->phone ? '(' . substr($this->phone, 0, 3) . ') ' . substr($this->phone, 3, 3) . '-' . substr($this->phone, 6) : ''); | ||||
|         return ($this->email ? "<a href='mailto:$this->email'>$this->email</a><br/>" : '') . | ||||
|             ($this->phone ? "<a href='tel:$this->phone'>$formattedPhone</a>" : ''); | ||||
|     } | ||||
|  | ||||
|     public function generateVCard(): string | ||||
|     { | ||||
|         return 'BEGIN:VCARD' . | ||||
|             "\nVERSION:3.0" . | ||||
|             "\nN:$this->name" . | ||||
|             "\nFN:$this->name" . | ||||
|             "\nORG:$this->name" . | ||||
|             "\nADR;TYPE=WORK:;;$this->address;$this->city;{$this->state->value};$this->zip" . | ||||
|             ($this->phone ? "\nTEL;TYPE=WORK,VOICE:$this->phone" : null) . | ||||
|             ($this->email ? "\nEMAIL;TYPE=WORK,INTERNET:$this->email" : null) . | ||||
|             ($this->url ? "\nURL:$this->url" : null) . | ||||
|             "\nNOTE:$this->notes" . | ||||
|             "\nREV:" . date('c') . | ||||
|             "\nEND:VCARD"; | ||||
|     } | ||||
|  | ||||
|     public function getMonOpen(): ?\DateTimeInterface | ||||
|     { | ||||
|         return $this->monOpen; | ||||
|     } | ||||
|  | ||||
|     public function setMonOpen(?\DateTimeInterface $monOpen): static | ||||
|     { | ||||
|         $this->monOpen = $monOpen; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function getMonClose(): ?\DateTimeInterface | ||||
|     { | ||||
|         return $this->monClose; | ||||
|     } | ||||
|  | ||||
|     public function setMonClose(?\DateTimeInterface $monClose): static | ||||
|     { | ||||
|         $this->monClose = $monClose; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function mon(): ?string | ||||
|     { | ||||
|         if (!$this->monOpen || !$this->monClose) { | ||||
|             return 'C'; | ||||
|         } | ||||
|  | ||||
|         $closeAt = new DateTime($this->today->format('Y-m-d') . ' ' . $this->monClose->format('H:i:s')); | ||||
|         if ($closeAt <= new DateTime()) { | ||||
|             return 'C'; | ||||
|         } | ||||
|  | ||||
|         return $this->monOpen->format('g:i A') . '-' . $this->monClose->format('g:i A'); | ||||
|     } | ||||
|  | ||||
|     public function getTueOpen(): ?\DateTimeInterface | ||||
|     { | ||||
|         return $this->tueOpen; | ||||
|     } | ||||
|  | ||||
|     public function setTueOpen(?\DateTimeInterface $tueOpen): static | ||||
|     { | ||||
|         $this->tueOpen = $tueOpen; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function getTueClose(): ?\DateTimeInterface | ||||
|     { | ||||
|         return $this->tueClose; | ||||
|     } | ||||
|  | ||||
|     public function setTueClose(?\DateTimeInterface $tueClose): static | ||||
|     { | ||||
|         $this->tueClose = $tueClose; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function tue(): ?string | ||||
|     { | ||||
|         if (!$this->tueOpen || !$this->tueClose) { | ||||
|             return 'C'; | ||||
|         } | ||||
|  | ||||
|         $closeAt = new DateTime($this->today->format('Y-m-d') . ' ' . $this->tueClose->format('H:i:s')); | ||||
|         if ($closeAt <= new DateTime()) { | ||||
|             return 'C'; | ||||
|         } | ||||
|  | ||||
|         return $this->tueOpen->format('g:i A') . '-' . $this->tueClose->format('g:i A'); | ||||
|     } | ||||
|  | ||||
|     public function getWedOpen(): ?\DateTimeInterface | ||||
|     { | ||||
|         return $this->wedOpen; | ||||
|     } | ||||
|  | ||||
|     public function setWedOpen(?\DateTimeInterface $wedOpen): static | ||||
|     { | ||||
|         $this->wedOpen = $wedOpen; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function getWedClose(): ?\DateTimeInterface | ||||
|     { | ||||
|         return $this->wedClose; | ||||
|     } | ||||
|  | ||||
|     public function setWedClose(?\DateTimeInterface $wedClose): static | ||||
|     { | ||||
|         $this->wedClose = $wedClose; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function wed(): ?string | ||||
|     { | ||||
|         if (!$this->wedOpen || !$this->wedClose) { | ||||
|             return 'C'; | ||||
|         } | ||||
|  | ||||
|         $closeAt = new DateTime($this->today->format('Y-m-d') . ' ' . $this->wedClose->format('H:i:s')); | ||||
|         if ($closeAt <= new DateTime()) { | ||||
|             return 'C'; | ||||
|         } | ||||
|  | ||||
|         return $this->wedOpen->format('g:i A') . '-' . $this->wedClose->format('g:i A'); | ||||
|     } | ||||
|  | ||||
|     public function getThuOpen(): ?\DateTimeInterface | ||||
|     { | ||||
|         return $this->thuOpen; | ||||
|     } | ||||
|  | ||||
|     public function setThuOpen(?\DateTimeInterface $thuOpen): static | ||||
|     { | ||||
|         $this->thuOpen = $thuOpen; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function getThuClose(): ?\DateTimeInterface | ||||
|     { | ||||
|         return $this->thuClose; | ||||
|     } | ||||
|  | ||||
|     public function setThuClose(?\DateTimeInterface $thuClose): static | ||||
|     { | ||||
|         $this->thuClose = $thuClose; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function thu(): ?string | ||||
|     { | ||||
|         if (!$this->thuOpen || !$this->thuClose) { | ||||
|             return 'C'; | ||||
|         } | ||||
|  | ||||
|         $closeAt = new DateTime($this->today->format('Y-m-d') . ' ' . $this->thuClose->format('H:i:s')); | ||||
|         if ($closeAt <= new DateTime()) { | ||||
|             return 'C'; | ||||
|         } | ||||
|  | ||||
|         return $this->thuOpen->format('g:i A') . '-' . $this->thuClose->format('g:i A'); | ||||
|     } | ||||
|  | ||||
|     public function getFriOpen(): ?\DateTimeInterface | ||||
|     { | ||||
|         return $this->friOpen; | ||||
|     } | ||||
|  | ||||
|     public function setFriOpen(?\DateTimeInterface $friOpen): static | ||||
|     { | ||||
|         $this->friOpen = $friOpen; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function getFriClose(): ?\DateTimeInterface | ||||
|     { | ||||
|         return $this->friClose; | ||||
|     } | ||||
|  | ||||
|     public function setFriClose(?\DateTimeInterface $friClose): static | ||||
|     { | ||||
|         $this->friClose = $friClose; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function fri(): ?string | ||||
|     { | ||||
|         if (!$this->friOpen || !$this->friClose) { | ||||
|             return 'C'; | ||||
|         } | ||||
|  | ||||
|         $closeAt = new DateTime($this->today->format('Y-m-d') . ' ' . $this->friClose->format('H:i:s')); | ||||
|         if ($closeAt <= new DateTime()) { | ||||
|             return 'C'; | ||||
|         } | ||||
|  | ||||
|         return $this->friOpen->format('g:i A') . '-' . $this->friClose->format('g:i A'); | ||||
|     } | ||||
|  | ||||
|     public function getSatOpen(): ?\DateTimeInterface | ||||
|     { | ||||
|         return $this->satOpen; | ||||
|     } | ||||
|  | ||||
|     public function setSatOpen(?\DateTimeInterface $satOpen): static | ||||
|     { | ||||
|         $this->satOpen = $satOpen; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function getSatClose(): ?\DateTimeInterface | ||||
|     { | ||||
|         return $this->satClose; | ||||
|     } | ||||
|  | ||||
|     public function setSatClose(?\DateTimeInterface $satClose): static | ||||
|     { | ||||
|         $this->satClose = $satClose; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function sat(): ?string | ||||
|     { | ||||
|         if (!$this->satOpen || !$this->satClose) { | ||||
|             return 'C'; | ||||
|         } | ||||
|  | ||||
|         $closeAt = new DateTime($this->today->format('Y-m-d') . ' ' . $this->satClose->format('H:i:s')); | ||||
|         if ($closeAt <= new DateTime()) { | ||||
|             return 'C'; | ||||
|         } | ||||
|  | ||||
|         return $this->satOpen->format('g:i A') . '-' . $this->satClose->format('g:i A'); | ||||
|     } | ||||
|  | ||||
|     public function getSunOpen(): ?\DateTimeInterface | ||||
|     { | ||||
|         return $this->sunOpen; | ||||
|     } | ||||
|  | ||||
|     public function setSunOpen(?\DateTimeInterface $sunOpen): static | ||||
|     { | ||||
|         $this->sunOpen = $sunOpen; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function getSunClose(): ?\DateTimeInterface | ||||
|     { | ||||
|         return $this->sunClose; | ||||
|     } | ||||
|  | ||||
|     public function setSunClose(?\DateTimeInterface $sunClose): static | ||||
|     { | ||||
|         $this->sunClose = $sunClose; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function sun(): ?string | ||||
|     { | ||||
|         if (!$this->sunOpen || !$this->sunClose) { | ||||
|             return 'C'; | ||||
|         } | ||||
|  | ||||
|         $closeAt = new DateTime($this->today->format('Y-m-d') . ' ' . $this->sunClose->format('H:i:s')); | ||||
|         if ($closeAt <= new DateTime()) { | ||||
|             return 'C'; | ||||
|         } | ||||
|  | ||||
|         return $this->sunOpen->format('g:i A') . '-' . $this->sunClose->format('g:i A'); | ||||
|     } | ||||
|  | ||||
|     public function getHours(): ?string | ||||
|     { | ||||
|         $this->today = new DateTime('now', new DateTimeZone('America/New_York')); | ||||
|         switch ($this->today->format('w')) { | ||||
|             case 0: | ||||
|                 return $this->sun(); | ||||
|             case 1: | ||||
|                 return $this->mon(); | ||||
|             case 2: | ||||
|                 return $this->tue(); | ||||
|             case 3: | ||||
|                 return $this->wed(); | ||||
|             case 4: | ||||
|                 return $this->thu(); | ||||
|             case 5: | ||||
|                 return $this->fri(); | ||||
|             case 6: | ||||
|                 return $this->sat(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function getFormattedHours(): ?string | ||||
|     { | ||||
|         $mon = 'CLOSED'; | ||||
|         $tue = 'CLOSED'; | ||||
|         $wed = 'CLOSED'; | ||||
|         $thu = 'CLOSED'; | ||||
|         $fri = 'CLOSED'; | ||||
|         $sat = 'CLOSED'; | ||||
|         $sun = 'CLOSED'; | ||||
|  | ||||
|         if ($this->monOpen && $this->monClose) { | ||||
|             $mon = $this->monOpen->format('g:i A') . '-' . $this->monClose->format('g:i A'); | ||||
|         } | ||||
|         if ($this->tueOpen && $this->tueClose) { | ||||
|             $tue = $this->tueOpen->format('g:i A') . '-' . $this->tueClose->format('g:i A'); | ||||
|         } | ||||
|         if ($this->wedOpen && $this->wedClose) { | ||||
|             $wed = $this->wedOpen->format('g:i A') . '-' . $this->wedClose->format('g:i A'); | ||||
|         } | ||||
|         if ($this->thuOpen && $this->thuClose) { | ||||
|             $thu = $this->thuOpen->format('g:i A') . '-' . $this->thuClose->format('g:i A'); | ||||
|         } | ||||
|         if ($this->friOpen && $this->friClose) { | ||||
|             $fri = $this->friOpen->format('g:i A') . '-' . $this->friClose->format('g:i A'); | ||||
|         } | ||||
|         if ($this->satOpen && $this->satClose) { | ||||
|             $sat = $this->satOpen->format('g:i A') . '-' . $this->satClose->format('g:i A'); | ||||
|         } | ||||
|         if ($this->sunOpen && $this->sunClose) { | ||||
|             $sun = $this->sunOpen->format('g:i A') . '-' . $this->sunClose->format('g:i A'); | ||||
|         } | ||||
|  | ||||
|         return <<<HTML | ||||
|             <p>Sun: {$sun}</p> | ||||
|             <p>Mon: {$mon}</p> | ||||
|             <p>Tue: {$tue}</p> | ||||
|             <p>Wed: {$wed}</p> | ||||
|             <p>Thu: {$thu}</p> | ||||
|             <p>Fri: {$fri}</p> | ||||
|             <p>Sat: {$sat}</p> | ||||
|         HTML; | ||||
|     } | ||||
|  | ||||
|     public function getNotes(): ?string | ||||
|     { | ||||
|         return $this->notes; | ||||
|     } | ||||
|  | ||||
|     public function setNotes(?string $notes): static | ||||
|     { | ||||
|         $this->notes = $notes; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function getServicesAvailable(): ?string | ||||
|     { | ||||
|         return $this->servicesAvailable; | ||||
|     } | ||||
|  | ||||
|     public function setServicesAvailable(?string $servicesAvailable): static | ||||
|     { | ||||
|         $this->servicesAvailable = $servicesAvailable; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										58
									
								
								src/Enums/State.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/Enums/State.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,58 @@ | ||||
| <?php | ||||
|  | ||||
| namespace App\Enums; | ||||
|  | ||||
| enum State: string | ||||
| { | ||||
|     case AL = 'AL'; | ||||
|     case AK = 'AK'; | ||||
|     case AZ = 'AZ'; | ||||
|     case AR = 'AR'; | ||||
|     case CA = 'CA'; | ||||
|     case CO = 'CO'; | ||||
|     case CT = 'CT'; | ||||
|     case DE = 'DE'; | ||||
|     case FL = 'FL'; | ||||
|     case GA = 'GA'; | ||||
|     case HI = 'HI'; | ||||
|     case ID = 'ID'; | ||||
|     case IL = 'IL'; | ||||
|     case IN = 'IN'; | ||||
|     case IA = 'IA'; | ||||
|     case KS = 'KS'; | ||||
|     case KY = 'KY'; | ||||
|     case LA = 'LA'; | ||||
|     case ME = 'ME'; | ||||
|     case MD = 'MD'; | ||||
|     case MA = 'MA'; | ||||
|     case MI = 'MI'; | ||||
|     case MN = 'MN'; | ||||
|     case MS = 'MS'; | ||||
|     case MO = 'MO'; | ||||
|     case MT = 'MT'; | ||||
|     case NE = 'NE'; | ||||
|     case NV = 'NV'; | ||||
|     case NH = 'NH'; | ||||
|     case NJ = 'NJ'; | ||||
|     case NM = 'NM'; | ||||
|     case NY = 'NY'; | ||||
|     case NC = 'NC'; | ||||
|     case ND = 'ND'; | ||||
|     case OH = 'OH'; | ||||
|     case OK = 'OK'; | ||||
|     case OR = 'OR'; | ||||
|     case PA = 'PA'; | ||||
|     case RI = 'RI'; | ||||
|     case SC = 'SC'; | ||||
|     case SD = 'SD'; | ||||
|     case TN = 'TN'; | ||||
|     case TX = 'TX'; | ||||
|     case UT = 'UT'; | ||||
|     case VT = 'VT'; | ||||
|     case VA = 'VA'; | ||||
|     case WA = 'WA'; | ||||
|     case WV = 'WV'; | ||||
|     case WI = 'WI'; | ||||
|     case WY = 'WY'; | ||||
|     case DC = 'DC'; | ||||
| } | ||||
							
								
								
									
										96
									
								
								src/Form/ResourceFormType.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								src/Form/ResourceFormType.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | ||||
| <?php | ||||
|  | ||||
| namespace App\Form; | ||||
|  | ||||
| use App\Entity\CommunityResource; | ||||
| use App\Enums\County; | ||||
| use App\Enums\State; | ||||
| use Symfony\Component\Form\AbstractType; | ||||
| use Symfony\Component\Form\Extension\Core\Type\EmailType; | ||||
| use Symfony\Component\Form\Extension\Core\Type\EnumType; | ||||
| use Symfony\Component\Form\Extension\Core\Type\NumberType; | ||||
| use Symfony\Component\Form\Extension\Core\Type\TextType; | ||||
| use Symfony\Component\Form\Extension\Core\Type\TimeType; | ||||
| use Symfony\Component\Form\Extension\Core\Type\UrlType; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use Symfony\Component\OptionsResolver\OptionsResolver; | ||||
|  | ||||
| class ResourceFormType extends AbstractType | ||||
| { | ||||
|     public function buildForm(FormBuilderInterface $builder, array $options): void | ||||
|     { | ||||
|         $builder | ||||
|             ->add('name', TextType::class, [ | ||||
|                 'required' => true, | ||||
|             ]) | ||||
|             ->add('address', TextType::class, [ | ||||
|                 'required' => true, | ||||
|             ]) | ||||
|             ->add('address2') | ||||
|             ->add('city', TextType::class, [ | ||||
|                 'required' => true, | ||||
|             ]) | ||||
|             ->add('state', EnumType::class, [ | ||||
|                 'class' => State::class, | ||||
|             ]) | ||||
|             ->add('zip', NumberType::class) | ||||
|             ->add('county', EnumType::class, [ | ||||
|                 'class' => County::class, | ||||
|             ]) | ||||
|             ->add('phone') | ||||
|             ->add('email', EmailType::class) | ||||
|             ->add('url', UrlType::class) | ||||
|             ->add('monOpen', TimeType::class, [ | ||||
|                 'widget' => 'single_text', | ||||
|             ]) | ||||
|             ->add('monClose', TimeType::class, [ | ||||
|                 'widget' => 'single_text', | ||||
|             ]) | ||||
|             ->add('tueOpen', TimeType::class, [ | ||||
|                 'widget' => 'single_text', | ||||
|             ]) | ||||
|             ->add('tueClose', TimeType::class, [ | ||||
|                 'widget' => 'single_text', | ||||
|             ]) | ||||
|             ->add('wedOpen', TimeType::class, [ | ||||
|                 'widget' => 'single_text', | ||||
|             ]) | ||||
|             ->add('wedClose', TimeType::class, [ | ||||
|                 'widget' => 'single_text', | ||||
|             ]) | ||||
|             ->add('thuOpen', TimeType::class, [ | ||||
|                 'widget' => 'single_text', | ||||
|             ]) | ||||
|             ->add('thuClose', TimeType::class, [ | ||||
|                 'widget' => 'single_text', | ||||
|             ]) | ||||
|             ->add('friOpen', TimeType::class, [ | ||||
|                 'widget' => 'single_text', | ||||
|             ]) | ||||
|             ->add('friClose', TimeType::class, [ | ||||
|                 'widget' => 'single_text', | ||||
|             ]) | ||||
|             ->add('satOpen', TimeType::class, [ | ||||
|                 'widget' => 'single_text', | ||||
|             ]) | ||||
|             ->add('satClose', TimeType::class, [ | ||||
|                 'widget' => 'single_text', | ||||
|             ]) | ||||
|             ->add('sunOpen', TimeType::class, [ | ||||
|                 'widget' => 'single_text', | ||||
|             ]) | ||||
|             ->add('sunClose', TimeType::class, [ | ||||
|                 'widget' => 'single_text', | ||||
|             ]) | ||||
|             ->add('notes') | ||||
|             ->add('servicesAvailable') | ||||
|         ; | ||||
|     } | ||||
|  | ||||
|     public function configureOptions(OptionsResolver $resolver): void | ||||
|     { | ||||
|         $resolver->setDefaults([ | ||||
|             'data_class' => CommunityResource::class, | ||||
|         ]); | ||||
|     } | ||||
| } | ||||
| @@ -14,6 +14,7 @@ class NavList | ||||
|         'add_user' => 'nav-link text-dark', | ||||
|         'referral_sources' => 'nav-link text-dark', | ||||
|         'case_notes' => 'nav-link text-dark', | ||||
|         'community_resource' => 'nav-link text-dark', | ||||
|     ]; | ||||
|  | ||||
|     public const PRESENT_LINK = 'nav-link text-white active bg-gradient-dark'; | ||||
|   | ||||
							
								
								
									
										43
									
								
								src/Repository/CommunityResourceRepository.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/Repository/CommunityResourceRepository.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| <?php | ||||
|  | ||||
| namespace App\Repository; | ||||
|  | ||||
| use App\Entity\CommunityResource; | ||||
| use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; | ||||
| use Doctrine\Persistence\ManagerRegistry; | ||||
|  | ||||
| /** | ||||
|  * @extends ServiceEntityRepository<CommunityResource> | ||||
|  */ | ||||
| class CommunityResourceRepository extends ServiceEntityRepository | ||||
| { | ||||
|     public function __construct(ManagerRegistry $registry) | ||||
|     { | ||||
|         parent::__construct($registry, CommunityResource::class); | ||||
|     } | ||||
|  | ||||
|     //    /** | ||||
|     //     * @return CommunityResource[] Returns an array of CommunityResource objects | ||||
|     //     */ | ||||
|     //    public function findByExampleField($value): array | ||||
|     //    { | ||||
|     //        return $this->createQueryBuilder('c') | ||||
|     //            ->andWhere('c.exampleField = :val') | ||||
|     //            ->setParameter('val', $value) | ||||
|     //            ->orderBy('c.id', 'ASC') | ||||
|     //            ->setMaxResults(10) | ||||
|     //            ->getQuery() | ||||
|     //            ->getResult() | ||||
|     //        ; | ||||
|     //    } | ||||
|  | ||||
|     //    public function findOneBySomeField($value): ?CommunityResource | ||||
|     //    { | ||||
|     //        return $this->createQueryBuilder('c') | ||||
|     //            ->andWhere('c.exampleField = :val') | ||||
|     //            ->setParameter('val', $value) | ||||
|     //            ->getQuery() | ||||
|     //            ->getOneOrNullResult() | ||||
|     //        ; | ||||
|     //    } | ||||
| } | ||||
							
								
								
									
										165
									
								
								templates/internal/community_resource/add.html.twig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								templates/internal/community_resource/add.html.twig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,165 @@ | ||||
| {% extends 'base.html.twig' %} | ||||
|  | ||||
| {% block title %}Community Resources | ||||
| {% endblock %} | ||||
|  | ||||
| {% 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_start(form) }} | ||||
|  | ||||
| 						{{ form_errors(form) }} | ||||
| 						<div class="row"> | ||||
| 							<div class='col'> | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<label for='rsc_form_name' class='form-label'>Name</label> | ||||
| 									<input type='text' name='{{ field_name(form.name) }}' id='rsc_form_name' class='form-control' required='required'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<label for='rsc_form_address' class='form-label'>Address</label> | ||||
| 									<input type='text' name='{{ field_name(form.address) }}' id='rsc_form_address' class='form-control' required='required'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<label for='rsc_form_address2' class='form-label'>Address 2</label> | ||||
| 									<input type='text' name='{{ field_name(form.address2) }}' id='rsc_form_address2' class='form-control'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<label for='rsc_form_city' class='form-label'>City</label> | ||||
| 									<input type='text' name='{{ field_name(form.city) }}' id='rsc_form_city' class='form-control' required='required'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<label for='rsc_form_state'></label> | ||||
| 									<select id='rsc_form_state' name='{{ field_name(form.state) }}' class='form-control' required='required'> | ||||
| 										<option value=''>-- Select --</option> | ||||
| 										{% for s in enum('App\\Enums\\State').cases() %} | ||||
| 											<option value='{{ s.value }}'>{{ s.name }}</option> | ||||
| 										{% endfor %} | ||||
| 									</select> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<label for='rsc_form_zip' class='form-label'>Zip</label> | ||||
| 									<input type='text' name='{{ field_name(form.zip) }}' id='rsc_form_zip' class='form-control' required='required'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<label for='rsc_form_county' class='form-label'></label> | ||||
| 									<select name='{{ field_name(form.county) }}' id='rsc_form_county' class='form-control' required='required'> | ||||
| 										<option value=''>-- Select --</option> | ||||
|  | ||||
| 										{% for c in enum('App\\Enums\\County').cases() %} | ||||
| 											<option value='{{ c.value }}'>{{ c.value }}</option> | ||||
| 										{% endfor %} | ||||
| 									</select> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<label for='rsc_form_phone' class='form-label'>Phone</label> | ||||
| 									<input type='phone' name='{{ field_name(form.phone) }}' id='rsc_form_phone' class='form-control'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<label for='rsc_form_email' class='form-label'>Email</label> | ||||
| 									<input type='email' name='{{ field_name(form.email) }}' id='rsc_form_email' class='form-control'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<label for='rsc_form_url' class='form-label'>URL</label> | ||||
| 									<input type='text' name='{{ field_name(form.url) }}' id='rsc_form_url' class='form-control'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<label for='rsc_form_services' class='form-label'>Services Available</label> | ||||
| 									<input type='text' name='{{ field_name(form.servicesAvailable) }}' id='rsc_form_services' class='form-control'/> | ||||
| 								</div> | ||||
| 							</div> | ||||
| 							<div class='col'> | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<span>Sunday</span> | ||||
| 									<label for='rsc_form_sunOpen'></label> | ||||
| 									<input type='time' name='{{ field_name(form.sunOpen) }}' id='rsc_form_sunOpen' class='form-control'/> | ||||
| 									<label for='rsc_form_sunClose'></label> | ||||
| 									<input type='time' name='{{ field_name(form.sunClose) }}' id='rsc_form_sunClose' class='form-control'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<span>Monday</span> | ||||
| 									<label for='rsc_form_monOpen'></label> | ||||
| 									<input type='time' name='{{ field_name(form.monOpen) }}' id='rsc_form_monOpen' class='form-control'/> | ||||
| 									<label for='rsc_form_monClose'></label> | ||||
| 									<input type='time' name='{{ field_name(form.monClose) }}' id='rsc_form_monClose' class='form-control'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<span>Tuesday</span> | ||||
| 									<label for='rsc_form_tueOpen'></label> | ||||
| 									<input type='time' name='{{ field_name(form.tueOpen) }}' id='rsc_form_tueOpen' class='form-control'/> | ||||
| 									<label for='rsc_form_tueClose'></label> | ||||
| 									<input type='time' name='{{ field_name(form.tueClose) }}' id='rsc_form_tueClose' class='form-control'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<span>Wednesday</span> | ||||
| 									<label for='rsc_form_wedOpen'></label> | ||||
| 									<input type='time' name='{{ field_name(form.wedOpen) }}' id='rsc_form_wedOpen' class='form-control'/> | ||||
| 									<label for='rsc_form_wedClose'></label> | ||||
| 									<input type='time' name='{{ field_name(form.wedClose) }}' id='rsc_form_wedClose' class='form-control'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<span>Thursday</span> | ||||
| 									<label for='rsc_form_thuOpen'></label> | ||||
| 									<input type='time' name='{{ field_name(form.thuOpen) }}' id='rsc_form_thuOpen' class='form-control'/> | ||||
| 									<label for='rsc_form_thuClose'></label> | ||||
| 									<input type='time' name='{{ field_name(form.thuClose) }}' id='rsc_form_thuClose' class='form-control'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<span>Friday</span> | ||||
| 									<label for='rsc_form_friOpen'></label> | ||||
| 									<input type='time' name='{{ field_name(form.friOpen) }}' id='rsc_form_friOpen' class='form-control'/> | ||||
| 									<label for='rsc_form_friClose'></label> | ||||
| 									<input type='time' name='{{ field_name(form.friClose) }}' id='rsc_form_friClose' class='form-control'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<span>Saturday</span> | ||||
| 									<label for='rsc_form_satOpen'></label> | ||||
| 									<input type='time' name='{{ field_name(form.satOpen) }}' id='rsc_form_satOpen' class='form-control'/> | ||||
| 									<label for='rsc_form_satClose'></label> | ||||
| 									<input type='time' name='{{ field_name(form.satClose) }}' id='rsc_form_satClose' class='form-control'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<textarea name='{{ field_name(form.notes) }}' id='rsc_form_notes' style='width:100%;height:150px;' placeholder='Notes'></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 Resource</button> | ||||
| 							</div> | ||||
| 						</div> | ||||
| 						{{ form_end(form) }} | ||||
| 					</div> | ||||
| 				</div> | ||||
| 			</div> | ||||
| 		</section> | ||||
| 	</main> | ||||
| {% endblock %} | ||||
							
								
								
									
										164
									
								
								templates/internal/community_resource/edit.html.twig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								templates/internal/community_resource/edit.html.twig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,164 @@ | ||||
| {% extends 'base.html.twig' %} | ||||
|  | ||||
| {% block title %}Community Resources | ||||
| {% endblock %} | ||||
|  | ||||
| {% 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">{{ field_value(form.name) }}</h4> | ||||
| 				</div> | ||||
| 				<div class="card-body"> | ||||
| 					<div class="container"> | ||||
| 						{{ form_start(form) }} | ||||
|  | ||||
| 						{{ form_errors(form) }} | ||||
| 						<div class="row"> | ||||
| 							<div class='col'> | ||||
| 								<div class='input-group input-group-outline mb-3 is-filled'> | ||||
| 									<label for='rsc_form_name' class='form-label'>Name</label> | ||||
| 									<input type='text' name='{{ field_name(form.name) }}' value='{{ field_value(form.name) }}' id='rsc_form_name' class='form-control' required='required'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3 is-filled'> | ||||
| 									<label for='rsc_form_address' class='form-label'>Address</label> | ||||
| 									<input type='text' name='{{ field_name(form.address) }}' value='{{ field_value(form.address) }}' id='rsc_form_address' class='form-control' required='required'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3 {% if field_value(form.address2) %}is-filled{% endif %}'> | ||||
| 									<label for='rsc_form_address2' class='form-label'>Address 2</label> | ||||
| 									<input type='text' name='{{ field_name(form.address2) }}' value='{{ field_value(form.address2) }}' id='rsc_form_address2' class='form-control'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3 is-filled'> | ||||
| 									<label for='rsc_form_city' class='form-label'>City</label> | ||||
| 									<input type='text' name='{{ field_name(form.city) }}' value='{{ field_value(form.city) }}' id='rsc_form_city' class='form-control' required='required'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<label for='rsc_form_state'></label> | ||||
| 									<select id='rsc_form_state' name='{{ field_name(form.state) }}' class='form-control' required='required'> | ||||
| 										<option value=''>-- Select --</option> | ||||
| 										{% for s in enum('App\\Enums\\State').cases() %} | ||||
| 											<option value='{{ s.value }}' {% if s.value == field_value(form.state) %} selected='selected' {% endif %}>{{ s.name }}</option> | ||||
| 										{% endfor %} | ||||
| 									</select> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3 is-filled'> | ||||
| 									<label for='rsc_form_zip' class='form-label'>Zip</label> | ||||
| 									<input type='text' name='{{ field_name(form.zip) }}' value='{{ field_value(form.zip) }}' id='rsc_form_zip' class='form-control' required='required'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<label for='rsc_form_county' class='form-label'></label> | ||||
| 									<select name='{{ field_name(form.county) }}' id='rsc_form_county' class='form-control' required='required'> | ||||
| 										<option value=''>-- Select --</option> | ||||
|  | ||||
| 										{% for c in enum('App\\Enums\\County').cases() %} | ||||
| 											<option value='{{ c.value }}' {% if c.value == field_value(form.county) %} selected='selected' {% endif %}>{{ c.value }}</option> | ||||
| 										{% endfor %} | ||||
| 									</select> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3 {% if field_value(form.phone) %}is-filled{% endif %}'> | ||||
| 									<label for='rsc_form_phone' class='form-label'>Phone</label> | ||||
| 									<input type='phone' name='{{ field_name(form.phone) }}' value='{{ field_value(form.phone) }}' id='rsc_form_phone' class='form-control'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3 {% if field_value(form.email) %}is-filled{% endif %}'> | ||||
| 									<label for='rsc_form_email' class='form-label'>Email</label> | ||||
| 									<input type='email' name='{{ field_name(form.email) }}' value='{{ field_value(form.email) }}' id='rsc_form_email' class='form-control'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3 {% if field_value(form.url) %}is-filled{% endif %}'> | ||||
| 									<label for='rsc_form_url' class='form-label'>URL</label> | ||||
| 									<input type='text' name='{{ field_name(form.url) }}' value='{{ field_value(form.url) }}' id='rsc_form_url' class=' form-control'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class=' input-group input-group-outline mb-3 {% if field_value(form.servicesAvailable) %}is-filled{% endif %}'> | ||||
| 									<label for='rsc_form_services' class='form-label'>Services Available</label> | ||||
| 									<input type='text' name='{{ field_name(form.servicesAvailable) }}' value='{{ field_value(form.servicesAvailable) }}' id='rsc_form_services' class='form-control'/> | ||||
| 								</div> | ||||
| 							</div> | ||||
| 							<div class='col'> | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<span>Sunday</span> | ||||
| 									<label for='rsc_form_sunOpen'></label> | ||||
| 									<input type='time' name='{{ field_name(form.sunOpen) }}' value='{{ field_value(form.sunOpen) }}' id='rsc_form_sunOpen' class='form-control'/> | ||||
| 									<label for='rsc_form_sunClose'></label> | ||||
| 									<input type='time' name='{{ field_name(form.sunClose) }}' value='{{ field_value(form.sunClose) }}' id='rsc_form_sunClose' class='form-control'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<span>Monday</span> | ||||
| 									<label for='rsc_form_monOpen'></label> | ||||
| 									<input type='time' name='{{ field_name(form.monOpen) }}' value='{{ field_value(form.monOpen) }}' id='rsc_form_monOpen' class='form-control'/> | ||||
| 									<label for='rsc_form_monClose'></label> | ||||
| 									<input type='time' name='{{ field_name(form.monClose) }}' value='{{ field_value(form.monClose) }}' id='rsc_form_monClose' class='form-control'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<span>Tuesday</span> | ||||
| 									<label for='rsc_form_tueOpen'></label> | ||||
| 									<input type='time' name='{{ field_name(form.tueOpen) }}' value='{{ field_value(form.tueOpen) }}' id='rsc_form_tueOpen' class='form-control'/> | ||||
| 									<label for='rsc_form_tueClose'></label> | ||||
| 									<input type='time' name='{{ field_name(form.tueClose) }}' value='{{ field_value(form.tueClose) }}' id='rsc_form_tueClose' class='form-control'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<span>Wednesday</span> | ||||
| 									<label for='rsc_form_wedOpen'></label> | ||||
| 									<input type='time' name='{{ field_name(form.wedOpen) }}' value='{{ field_value(form.wedOpen) }}' id='rsc_form_wedOpen' class='form-control'/> | ||||
| 									<label for='rsc_form_wedClose'></label> | ||||
| 									<input type='time' name='{{ field_name(form.wedClose) }}' value='{{ field_value(form.wedClose) }}' id='rsc_form_wedClose' class='form-control'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<span>Thursday</span> | ||||
| 									<label for='rsc_form_thuOpen'></label> | ||||
| 									<input type='time' name='{{ field_name(form.thuOpen) }}' value='{{ field_value(form.thuOpen) }}' id='rsc_form_thuOpen' class='form-control'/> | ||||
| 									<label for='rsc_form_thuClose'></label> | ||||
| 									<input type='time' name='{{ field_name(form.thuClose) }}' value='{{ field_value(form.thuClose) }}' id='rsc_form_thuClose' class='form-control'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<span>Friday</span> | ||||
| 									<label for='rsc_form_friOpen'></label> | ||||
| 									<input type='time' name='{{ field_name(form.friOpen) }}' value='{{ field_value(form.friOpen) }}' id='rsc_form_friOpen' class='form-control'/> | ||||
| 									<label for='rsc_form_friClose'></label> | ||||
| 									<input type='time' name='{{ field_name(form.friClose) }}' value='{{ field_value(form.friClose) }}' id='rsc_form_friClose' class='form-control'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<span>Saturday</span> | ||||
| 									<label for='rsc_form_satOpen'></label> | ||||
| 									<input type='time' name='{{ field_name(form.satOpen) }}' value='{{ field_value(form.satOpen) }}' id='rsc_form_satOpen' class='form-control'/> | ||||
| 									<label for='rsc_form_satClose'></label> | ||||
| 									<input type='time' name='{{ field_name(form.satClose) }}' value='{{ field_value(form.satClose) }}' id='rsc_form_satClose' class='form-control'/> | ||||
| 								</div> | ||||
|  | ||||
| 								<div class='input-group input-group-outline mb-3'> | ||||
| 									<textarea name='{{ field_name(form.notes) }}' id='rsc_form_notes' style='width:100%;height:150px;' placeholder='Notes'>{{ field_value(form.notes) }}</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 Resource</button> | ||||
| 							</div> | ||||
| 						</div> | ||||
| 						{{ form_end(form) }} | ||||
| 					</div> | ||||
| 				</div> | ||||
| 			</div> | ||||
| 		</section> | ||||
| 	</main> | ||||
| {% endblock %} | ||||
							
								
								
									
										79
									
								
								templates/internal/community_resource/list.html.twig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								templates/internal/community_resource/list.html.twig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | ||||
| {% extends 'base.html.twig' %} | ||||
|  | ||||
| {% block title %}Community Resources | ||||
| {% endblock %} | ||||
|  | ||||
| {% block body %} | ||||
| 	{% set today = date("now", "America/Indiana/Indianapolis") %} | ||||
| 	{{ 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">Free/Low-cost Community Resources</h6> | ||||
| 								</div> | ||||
| 								<div> | ||||
| 									<button type="button" class="btn btn-block btn-light mb-3" onclick="window.open('{{ path('app_community_resource_add') }}', '_self')">Add Resource</button> | ||||
| 								</div> | ||||
| 							</div> | ||||
| 						</div> | ||||
| 						<div class="card-body px-0 pb-2"> | ||||
| 							<div> | ||||
| 								Filters: | ||||
| 								<select onchange='filterResourceByCounty(this.value)'> | ||||
| 									<option value=''></option> | ||||
|  | ||||
| 									{% for c in enum('App\\Enums\\County').cases() %} | ||||
| 										<option value='{{ c.value }}'>{{ c.value }}</option> | ||||
| 									{% endfor %} | ||||
| 								</select> | ||||
| 							</div> | ||||
| 							<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">Name</th> | ||||
| 											<th class="text-uppercase text-secondary text-xxs font-weight-bolder opacity-7 ps-2">Address</th> | ||||
| 											<th class="text-center text-uppercase text-secondary text-xxs font-weight-bolder opacity-7">Contact Info</th> | ||||
| 											<th class="text-center text-uppercase text-secondary text-xxs font-weight-bolder opacity-7">Hours</th> | ||||
| 											<th class="text-secondary opacity-7"></th> | ||||
| 										</tr> | ||||
| 									</thead> | ||||
| 									<tbody id='resource-list'> | ||||
| 										{% for r in resources %} | ||||
| 											<tr> | ||||
| 												<td>{{ r.name }} | ||||
| 													{% if r.url %} | ||||
| 														<br/>{{ r.urlString|raw }} | ||||
| 													{% endif %} | ||||
| 												</td> | ||||
| 												<td>{{ r.getFormattedAddress()|raw }}</td> | ||||
| 												<td>{{ r.getContactCard()|raw }}</td> | ||||
| 												<td>{{ r.getHours() }}</td> | ||||
| 												<td class='align-right'> | ||||
| 													<a href='{{ path('app_community_resource_edit', {id: r.id}) }}' title='Edit Resource'> | ||||
| 														<i class="material-symbols-rounded opacity-5">edit</i> | ||||
| 													</a> | ||||
| 													<a href='{{ path('app_community_resource_download', {id: r.id}) }}' title='Download vCard'> | ||||
| 														<i class="material-symbols-rounded opacity-5">import_contacts</i> | ||||
| 													</a> | ||||
| 												</td> | ||||
| 											</tr> | ||||
| 										{% endfor %} | ||||
| 									</tbody> | ||||
| 								</table> | ||||
| 							</div> | ||||
| 						</div> | ||||
| 					</div> | ||||
| 				</div> | ||||
| 			</div> | ||||
| 		</div> | ||||
| 	</main> | ||||
| {% endblock %} | ||||
| @@ -70,6 +70,12 @@ | ||||
| 						<span class='nav-link-text ms-1'>Case Notes</span> | ||||
| 					</a> | ||||
| 				</li> | ||||
| 				<li class='nav-item'> | ||||
| 					<a class='{{ community_resource }}' href='{{ path('app_community_resource') }}'> | ||||
| 						<i class='material-symbols-rounded opacity-5'>verified</i> | ||||
| 						<span class='nav-link-text ms-1'>Resources</span> | ||||
| 					</a> | ||||
| 				</li> | ||||
| 				<li class="nav-item mt-3"> | ||||
| 					<h6 class="ps-4 ms-2 text-uppercase text-xs text-dark font-weight-bolder opacity-5">Account pages</h6> | ||||
| 				</li> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user