Skip to content

Commit

Permalink
Add user configuration management and localization features (#220)
Browse files Browse the repository at this point in the history
This pull request introduces a new feature for account configuration in
the admin panel, including both backend and frontend changes. The most
important changes include the addition of the `AccountController` class,
updates to the admin routes, and the creation of a new view for account
configuration.

Backend changes:
* Added `AccountController` class to handle account configuration in
`app/src/app/Controllers/Admin/AccountController.php`. This includes
methods for displaying and updating user account information.
* Updated `app/src/routes/admin.php` to include new routes for account
configuration, mapping to the `AccountController`.
[[1]](diffhunk://#diff-b885f3c2c2423c8e57d08c9eccf34a87bc5af3773a6803afeaf7406b68b7d3daR30-R34)
[[2]](diffhunk://#diff-b885f3c2c2423c8e57d08c9eccf34a87bc5af3773a6803afeaf7406b68b7d3daR305-R312)

Frontend changes:
* Created a new view for account configuration in
`app/src/app/Views/Admin/AccountConfig/AccountConfig.php`, which
includes forms for updating personal information and changing the
password.
* Modified `app/src/app/Layouts/Admin/AdminLayout.php` to add a link to
the new account configuration page in the admin menu.
* Added a JavaScript function `checkChanges` in
`app/src/public/assets/js/app.js` to enable the save button when changes
are detected in the account configuration form.
  • Loading branch information
0x1026 authored Dec 18, 2024
2 parents 0340caf + bd320f9 commit 85c0e39
Show file tree
Hide file tree
Showing 6 changed files with 275 additions and 1 deletion.
83 changes: 83 additions & 0 deletions app/src/app/Controllers/Admin/AccountController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php

namespace App\Controllers\Admin;

use App\Core\Session;
use App\Core\View;
use App\Models\User;

class AccountController
{
public function index($queryParams)
{

$user = User::find(Session::get('user')['id']);
View::render([
'view' => 'Admin/AccountConfig/AccountConfig',
'title' => 'Configuración de cuenta',
'layout' => 'Admin/AdminLayout',
'data' => [
'user' => $user
]
]);
}


public function update($id, $postData)
{
$user = User::find(id: $id);

if (!$user) {
Session::set('error', 'Usuario no encontrado');
header('Location: /admin/configuration');
exit;
}

// save the new data
$user->name = $postData['name'];
$user->surname = $postData['surname'];

// detect password changes
if (strlen($postData['current_password']) > 0) {



if (!password_verify($postData['current_password'], $user->password)) {
Session::set('error', 'Contraseña incorrecta');
header('Location: /admin/configuration');
exit;
}


if (empty($postData['password']) || empty($postData['password_confirmation'])) {
Session::set('error', 'Completa los campos');
header('Location: /admin/configuration');
exit;
}


if ($postData['password'] !== $postData['password_confirmation']) {
Session::set('error', 'Las contraseñas no coinciden');
header('Location: /admin/configuration');
exit;
}

$user->password = password_hash($postData['password'], PASSWORD_BCRYPT);
}

$user->save();



Session::set('user', [
'id' => $user->getId(),
'name' => $user->name,
'surname' => $user->surname,
'email' => $user->email,
'role' => $user->role,
]);

Session::set('success', 'Usuario y/o contraseña actualizados correctamente');
header('Location: /admin/configuration');
}
}
1 change: 1 addition & 0 deletions app/src/app/Controllers/Auth/AuthController.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public function login($postData)
'surname' => $user->surname[0],
'email' => $user->email,
'role' => $user->role,

]);
if ($user->role === 0) {
header('Location: /customer');
Expand Down
2 changes: 1 addition & 1 deletion app/src/app/Layouts/Admin/AdminLayout.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class="block text-gray-700"><?= $_SESSION['user']['name'] . ' ' . $_SESSION['use
class="hidden absolute right-0 z-10 mt-2 w-56 origin-top-right rounded-md bg-white shadow-lg ring-1 ring-black/5 focus:outline-none"
role="menu" aria-orientation="vertical" aria-labelledby="menu-button" tabindex="-1">
<div class="py-1" role="none">
<a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:text-gray-800"
<a href="/admin/configuration" class="block px-4 py-2 text-sm text-gray-700 hover:text-gray-800"
role="menuitem" tabindex="-1" id="menu-item-0">Configuración de la cuenta</a>
<a href="#" class="block px-4 py-2 text-sm text-gray-700" role="menuitem" tabindex="-1"
id="menu-item-1">Soporte</a>
Expand Down
135 changes: 135 additions & 0 deletions app/src/app/Views/Admin/AccountConfig/AccountConfig.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
<?php
use App\Core\Session;

?>


<div class="mt-8">
<h1 class="text-5xl font-semibold">Configuración</h1>
<p class="text-md text-gray-600 mt-3">Aquí podrás configurar tu cuenta.</p>
<article class="mb-10">
<h2 class="text-3xl font-semibold col-span-4 mb-5 mt-8">Informacíon personal</h2>

<?php if (Session::has('error')) { ?>
<div class="bg-red-500 text-white px-4 py-3 rounded-lg mb-6" role="alert">
<strong class="font-bold">Error: </strong>
<span><?= htmlspecialchars(Session::get('error')); ?></span>
</div>
<?php } ?>

<form action="/admin/configuration/<?= $user->getId() ?>/update" method="POST" class="grid grid-cols-4 gap-4">
<!-- user info -->
<div class="flex flex-col justify-between h-full">
<div class="flex flex-col gap-4">
<div class="flex flex-col">
<label for="first-name" class="text-sm font-semibold text-gray-700">First Name</label>
<input
type="text"
id="first-name"
class="mt-1 px-3 py-2 border rounded-md text-gray-600 bg-gray-100"
value="<?= $user->name ?>"
data-original-value="<?= $user->name ?>"
name="name"
oninput="checkChanges()">
</div>

<div class="flex flex-col">
<label for="dni" class="text-sm font-semibold text-gray-700">DNI</label>
<input
type="text"
id="dni"
class="mt-1 px-3 py-2 border rounded-md text-gray-600 bg-gray-100 cursor-not-allowed"
value="<?= $user->dni ?>"
data-original-value="<?= $user->dni ?>"
oninput="checkChanges()"
disabled>
</div>
</div>
</div>

<div class="flex flex-col justify-between h-full">
<div class="flex flex-col gap-4">
<div class="flex flex-col">
<label for="surname" class="text-sm font-semibold text-gray-700">Surname</label>
<input
type="text"
id="surname"
class="mt-1 px-3 py-2 border rounded-md text-gray-600 bg-gray-100"
value="<?= $user->surname ?>"
data-original-value="<?= $user->surname ?>"
name="surname"
oninput="checkChanges()">
</div>

<div class="flex flex-col">
<label for="email" class="text-sm font-semibold text-gray-700">Email</label>
<input
type="text"
id="email"
class="mt-1 px-3 py-2 border rounded-md text-gray-600 bg-gray-100 cursor-not-allowed"
value="<?= $user->email ?>"
data-original-value="<?= $user->email ?>"
oninput="checkChanges()"
disabled>
</div>
</div>
</div>

<!-- avatar info -->
<div class="flex flex-col justify-between h-full justify-center items-center">
<img class="h-20 w-20 rounded-full" src="/assets/images/avatar.png" alt="User Avatar">
<div class="flex flex-col items-center mt-3">
<button type="button" class="px-3 py-1.5 bg-blue-500 text-white rounded-md hover:bg-blue-600 transition">
Cambiar imagen
</button>
<p class="text-xs text-gray-600 mt-1.5">JPG or PNG. 1MB max.</p>
</div>
</div>

<!-- password change info -->
<h3 class="text-3xl font-semibold col-span-4 mt-12">Cambiar contraseña</h3>

<div class="flex flex-col">
<label for="current-password" class="text-sm font-semibold text-gray-700">Contraseña actual</label>
<input
type="password"
id="current-password"
name="current_password"
class="mt-1 px-3 py-2 border rounded-md text-gray-600 bg-gray-100"
oninput="checkChanges()">
</div>
<div class="flex flex-col">
<label for="new-password" class="text-sm font-semibold text-gray-700">Nueva contraseña</label>
<input
type="password"
id="new-password"
name="password"
class="mt-1 px-3 py-2 border rounded-md text-gray-600 bg-gray-100"
oninput="checkChanges()">
</div>
<div class="flex flex-col">
<label for="confirm-password" class="text-sm font-semibold text-gray-700">Confirmar contraseña</label>
<input
type="password"
id="confirm-password"
name="password_confirmation"
class="mt-1 px-3 py-2 border rounded-md text-gray-600 bg-gray-100"
oninput="checkChanges()">
</div>




<!-- save button -->
<div class="col-span-4 flex justify-end">
<button
id="button-save"
type="submit"
class="bg-gray-400 text-gray-500 py-2 px-4 rounded-lg cursor-not-allowed disabled:bg-gray-400 disabled:text-white"
disabled>
Guardar cambios
</button>
</div>
</form>
</article>
</div>
41 changes: 41 additions & 0 deletions app/src/public/assets/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -379,3 +379,44 @@ function applySelection() {
// Cierra el modal
closeModal();
}

// func to active the button if detect changes in the form
function checkChanges() {
const inputs = document.querySelectorAll("input");
const button = document.getElementById("button-save");

let changesDetected = false;

inputs.forEach((input) => {
const originalValue = input.getAttribute("data-original-value");
if (input.value !== originalValue) {
changesDetected = true;
}
});

if (changesDetected) {
button.disabled = false;
button.classList.remove(
"bg-gray-400",
"cursor-not-allowed",
"text-gray-500"
);
button.classList.add(
"bg-green-500",
"hover:bg-green-600",
"text-white"
);
} else {
button.disabled = true;
button.classList.add(
"bg-gray-400",
"cursor-not-allowed",
"text-gray-500"
);
button.classList.remove(
"bg-green-500",
"hover:bg-green-600",
"text-white"
);
}
}
14 changes: 14 additions & 0 deletions app/src/routes/admin.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?php

use App\Controllers\Admin\AccountController;
use App\Controllers\Admin\ContractController;
use App\Controllers\Admin\DashboardController;
use App\Controllers\Admin\ElementController;
Expand All @@ -26,6 +27,11 @@
'method' => 'index',
'middlewares' => [AdminMiddleware::class],
],
'/admin/configuration' => [
'controller' => AccountController::class,
'method' => 'index',
'middlewares' => [AdminMiddleware::class],
],
// === Users GET Routes
'/admin/users' => [
'controller' => UserController::class,
Expand Down Expand Up @@ -296,5 +302,13 @@
'method' => 'update',
'middlewares' => [AdminMiddleware::class],
],

// === Config POST Routes

'/admin/configuration/:id/update' => [
'controller' => AccountController::class,
'method' => 'update',
'middlewares' => [AdminMiddleware::class],
],
],
];

0 comments on commit 85c0e39

Please sign in to comment.