Compare commits
13 Commits
577dee227d
...
c6d4a871fa
Author | SHA1 | Date | |
---|---|---|---|
c6d4a871fa | |||
9f23dfa0eb | |||
f12f9dda12 | |||
b2972fec3e | |||
18c7c33ffb | |||
68236e1571 | |||
fe47746c1f | |||
edfe6936f5 | |||
ea322dc2ac | |||
8d97ab0345 | |||
133d99d297 | |||
96abea4198 | |||
368b4fbcd3 |
BIN
assets/img/pinpoints/black-pinpoint-icon.png
Normal file
BIN
assets/img/pinpoints/black-pinpoint-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
BIN
assets/img/pinpoints/blue-pinpoint-icon.png
Normal file
BIN
assets/img/pinpoints/blue-pinpoint-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
BIN
assets/img/pinpoints/green-pinpoint-icon.png
Normal file
BIN
assets/img/pinpoints/green-pinpoint-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
BIN
assets/img/pinpoints/red-pinpoint-icon.png
Normal file
BIN
assets/img/pinpoints/red-pinpoint-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
BIN
assets/img/pinpoints/yellow-pinpoint-icon.png
Normal file
BIN
assets/img/pinpoints/yellow-pinpoint-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
@ -14,6 +14,7 @@
|
|||||||
"doctrine/orm": "^3.3",
|
"doctrine/orm": "^3.3",
|
||||||
"phpdocumentor/reflection-docblock": "^5.4",
|
"phpdocumentor/reflection-docblock": "^5.4",
|
||||||
"phpstan/phpdoc-parser": "^1.33",
|
"phpstan/phpdoc-parser": "^1.33",
|
||||||
|
"symfony-cmf/slugifier-api": "^2.1",
|
||||||
"symfony/asset": "7.2.*",
|
"symfony/asset": "7.2.*",
|
||||||
"symfony/asset-mapper": "7.2.*",
|
"symfony/asset-mapper": "7.2.*",
|
||||||
"symfony/console": "7.2.*",
|
"symfony/console": "7.2.*",
|
||||||
|
@ -79,4 +79,7 @@ return [
|
|||||||
'underscore' => [
|
'underscore' => [
|
||||||
'version' => '1.5.2',
|
'version' => '1.5.2',
|
||||||
],
|
],
|
||||||
|
'chartjs' => [
|
||||||
|
'version' => '0.3.24',
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
@ -12,6 +12,7 @@ use App\Form\UserFormType;
|
|||||||
use App\Libs\Breadcrumb;
|
use App\Libs\Breadcrumb;
|
||||||
use App\Libs\NavList;
|
use App\Libs\NavList;
|
||||||
use App\Repository\UserRepository;
|
use App\Repository\UserRepository;
|
||||||
|
use DateTime;
|
||||||
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\Request;
|
||||||
@ -20,6 +21,7 @@ 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;
|
||||||
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
||||||
|
use Symfony\Component\String\Slugger\SluggerInterface;
|
||||||
|
|
||||||
#[IsGranted('ROLE_ADMIN')]
|
#[IsGranted('ROLE_ADMIN')]
|
||||||
class AdminController extends AbstractController
|
class AdminController extends AbstractController
|
||||||
@ -96,8 +98,11 @@ class AdminController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[Route('/add-user', name: 'app_add_user')]
|
#[Route('/add-user', name: 'app_add_user')]
|
||||||
public function addUser(Request $request, #[CurrentUser()] User $admin): Response
|
public function addUser(
|
||||||
{
|
Request $request,
|
||||||
|
#[CurrentUser()] User $admin,
|
||||||
|
SluggerInterface $slugger
|
||||||
|
): Response {
|
||||||
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
||||||
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($admin);
|
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($admin);
|
||||||
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($admin);
|
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($admin);
|
||||||
@ -141,8 +146,22 @@ class AdminController extends AbstractController
|
|||||||
->setRate($form->get('rate')->getData())
|
->setRate($form->get('rate')->getData())
|
||||||
->setLevel($form->get('level')->getData())
|
->setLevel($form->get('level')->getData())
|
||||||
->setCompany($admin->getCompany())
|
->setCompany($admin->getCompany())
|
||||||
|
->setPasswordChanged(new DateTime())
|
||||||
;
|
;
|
||||||
|
|
||||||
|
if ($form->get('imageName')->getData()) {
|
||||||
|
/** @var \Symfony\Component\HttpFoundation\File\UploadedFile $file */
|
||||||
|
$file = $form['imageName']->getData();
|
||||||
|
$destination = $this->getParameter('kernel.project_dir').'/public/uploads/user_images/';
|
||||||
|
$originalFilename = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
|
||||||
|
$newFilename = $slugger->slug($originalFilename).'-'.uniqid().'.'.$file->guessExtension();
|
||||||
|
$file->move(
|
||||||
|
$destination,
|
||||||
|
$newFilename
|
||||||
|
);
|
||||||
|
|
||||||
|
$user->setImageName($newFilename);
|
||||||
|
}
|
||||||
|
|
||||||
$msg = MessageFactory::createUser($admin, $user, 'Welcome', "Welcome to CM Tracker");
|
$msg = MessageFactory::createUser($admin, $user, 'Welcome', "Welcome to CM Tracker");
|
||||||
|
|
||||||
|
@ -71,17 +71,21 @@ class CommunityResourceController extends AbstractController
|
|||||||
$rcs = $this->entityManager->getRepository(CommunityResource::class)->findAll();
|
$rcs = $this->entityManager->getRepository(CommunityResource::class)->findAll();
|
||||||
|
|
||||||
$map = new Map('default');
|
$map = new Map('default');
|
||||||
$map->center(new Point(39.768502, -86.157918))
|
$map->center(new Point($_ENV['MAP_CENTER_LAT'], $_ENV['MAP_CENTER_LON']))
|
||||||
->zoom(9)
|
->zoom($_ENV['MAP_ZOOM_LEVEL'])
|
||||||
;
|
;
|
||||||
|
|
||||||
foreach ($rcs as $rsc) {
|
foreach ($rcs as $rsc) {
|
||||||
|
/** @var CommunityResource $rsc */
|
||||||
$map->addMarker(new Marker(
|
$map->addMarker(new Marker(
|
||||||
position: new Point($rsc->getLat(), $rsc->getLon()),
|
position: new Point($rsc->getLat(), $rsc->getLon()),
|
||||||
title: $rsc->getName(),
|
title: $rsc->getName(),
|
||||||
infoWindow: new InfoWindow(
|
infoWindow: new InfoWindow(
|
||||||
content: "{$rsc->getName()}<br>{$rsc->getAddress()}, {$rsc->getCity()}, {$rsc->getState()->value} {$rsc->getZip()}<br>Services: " . $rsc->getServicesAvailable()
|
content: "{$rsc->getName()}<br>{$rsc->getAddress()}, {$rsc->getCity()}, {$rsc->getState()->value} {$rsc->getZip()}<br>Services: " . $rsc->getServicesAvailable()
|
||||||
)
|
),
|
||||||
|
extra: [
|
||||||
|
'type' => ''
|
||||||
|
]
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,6 +96,7 @@ class CommunityResourceController extends AbstractController
|
|||||||
[
|
[
|
||||||
'map' => $map,
|
'map' => $map,
|
||||||
'breadcrumbs' => [
|
'breadcrumbs' => [
|
||||||
|
new Breadcrumb($this->generateUrl('app_community_resource'), 'List Resources'),
|
||||||
new Breadcrumb('#', 'Community Resources')
|
new Breadcrumb('#', 'Community Resources')
|
||||||
],
|
],
|
||||||
'notifications' => $this->msgs,
|
'notifications' => $this->msgs,
|
||||||
|
@ -6,13 +6,23 @@ use App\Entity\Messages;
|
|||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
use App\Libs\Breadcrumb;
|
use App\Libs\Breadcrumb;
|
||||||
use App\Libs\NavList;
|
use App\Libs\NavList;
|
||||||
|
use DateTime;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\EmailType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\FileType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
|
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
|
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;
|
||||||
|
use Symfony\Component\String\Slugger\SluggerInterface;
|
||||||
|
use Vich\UploaderBundle\Entity\File;
|
||||||
|
|
||||||
class DefaultController extends AbstractController
|
class DefaultController extends AbstractController
|
||||||
{
|
{
|
||||||
@ -56,20 +66,106 @@ class DefaultController extends AbstractController
|
|||||||
],
|
],
|
||||||
'notifications' => $this->msgs,
|
'notifications' => $this->msgs,
|
||||||
'notificationCount' => $this->notificationCount,
|
'notificationCount' => $this->notificationCount,
|
||||||
|
'milesTravelledYTD' => 0,
|
||||||
|
'milesTravelled30Days' => 0,
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Route('/profile', name: 'app_profile')]
|
#[Route('/profile', name: 'app_profile')]
|
||||||
public function profile(#[CurrentUser()] User $user): Response
|
public function profile(
|
||||||
{
|
Request $request,
|
||||||
|
#[CurrentUser()] User $user,
|
||||||
|
SluggerInterface $slugger
|
||||||
|
): Response {
|
||||||
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
|
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
|
||||||
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
|
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
|
||||||
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
|
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
|
||||||
|
|
||||||
$this->navLinks['profile'] = NavList::PRESENT_LINK;
|
$this->navLinks['profile'] = NavList::PRESENT_LINK;
|
||||||
|
|
||||||
|
$form = $this->createFormBuilder($user)
|
||||||
|
->add('name', TextType::class, [
|
||||||
|
'label' => 'Name',
|
||||||
|
'label_attr' => ['class' => 'form-label'],
|
||||||
|
'attr' => ['class' => 'form-control'],
|
||||||
|
])
|
||||||
|
->add('email', EmailType::class, [
|
||||||
|
'label' => 'Email',
|
||||||
|
'label_attr' => ['class' => 'form-label'],
|
||||||
|
'attr' => ['class' => 'form-control'],
|
||||||
|
])
|
||||||
|
->add('password', RepeatedType::class, [
|
||||||
|
'type' => PasswordType::class,
|
||||||
|
'invalid_message' => 'The password fields must match.',
|
||||||
|
'required' => false,
|
||||||
|
'mapped' => false,
|
||||||
|
'first_options' => ['label' => 'Password', 'label_attr' => ['class' => 'form-label']],
|
||||||
|
'second_options' => ['label' => 'Repeat Password', 'label_attr' => ['class' => 'form-label']],
|
||||||
|
])
|
||||||
|
->add('imageName', FileType::class, [
|
||||||
|
'label' => 'Profile Picture',
|
||||||
|
'required' => false,
|
||||||
|
'mapped' => false
|
||||||
|
])
|
||||||
|
->add('submit', SubmitType::class, [
|
||||||
|
'label' => 'Save Profile',
|
||||||
|
'attr' => ['class' => 'btn btn-lg bg-gradient-dark btn-lg w-100 mt-4 mb-0']
|
||||||
|
])
|
||||||
|
->getForm()
|
||||||
|
;
|
||||||
|
|
||||||
|
$form->handleRequest($request);
|
||||||
|
|
||||||
|
if ($form->isSubmitted() && $form->isValid()) {
|
||||||
|
$firstPassword = $form->get('password')['first']->getData();
|
||||||
|
$secondPassword = $form->get('password')['second']->getData();
|
||||||
|
|
||||||
|
if ($firstPassword !== $secondPassword) {
|
||||||
|
$this->addFlash('danger', 'The password fields must match.');
|
||||||
|
return $this->redirectToRoute('app_profile');
|
||||||
|
}
|
||||||
|
|
||||||
|
$plainPassword = $form->get('password')['first']->getData();
|
||||||
|
|
||||||
|
if ($plainPassword) {
|
||||||
|
$user->setPassword(
|
||||||
|
$this->userPasswordHasher->hashPassword(
|
||||||
|
$user,
|
||||||
|
$plainPassword
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$user->setPasswordChanged(new DateTime())
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($form['imageName']->getData()) {
|
||||||
|
/** @var \Symfony\Component\HttpFoundation\File\UploadedFile $file */
|
||||||
|
$file = $form['imageName']->getData();
|
||||||
|
$destination = $this->getParameter('kernel.project_dir').'/public/uploads/user_images/';
|
||||||
|
|
||||||
|
if (!file_exists($destination)) {
|
||||||
|
mkdir($destination, 0775);
|
||||||
|
}
|
||||||
|
|
||||||
|
$originalFilename = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
|
||||||
|
$newFilename = $slugger->slug($originalFilename).'-'.uniqid().'.'.$file->guessExtension();
|
||||||
|
$file->move(
|
||||||
|
$destination,
|
||||||
|
$newFilename
|
||||||
|
);
|
||||||
|
|
||||||
|
$user->setImageName($newFilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->entityManager->persist($user);
|
||||||
|
$this->entityManager->flush();
|
||||||
|
|
||||||
|
return $this->redirectToRoute('app_dashboard');
|
||||||
|
} elseif ($form->isSubmitted() && !$form->isValid()) {
|
||||||
|
$this->addFlash('danger', 'The form contains errors.');
|
||||||
|
}
|
||||||
|
|
||||||
return $this->render(
|
return $this->render(
|
||||||
'internal/profile.html.twig',
|
'internal/profile.html.twig',
|
||||||
array_merge(
|
array_merge(
|
||||||
@ -80,8 +176,16 @@ class DefaultController extends AbstractController
|
|||||||
],
|
],
|
||||||
'notifications' => $this->msgs,
|
'notifications' => $this->msgs,
|
||||||
'notificationCount' => $this->notificationCount,
|
'notificationCount' => $this->notificationCount,
|
||||||
|
'currentUser' => $user,
|
||||||
|
'form' => $form->createView(),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[Route('/uploads/user_images/{imageName}', name: 'app_user_image')]
|
||||||
|
public function displayUserImage(string $imageName): Response
|
||||||
|
{
|
||||||
|
return new BinaryFileResponse($this->getParameter('kernel.project_dir')."/public/uploads/user_images/{$imageName}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,8 @@ class ItineraryController extends AbstractController
|
|||||||
#[Route('/itinerary/report', name: 'app_report_itinerary')]
|
#[Route('/itinerary/report', name: 'app_report_itinerary')]
|
||||||
public function reportItinerary(Request $request, #[CurrentUser()] ?User $user): Response
|
public function reportItinerary(Request $request, #[CurrentUser()] ?User $user): Response
|
||||||
{
|
{
|
||||||
|
$this->navLinks['case_itinerary'] = NavList::PRESENT_LINK;
|
||||||
|
|
||||||
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
|
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
|
||||||
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
|
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
|
||||||
|
|
||||||
@ -76,6 +78,8 @@ class ItineraryController extends AbstractController
|
|||||||
#[Route('/itinerary/map', name: 'app_map_itinerary')]
|
#[Route('/itinerary/map', name: 'app_map_itinerary')]
|
||||||
public function mapItinerary(Request $request, #[CurrentUser()] ?User $user): Response
|
public function mapItinerary(Request $request, #[CurrentUser()] ?User $user): Response
|
||||||
{
|
{
|
||||||
|
$this->navLinks['case_itinerary'] = NavList::PRESENT_LINK;
|
||||||
|
|
||||||
$case = null;
|
$case = null;
|
||||||
if ($request->getPayload()->get('caseId')) {
|
if ($request->getPayload()->get('caseId')) {
|
||||||
$case = $this->entityManager->getRepository(MemberCase::class)->find($request->getPayload()->get('caseId'));
|
$case = $this->entityManager->getRepository(MemberCase::class)->find($request->getPayload()->get('caseId'));
|
||||||
@ -93,8 +97,8 @@ class ItineraryController extends AbstractController
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$map = new Map('default');
|
$map = new Map('default');
|
||||||
$map->center(new Point(39.768502, -86.157918))
|
$map->center(new Point($_ENV['MAP_CENTER_LAT'], $_ENV['MAP_CENTER_LON']))
|
||||||
->zoom(9)
|
->zoom($_ENV['MAP_ZOOM_LEVEL'])
|
||||||
;
|
;
|
||||||
|
|
||||||
$total_distance = 0;
|
$total_distance = 0;
|
||||||
@ -148,7 +152,7 @@ class ItineraryController extends AbstractController
|
|||||||
[
|
[
|
||||||
'breadcrumbs' => [
|
'breadcrumbs' => [
|
||||||
new Breadcrumb($this->generateUrl('app_my_cases'), 'My Cases'),
|
new Breadcrumb($this->generateUrl('app_my_cases'), 'My Cases'),
|
||||||
new Breadcrumb($this->generateUrl('app_itinerary_report'), 'Itinerary Report'),
|
new Breadcrumb($this->generateUrl('app_report_itinerary'), 'Itinerary Report'),
|
||||||
],
|
],
|
||||||
'notifications' => $this->msgs,
|
'notifications' => $this->msgs,
|
||||||
'notificationCount' => $this->notificationCount,
|
'notificationCount' => $this->notificationCount,
|
||||||
|
@ -14,10 +14,13 @@ use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
|||||||
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
||||||
use Symfony\Component\Security\Core\User\UserInterface;
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
use Symfony\Component\Uid\Uuid;
|
use Symfony\Component\Uid\Uuid;
|
||||||
|
use Vich\UploaderBundle\Entity\File;
|
||||||
|
use Vich\UploaderBundle\Mapping\Annotation as Vich;
|
||||||
|
|
||||||
#[ORM\Entity(repositoryClass: UserRepository::class)]
|
#[ORM\Entity(repositoryClass: UserRepository::class)]
|
||||||
#[ORM\UniqueConstraint(name: 'UNIQ_IDENTIFIER_USERNAME', fields: ['username'])]
|
#[ORM\UniqueConstraint(name: 'UNIQ_IDENTIFIER_USERNAME', fields: ['username'])]
|
||||||
#[UniqueEntity(fields: ['username'], message: 'There is already an account with this username')]
|
#[UniqueEntity(fields: ['username'], message: 'There is already an account with this username')]
|
||||||
|
#[Vich\Uploadable]
|
||||||
class User implements UserInterface, PasswordAuthenticatedUserInterface
|
class User implements UserInterface, PasswordAuthenticatedUserInterface
|
||||||
{
|
{
|
||||||
#[ORM\Id]
|
#[ORM\Id]
|
||||||
@ -80,6 +83,15 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
|
|||||||
#[ORM\OneToMany(targetEntity: UserCase::class, mappedBy: 'user')]
|
#[ORM\OneToMany(targetEntity: UserCase::class, mappedBy: 'user')]
|
||||||
private Collection $userCases;
|
private Collection $userCases;
|
||||||
|
|
||||||
|
#[Vich\UploadableField(mapping: 'profile_image', fileNameProperty: 'imageName', size: 'size', mimeType: 'mimeType', originalName: 'originalName', dimensions: 'dimensions')]
|
||||||
|
private ?File $imageFile = null;
|
||||||
|
|
||||||
|
#[ORM\Column(type: Types::STRING, length: 255, nullable: true)]
|
||||||
|
private ?string $imageName = null;
|
||||||
|
|
||||||
|
#[ORM\Column(type: Types::DATETIME_MUTABLE)]
|
||||||
|
private ?\DateTimeInterface $passwordChanged = null;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->userCases = new ArrayCollection();
|
$this->userCases = new ArrayCollection();
|
||||||
@ -351,4 +363,40 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
|
|||||||
|
|
||||||
return $jobs;
|
return $jobs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getImageFile(): ?File
|
||||||
|
{
|
||||||
|
return $this->imageFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setImageFile(?File $imageFile): static
|
||||||
|
{
|
||||||
|
$this->imageFile = $imageFile;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getImageName(): ?string
|
||||||
|
{
|
||||||
|
return $this->imageName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setImageName(?string $imageName): static
|
||||||
|
{
|
||||||
|
$this->imageName = $imageName;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPasswordChanged(): ?\DateTimeInterface
|
||||||
|
{
|
||||||
|
return $this->passwordChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPasswordChanged(\DateTimeInterface $passwordChanged): static
|
||||||
|
{
|
||||||
|
$this->passwordChanged = $passwordChanged;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,10 @@
|
|||||||
<link
|
<link
|
||||||
rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@24,400,0,0"/>
|
rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@24,400,0,0"/>
|
||||||
<!-- CSS Files -->
|
<!-- CSS Files -->
|
||||||
<link id="pagestyle" href="{{ asset('css/material-dashboard.css') }}?v=3.2.0" rel="stylesheet"/> {% block stylesheets %}{% endblock %}
|
<link id="pagestyle" href="{{ asset('css/material-dashboard.css') }}?v=3.2.0" rel="stylesheet"/>
|
||||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/>
|
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/>
|
||||||
|
{% block stylesheets %}{% endblock %}
|
||||||
|
{% block page_css %}{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="bg-gray-200"> {% block body %}{% endblock %}
|
<body class="bg-gray-200"> {% block body %}{% endblock %}
|
||||||
|
@ -83,6 +83,10 @@
|
|||||||
<label for='user_form_rate' class='form-label'>Rate</label>
|
<label for='user_form_rate' class='form-label'>Rate</label>
|
||||||
<input type='number' name='{{ field_name(form.rate) }}' id='user_form_rate' class='form-control' min='0' step='0.01'/>
|
<input type='number' name='{{ field_name(form.rate) }}' id='user_form_rate' class='form-control' min='0' step='0.01'/>
|
||||||
</div>
|
</div>
|
||||||
|
<div class='input-group input-group-outline mb-3'>
|
||||||
|
<label for='user_form_file' class='form-label'>Profile Image</label>
|
||||||
|
<input type='file' name='{{ field_name(form.imageName) }}' id='user_form_file' class='form-control'/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<button type="submit" class="btn btn-lg bg-gradient-dark btn-lg w-100 mt-4 mb-0">Add User</button>
|
<button type="submit" class="btn btn-lg bg-gradient-dark btn-lg w-100 mt-4 mb-0">Add User</button>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<div class="container-fluid py-2">
|
<div class="container-fluid py-2">
|
||||||
<div>
|
<div>
|
||||||
Totals:
|
Totals:
|
||||||
{{ total_distance }}
|
{{ total_distance }}mi
|
||||||
/
|
/
|
||||||
{{ total_duration }}
|
{{ total_duration }}
|
||||||
</div>
|
</div>
|
||||||
|
@ -114,10 +114,5 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="sidenav-footer position-absolute w-100 bottom-0 ">
|
|
||||||
<div class="mx-3">
|
|
||||||
<a class="btn btn-outline-dark mt-4 w-100" href="https://www.creative-tim.com/learning-lab/bootstrap/overview/material-dashboard?ref=sidebarfree" type="button">Documentation</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</aside>
|
</aside>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<div class='ms-md-auto pe-md-3 d-flex align-items-left' id='messages'>
|
<div class='ms-md-auto pe-md-3 d-flex align-items-left' id='messages'>
|
||||||
{% for label, messages in app.flashes %}
|
{% for label, messages in app.flashes %}
|
||||||
{% for message in messages %}
|
{% for message in messages %}
|
||||||
<div class="flash-{{ label }} bg-gradient-info text-white">
|
<div class="flash-{{ label }} bg-gradient-{{ label }} text-white">
|
||||||
{{ message }}
|
{{ message }}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -8,5 +8,56 @@
|
|||||||
|
|
||||||
<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') }}
|
||||||
|
{{ form_start(form) }}
|
||||||
|
|
||||||
|
{{ form_errors(form) }}
|
||||||
|
<div class='container'>
|
||||||
|
<div class='row'>
|
||||||
|
<div class='col' id='profile-image'>
|
||||||
|
<input type='hidden' name='id' value='{{ currentUser.id }}'/>
|
||||||
|
<img class='profile-image' src='{% if currentUser.imageName %}/uploads/user_images/{{ currentUser.imageName }}{% endif %}'/>
|
||||||
|
|
||||||
|
{{ form_row(form.imageName) }}
|
||||||
|
</div>
|
||||||
|
<div class='col'>
|
||||||
|
<div class='input-group input-group-outline mb-3 is-filled'>
|
||||||
|
<label for='profile_form_name' class='form-label'>Name</label>
|
||||||
|
<input type='text' name='{{ field_name(form.name) }}' id='profile_form_name' class='form-control' value='{{ currentUser.name }}'/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class='input-group input-group-outline mb-3 is-filled'>
|
||||||
|
<label for='profile_form_email' class='form-label'>Email</label>
|
||||||
|
<input type='email' name='{{ field_name(form.email) }}' id='profile_form_email' class='form-control' value='{{ currentUser.email }}'/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class='input-group input-group-outline mb-3'>
|
||||||
|
<label for='profile_form_password' class='form-label'>Password</label>
|
||||||
|
<input type='password' name='{{ field_name(form.password.first) }}' id='profile_form_password' class='form-control' autocomplete='new-password'/>
|
||||||
|
</div>
|
||||||
|
<div class='input-group input-group-outline mb-3'>
|
||||||
|
<label for='profile_form_confirmPassword' class='form-label'>Confirm Password</label>
|
||||||
|
<input type='password' name='{{ field_name(form.password.second) }}' id='profile_form_confirmPassword' class='form-control' autocomplete='new-password'/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class='row'>
|
||||||
|
<div class='col text-center'>
|
||||||
|
<div class='input-group input-group-outline mb-3'>
|
||||||
|
{{ form_row(form.submit) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ form_end(form) }}
|
||||||
</main>
|
</main>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block page_css %}
|
||||||
|
<style rel='stylesheet'>
|
||||||
|
.profile-image {
|
||||||
|
width: 300px;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
Reference in New Issue
Block a user