Admin panel fixed

samuel
samuel 1 week ago
parent 6d563bd831
commit a02b25f61b

@ -40,8 +40,9 @@ security:
access_control:
- { path: ^/login, roles: PUBLIC_ACCESS }
- { path: ^/register, roles: PUBLIC_ACCESS }
- { path: ^/, roles: ROLE_USER }
- { path: ^/admin, roles: ROLE_ADMIN }
- { path: ^/, roles: ROLE_USER }

@ -0,0 +1,90 @@
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f4f6f8;
color: #333;
margin: 2rem auto;
max-width: 800px;
padding: 1rem;
}
h1 {
color: #2c3e50;
font-size: 2rem;
margin-bottom: 1rem;
text-align: center;
}
h2 {
color: #34495e;
font-size: 1.4rem;
margin-top: 2rem;
margin-bottom: 1rem;
border-bottom: 2px solid #ccc;
padding-bottom: 0.2rem;
}
section {
background: white;
border-radius: 8px;
padding: 1.5rem;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
margin-bottom: 1.5rem;
}
ul#user-list {
list-style: none;
padding: 0;
}
#user-list li {
background: #ecf0f1;
margin-bottom: 0.5rem;
padding: 0.8rem 1rem;
border-radius: 6px;
display: flex;
justify-content: space-between;
align-items: center;
}
#user-list li button {
background-color: #e74c3c;
color: white;
border: none;
padding: 6px 12px;
border-radius: 4px;
cursor: pointer;
font-size: 0.9rem;
}
#user-list li button:hover {
background-color: #c0392b;
}
form#add-user-form {
display: flex;
flex-direction: column;
gap: 0.8rem;
}
form#add-user-form input,
form#add-user-form select {
padding: 0.6rem;
border: 1px solid #bdc3c7;
border-radius: 4px;
font-size: 1rem;
}
form#add-user-form button {
background-color: #3498db;
color: white;
border: none;
padding: 0.7rem;
border-radius: 4px;
font-size: 1rem;
cursor: pointer;
}
form#add-user-form button:hover {
background-color: #2980b9;
}

@ -13,7 +13,7 @@ use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
#[Route('/admin', name: 'admin_users_')]
#[Route('/admin', name: 'admin_')]
#[IsGranted('ROLE_ADMIN')]
class AdminController extends AbstractController
{
@ -26,7 +26,13 @@ class AdminController extends AbstractController
$this->passwordHasher = $passwordHasher;
}
#[Route('/users', name: 'list', methods: ['GET'])]
#[Route('', name: 'admin_dashboard')]
public function dashboard(): Response
{
return $this->render('admin/index.html.twig');
}
#[Route('/users', name: 'users_list', methods: ['GET'])]
public function getUserById(UserRepository $userRepository): JsonResponse
{
$users = $userRepository->findAll();
@ -71,4 +77,22 @@ class AdminController extends AbstractController
return $this->json(['message' => 'User created successfully', 'id' => $user->getId()], Response::HTTP_CREATED);
}
#[Route('/users/delete/{id}', name: 'delete_user', methods: ['DELETE'])]
public function deleteUser(int $id): JsonResponse
{
$user = $this->entityManager->getRepository(User::class)->find($id);
if (!$user) {
return $this->json(['error' => 'User not found'], Response::HTTP_NOT_FOUND);
}
foreach ($user->getEmojis() as $userEmoji) {
$this->entityManager->remove($userEmoji);
}
$this->entityManager->remove($user);
$this->entityManager->flush();
return $this->json(['message' => 'User and related data deleted successfully'], Response::HTTP_OK);
}
}

@ -38,7 +38,6 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
public function __construct() {
$this->emojis = new ArrayCollection();
$this->emoji = new ArrayCollection();
}
public function getId(): ?int
@ -58,19 +57,12 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
return $this;
}
/**
* A visual identifier that represents this user.
*
* @see UserInterface
*/
public function getUserIdentifier(): string
{
return (string) $this->username;
}
/**
* @see UserInterface
*/
public function getRoles(): array
{
$roles = $this->roles;
@ -87,9 +79,6 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
return $this;
}
/**
* @see PasswordAuthenticatedUserInterface
*/
public function getPassword(): string
{
return $this->password;
@ -103,9 +92,9 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
}
public function getEmojis(): Collection
{
return $this->emojis;
}
{
return $this->emojis;
}
/**
* @see UserInterface
@ -115,34 +104,4 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
// If you store any temporary, sensitive data on the user, clear it here
// $this->plainPassword = null;
}
/**
* @return Collection<int, UserEmojis>
*/
public function getEmoji(): Collection
{
return $this->emoji;
}
public function addEmoji(UserEmojis $emoji): static
{
if (!$this->emoji->contains($emoji)) {
$this->emoji->add($emoji);
$emoji->setUser($this);
}
return $this;
}
public function removeEmoji(UserEmojis $emoji): static
{
if ($this->emoji->removeElement($emoji)) {
// set the owning side to null (unless already changed)
if ($emoji->getUser() === $this) {
$emoji->setUser(null);
}
}
return $this;
}
}

@ -0,0 +1,84 @@
{% extends 'base.html.twig' %}
{% block stylesheets %}
<link rel="stylesheet" href="{{ asset('css/admin.css') }}">
{% endblock %}
{% block title %}Admin - Gestion des utilisateurs{% endblock %}
{% block body %}
<h1>🔐 Admin - Gestion des utilisateurs</h1>
<section>
<h2>👥 Liste des utilisateurs</h2>
<ul id="user-list"></ul>
</section>
<section>
<h2> Ajouter un utilisateur</h2>
<form id="add-user-form">
<input type="text" name="username" placeholder="Nom d'utilisateur" required>
<input type="password" name="password" placeholder="Mot de passe" required>
<select name="role">
<option value="ROLE_USER">Utilisateur</option>
<option value="ROLE_ADMIN">Administrateur</option>
</select>
<button type="submit">Ajouter</button>
</form>
</section>
<script>
async function fetchUsers() {
const response = await fetch('/admin/users');
const users = await response.json();
const list = document.getElementById('user-list');
list.innerHTML = '';
users.forEach(user => {
const item = document.createElement('li');
item.innerHTML = `
<strong>${user.username}</strong> - Rôles: ${user.roles.join(', ')}
<button onclick="deleteUser(${user.id})">🗑️ Supprimer</button>
`;
list.appendChild(item);
});
}
async function deleteUser(id) {
if (!confirm('Confirmer la suppression de cet utilisateur ?')) return;
const response = await fetch(`/admin/users/delete/${id}`, {
method: 'DELETE',
});
if (response.ok) {
alert('Utilisateur supprimé.');
fetchUsers();
} else {
alert('Erreur lors de la suppression.');
}
}
document.getElementById('add-user-form').addEventListener('submit', async function (e) {
e.preventDefault();
const form = e.target;
const username = form.username.value;
const password = form.password.value;
const role = form.role.value;
const response = await fetch('/admin/users/add', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password, roles: [role] }),
});
if (response.ok) {
alert('Utilisateur ajouté avec succès.');
form.reset();
fetchUsers();
} else {
const data = await response.json();
alert('Erreur: ' + (data.error || 'Inconnue'));
}
});
fetchUsers();
</script>
{% endblock %}

@ -9,9 +9,9 @@
{% block body %}
{% if app.user %}
<div class="logout-container">
<span style="margin-right: 20px; text-decoration: underline">Connecté en tant que <strong>{{ app.user.username }}</strong></span>
<span style="margin-right: 20px; ">Connecté en tant que <strong>{{ app.user.username }}</strong></span>
<form action="{{ path('app_logout') }}" method="post" style="display: inline;">
<button type="submit" class="btn btn-logout">🚪 Se déconnecter</button>
<button type="submit" class="btn btn-logout">🚪Déconnexion</button>
</form>
</div>

Loading…
Cancel
Save