Edició de dades de l'usuari

De Wiki personal d'en Guillem Serrat

Edició de les dades de l'usuari

Qualsevol usuari de l'aplicatiu pot modificar les seves dades personals i la seva contrasenya gràcies al formulari d'edició de dades de l'usuari.

Aquest formulari mostra les dades actuals dins dels camps d'entrada per fer més fàcil la modificació d'aquestes, tant per part de l'usuari com per part de la BD

Inicialització de la sessió i connexió a la BD

Sempre que es treballa amb sessions, el primer que hem de fer és iniciar-la abans d'escriure el codi HTML

session_start();

A més, hem de requerir el fitxer amb les funcions i una connexió a la BD. En aquest cas, com hem de modificar dades de l'usuari i per tant actualitzar registres de la BD farem servir la connexió d'escriptura.

require 'funcions.php';
require './connexioBD/connexioRW.php';

Requerir autenticació

Per accedir a aquesta pàgina, és imperatiu que l'usuari estigui autenticat, en cas contrari no hi pot accedir.

Per verificar que l'usuari està autenticat, farem servir la funció requerir_autenticacio

// Requerir autenticació per accedir a la pàgina
requerir_autenticacio();

Formulari d'edició de dades

Recuperació de les dades de l'usuari a la BD

El formulari d'edició de dades mostra les dades actuals dins dels camps. És a dir, al camp "nom d'usuari" enlloc de sortir en blanc sortirà el nom d'usuari actual. Així l’usuari sap quins valors hi havien i pot modificar-los més fàcilment, a més que a nivell de gestió de BD, podrem fer un update de tot sense haver de comprovar quin camp ha canviat l’usuari, fent-ho més senzill.

Per això, recuperarem la ID de l'usuari a partir de la sessió

// 2. Obtenir ID de l'usuari autenticat
$usuari_id = $_SESSION['usuari']['id'];

I realitzarem una consulta SQL per recuperar les seves dades personals. En cas que la consulta no retorni res, voldrà dir que l'usuari no existeix

// 3. Obtenir les dades de l'usuari try {

   $stmt = $pdo->prepare("
   SELECT nom_usuari, nom_complet, email, telefon, ciutat, edat, contrasenya, email_verificat
   FROM usuaris
   WHERE id = ?
   ");
   $stmt->execute([$usuari_id]);
   $usuari = $stmt->fetch();

} catch (PDOException $e) {

   $error = "No s'ha pogut recuperar les dades de l'usuari. Motiu: " . $e->getMessage();

}

// En cas que la consulta no retorni res, voldrà dir que no hi ha cap usuari amb aquella ID if (!$usuari) {

   die("Usuari no trobat");

}

Mostra del formulari amb els valors predefinits

Un cop obtingudes les dades, en el formulari definirem l'argument "value" dels inputs com al resultat de la consulta SQL, excepte per les contrasenyes, per motius obvis

<form method="post" class="edit-card">
    <div class="form-section">
        <h3>Dades personals</h3>
        <div class="input-grid">
            <div class="input-group">
                <label>Nom d'usuari</label>
                <input type="text" name="nom_usuari" value="<?= htmlspecialchars($usuari['nom_usuari']) ?>" required>
            </div>
            <div class="input-group">
                <label>Nom complet</label>
                <input type="text" name="nom_complet" value="<?= htmlspecialchars($usuari['nom_complet']) ?>" required>
            </div>
            <div class="input-group full-width">
                <label>Email <span class="info-tag">(Es requerirà nova verificació si es canvia)</span></label>
                <input type="email" name="email" value="<?= htmlspecialchars($usuari['email']) ?>" required>
            </div>
            <div class="input-group">
                <label>Telèfon</label>
                <input type="text" name="telefon" value="<?= htmlspecialchars($usuari['telefon']) ?>" required>
            </div>
            <div class="input-group">
                <label>Ciutat</label>
                <input type="text" name="ciutat" value="<?= htmlspecialchars($usuari['ciutat']) ?>" required>
            </div>
            <div class="input-group">
                <label>Edat</label>
                <input type="number" name="edat" min="0" max="120" value="<?= htmlspecialchars($usuari['edat']) ?>" required>
            </div>
        </div>
    </div>

    <hr class="divider">

    <div class="form-section">
        <h3>Seguretat <span class="sub-title">(Opcional)</span></h3>
        <div class="input-group">
            <label>Contrasenya actual</label>
            <input type="password" name="contrasenya_actual">
        </div>
        <div class="input-grid">
            <div class="input-group">
                <label>Nova contrasenya</label>
                <input type="password" name="nova_contrasenya">
            </div>
            <div class="input-group">
                <label>Confirmar nova contrasenya</label>
                <input type="password" name="confirmar_contrasenya">
            </div>
        </div>
    </div>

    <div class="form-actions">
        <a href="privada.php" class="btn-cancel">Tornar enrere</a>
        <button type="submit" class="btn-submit">Desar canvis</button>
    </div>
</form>

La visualització del formulari serà com la següent:

Actualització de dades

Recuperació de les dades del formulari

Un cop s'ha respost el formulari, recuperarem tots els valors de les entrades

$nom_usuari  = trim($_POST['nom_usuari']);
$nom_complet = trim($_POST['nom_complet']);
$email       = trim($_POST['email']);
$telefon     = trim($_POST['telefon']);
$ciutat      = trim($_POST['ciutat']);
$edat        = trim($_POST['edat']);
$contrasenya_actual    = $_POST['contrasenya_actual'];
$nova_contrasenya      = $_POST['nova_contrasenya'];
$confirmar_contrasenya = $_POST['confirmar_contrasenya'];

Determinar si camps únics han canviat

Seguidament, a partir d'aquests valors haurem de comprovar si els següents camps han estat modificats:

  • Nom d'usuari
  • Email
  • Telèfon
  • Contrasenya

En cas del nom d'usuari, email i telèfon, hem de recordar que són valors únics dins la BD i per tant s'ha de realitzar unes comprovacions a part per assegurar que el nou valor no està ja registrat, a diferència de les demés dades que poden estar repetides

En cas de la contrasenya, al no estar obligats a canviar-la, no és un camp requerit i per tant es pot deixar buit. Per això, en cas de voler modificar una contrasenya, ens hem d'assegurar que el camp no estigui buit, a més de fer altres comprovacions a nivell de contrasenya.

// Determinar si l'email, el telèfon o el nom d'usuari ha canviat
$email_ha_canviat = ($email !== $usuari['email']);
$telefon_ha_canviat = ($telefon !== $usuari['telefon']);
$usuari_ha_canviat = ($nom_usuari !== $usuari['nom_usuari']);

// Determinem si volem canviar la contrasenya mirant si tots els camps estan plens
$canvi_contrasenya = ( // Si hi ha algun camp buit = fals = NO es vol canviar la contrasenya
    $contrasenya_actual !== '' ||
    $nova_contrasenya !== '' ||
    $confirmar_contrasenya !== ''
);

Verificacions bàsiques

A continuació es faran unes validacions bàsiques que sempre s'executaran. Aquestes validacions són les mateixes que al registre d'usuaris.

// Validacions bàsiques
// Verifiquem que cap camp estigui buit
if ($nom_usuari === '' || $nom_complet === '' || $email === '' || $ciutat === '' || $telefon === '' || $edat === '') {
    $error = "Els camps obligatoris no poden estar buits";
} 

// Verifiquem que l'email sigui realment un email
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    $error = "L'email introduït no és vàlid";
} 

// Verifiquem que el telèfon sigui vàlid
if (strlen($telefon) != 9) {
    $error = "Telèfon no vàlid";
}

// Verifiquem que la ciutat sigui vàlida
if (strlen($ciutat) > 100) {
    $error = "Ciutat no vàlida";
}

// Verifiquem que l'edat sigui vàlida
if ($edat < 18 || $edat > 120) {
    $error = "Edat no vàlida";
}

Verificacions de camps únics

A continuació, depenent de si s'ha modificat el camp únic o no, realitzarem una consulta SQL on cercarem un usuari a la BD amb el mateix valor del camp comprovat. En cas que es retorni algun resultat, voldrà dir que ja hi ha un usuari amb aquella informació registrada

// Validar si el mail ja està registrat per qualsevol altre usuari
if ($email_ha_canviat && $error === '') {
    $stmt_check = $pdo->prepare("SELECT id FROM usuaris WHERE email = ?"); // Realitzem una consulta on busquem un usuari amb el mateix email
    $stmt_check->execute([$email]); // Si retorna algun resultat, significa que el email ja està a la BD
    if ($stmt_check->fetch()) {
        $error = "Aquest email ja està registrat per un altre usuari";
    }
}

// Validar si el telèfon ja està registrat per qualsevol altre usuari
if ($telefon_ha_canviat && $error === '') {
    $stmt_tel = $pdo->prepare("SELECT id FROM usuaris WHERE telefon = ?"); // Realitzem una consulta on busquem un usuari amb el mateix telèfon
    $stmt_tel->execute([$telefon]);
    if ($stmt_tel->fetch()) { // Si retorna algun resultat, significa que el telèfon ja està a la BD
        $error = "Aquest telèfon ja està registrat"; 
    }
}

// Validar si el nom d'usuari ja està registrat per qualsevol altre usuari
if ($usuari_ha_canviat && $error === '') {
    $stmt_user = $pdo->prepare("SELECT id FROM usuaris WHERE nom_usuari = ?"); // Realitzem una consulta on busquem un usuari amb el mateix nom d'usuari
    $stmt_user->execute([$nom_usuari]); // Si retorna algun resultat, significa que el nom d'usuari ja està a la BD
    if ($stmt_user->fetch()) { 
        $error = "Aquest nom d'usuari ja està registrat"; 
    }
}

En cas de verificar la contrasenya, verificarem:

  • Que els tres camps tenen algun valor
  • Que la contrasenya actual sigui correcta, amb la funcio verificar_contrasenya
  • Que les noves contrasenyes coincideixin en els dos camps
// En cas que volguem canviar la contrasenya, farem les següent validacions
if ($canvi_contrasenya && $error === '') {
    if ($contrasenya_actual === '' || $nova_contrasenya === '' || $confirmar_contrasenya === '') { // Revisem que tots els camps estiguin plens
        $error = "Has d'omplir tots els camps de contrasenya";
    } elseif (!verificar_contrasenya($contrasenya_actual, $usuari['contrasenya'])) { // Que la contrasenya de l'usuari sigui correcte
        $error = "La contrasenya actual no és correcta";
    } elseif ($nova_contrasenya !== $confirmar_contrasenya) { // Que la nova contrasenya i la seva verificació coincideixin
        $error = "Les noves contrasenyes no coincideixen";
    }
}

Inserció de dades a la BD

A cada pas de les verificacions anteriors, en cas d'haver-hi algun error es registrarà dins la variable $error, que servirà per imprimir-ho i que l'usuari sigui conscient i verificar si és correcte actualitzar les dades o no

// Si s'ha superat totes les validacions
if ($error === '') {

Un cop verificat que no hi hagi hagut cap error, inserirem les dades obtingudes del formulari a la taula usuaris. Abans, definirem l'estat de verificació de l'email. En cas que l'email hagi estat modificat, establirem la verificació a "no", si no ho ha estat, deixarem l'estat de verificació actual

if ($email_ha_canviat) { // Si l'email ha canviat
    $nou_estat_verificacio = 'no'; // Definirem que l'estat de verificació és no
} else { // Si l'email no ha canviat
    $nou_estat_verificacio = $usuari['email_verificat']; // Valor original de l'usuari
}

En cas que s'hagi modificat la contrasenya, realitzarem un update on encriptarem al contrasenya amb la funció encriptar_contrasenya i actualitzarem no només les dades personals sinó també la contrasenya. També afegirem una acció indicant que la contrasenya s'ha restablert. En cas que la contrasenya no s'hagi modificat, únicament actualitzarem les dades personals amb les dades del formulari

if ($canvi_contrasenya) { // Si canviem la contrasenya
    $hash = encriptar_contrasenya($nova_contrasenya);
    $stmt = $pdo->prepare("
        UPDATE usuaris 
        SET nom_usuari = ?, nom_complet = ?, email = ?, telefon = ?, ciutat = ?, edat = ?, contrasenya = ?, email_verificat = ?
        WHERE id = ?
    ");
    // Fem un Update de tots els camps de la BD: Dades personals + contrasenya
    $stmt->execute([$nom_usuari, $nom_complet, $email, $telefon, $ciutat, $edat, $hash, $nou_estat_verificacio, $usuari_id]);
    registrar_activitat($pdo, $usuari_id, 'restablir-contrasenya');
} else { // Si no canviem la contrasenya
    $stmt = $pdo->prepare("
        UPDATE usuaris 
        SET nom_usuari = ?, nom_complet = ?, email = ?, telefon = ?, ciutat = ?, edat = ?, email_verificat = ?
        WHERE id = ?
    ");
    // Únicament actualitzem les dades personals
    $stmt->execute([$nom_usuari, $nom_complet, $email, $telefon, $ciutat, $edat, $nou_estat_verificacio, $usuari_id]);
}

Un cop actualitzades les dades a la BD, actualitzarem la sessió i les dades que es mostraran al formulari

// Actualizar sessió $_SESSION['usuari']['nom_usuari'] = $nom_usuari; $_SESSION['usuari']['nom_complet'] = $nom_complet; $_SESSION['usuari']['email'] = $email;

// Actualitzar les dades modificades obtenides a la consulta per mostrar-les al formulari $usuari['nom_usuari'] = $nom_usuari; $usuari['nom_complet'] = $nom_complet; $usuari['email'] = $email; $usuari['telefon'] = $telefon; $usuari['ciutat'] = $ciutat; $usuari['edat'] = $edat;

Si hem modificat el correu electrònic, esborrarem qualsevol codi de verificació que s’hagi desat a la sessió i mostrarem un missatge diferent al genèric, recordant que s’ha de tornar a verificar el correu electrònic.

if ($email_ha_canviat) { // Si hem canviat l'email

   // Borrar codi de verificació
   unset($_SESSION['codi_verificacio']);
   $correcte = "Perfil actualitzat. Com que has canviat l'email, l'hauràs de tornar a verificar.";

} else {

   $correcte = "Perfil actualitzat correctament";

}

Per últim, registrarem una acció d'usuari on indicarem que s'ha modificat el perfil

registrar_activitat($pdo, $usuari_id, 'editar-perfil');

Mostra de missatges d'error o èxit

En cas que l'usuari cometi algun error o completi l'operació amb èxit, es mostrarà un missatge a la part superior del formulari

<?php if ($error): // En cas que hi hagi un error es mostrarà?>
    <div class="alert alert-error"><?= htmlspecialchars($error) ?></div>
<?php endif; ?>

<?php if ($correcte): // En cas que hi hagi un missatge d'èxit es mostrarà?>
    <div class="alert alert-success"><?= htmlspecialchars($correcte) ?></div>
<?php endif; ?>

Un exemple de missatge d'error es visualitzaria de la següent forma


Un exemple de missatge d'èxit es visualitzaria de la següent forma

I en cas d'editar el correu electrònic es visualitzaria de la següent forma

Codi complet

<?php
date_default_timezone_set('Europe/Madrid');

session_start();
require 'funcions.php';
require './connexioBD/connexioRW.php';

// 1. Verifiquem que l'usuari està autenticat
requerir_autenticacio();

// Inicialització de les variables de missatge
$error = '';
$correcte = '';

// 2. Obtenir ID de l'usuari autenticat
$usuari_id = $_SESSION['usuari']['id'];

// 3. Obtenir les dades de l'usuari 
try {
    $stmt = $pdo->prepare("
    SELECT nom_usuari, nom_complet, email, telefon, ciutat, edat, contrasenya, email_verificat
    FROM usuaris
    WHERE id = ?
    ");
    $stmt->execute([$usuari_id]);
    $usuari = $stmt->fetch();
} catch (PDOException $e) {
    $error = "No s'ha pogut recuperar les dades de l'usuari. Motiu: " . $e->getMessage();
}  

// En cas que la consulta no retorni res, voldrà dir que no hi ha cap usuari amb aquella ID
if (!$usuari) {
    die("Usuari no trobat");
}

// 4. Processar formulari
if ($_SERVER['REQUEST_METHOD'] === 'POST') {

    $nom_usuari  = trim($_POST['nom_usuari']);
    $nom_complet = trim($_POST['nom_complet']);
    $email       = trim($_POST['email']);
    $telefon     = trim($_POST['telefon']);
    $ciutat      = trim($_POST['ciutat']);
    $edat        = trim($_POST['edat']);
    $contrasenya_actual    = $_POST['contrasenya_actual'];
    $nova_contrasenya      = $_POST['nova_contrasenya'];
    $confirmar_contrasenya = $_POST['confirmar_contrasenya'];

    // Determinar si l'email, el telèfon o el nom d'usuari ha canviat
    $email_ha_canviat = ($email !== $usuari['email']);
    $telefon_ha_canviat = ($telefon !== $usuari['telefon']);
    $usuari_ha_canviat = ($nom_usuari !== $usuari['nom_usuari']);

    // Determinem si volem canviar la contrasenya mirant si tots els camps estan plens
    $canvi_contrasenya = ( // Si hi ha algun camp buit = fals = NO es vol canviar la contrasenya
        $contrasenya_actual !== '' ||
        $nova_contrasenya !== '' ||
        $confirmar_contrasenya !== ''
    );

    // Validacions bàsiques
    // Verifiquem que cap camp estigui buit
    if ($nom_usuari === '' || $nom_complet === '' || $email === '' || $ciutat === '' || $telefon === '' || $edat === '') {
        $error = "Els camps obligatoris no poden estar buits";
    } 

    // Verifiquem que l'email sigui realment un email
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $error = "L'email introduït no és vàlid";
    } 

    // Verifiquem que el telèfon sigui vàlid
    if (strlen($telefon) != 9) {
        $error = "Telèfon no vàlid";
    }

    // Verifiquem que la ciutat sigui vàlida
    if (strlen($ciutat) > 100) {
        $error = "Ciutat no vàlida";
    }

    // Verifiquem que l'edat sigui vàlida
    if ($edat < 18 || $edat > 120) {
        $error = "Edat no vàlida";
    }

    // Validar si el mail ja està registrat per qualsevol altre usuari
    if ($email_ha_canviat && $error === '') {
        $stmt_check = $pdo->prepare("SELECT id FROM usuaris WHERE email = ?"); // Realitzem una consulta on busquem un usuari amb el mateix email
        $stmt_check->execute([$email]); // Si retorna algun resultat, significa que el email ja està a la BD
        if ($stmt_check->fetch()) {
            $error = "Aquest email ja està registrat per un altre usuari";
        }
    }

    // Validar si el telèfon ja està registrat per qualsevol altre usuari
    if ($telefon_ha_canviat && $error === '') {
        $stmt_tel = $pdo->prepare("SELECT id FROM usuaris WHERE telefon = ?"); // Realitzem una consulta on busquem un usuari amb el mateix telèfon
        $stmt_tel->execute([$telefon]);
        if ($stmt_tel->fetch()) { // Si retorna algun resultat, significa que el telèfon ja està a la BD
            $error = "Aquest telèfon ja està registrat"; 
        }
    }

    // Validar si el nom d'usuari ja està registrat per qualsevol altre usuari
    if ($usuari_ha_canviat && $error === '') {
        $stmt_user = $pdo->prepare("SELECT id FROM usuaris WHERE nom_usuari = ?"); // Realitzem una consulta on busquem un usuari amb el mateix nom d'usuari
        $stmt_user->execute([$nom_usuari]); // Si retorna algun resultat, significa que el nom d'usuari ja està a la BD
        if ($stmt_user->fetch()) { 
            $error = "Aquest nom d'usuari ja està registrat"; 
        }
    }

    // En cas que volguem canviar la contrasenya, farem les següent validacions
    if ($canvi_contrasenya && $error === '') {
        if ($contrasenya_actual === '' || $nova_contrasenya === '' || $confirmar_contrasenya === '') { // Revisem que tots els camps estiguin plens
            $error = "Has d'omplir tots els camps de contrasenya";
        } elseif (!verificar_contrasenya($contrasenya_actual, $usuari['contrasenya'])) { // Que la contrasenya de l'usuari sigui correcte
            $error = "La contrasenya actual no és correcta";
        } elseif ($nova_contrasenya !== $confirmar_contrasenya) { // Que la nova contrasenya i la seva verificació coincideixin
            $error = "Les noves contrasenyes no coincideixen";
        }
    }

    // Si s'ha superat totes les validacions
    if ($error === '') {
        try {
            if ($email_ha_canviat) { // Si l'email ha canviat
                $nou_estat_verificacio = 'no'; // Definirem que l'estat de verificació és no
            } else { // Si l'email no ha canviat
                $nou_estat_verificacio = $usuari['email_verificat']; // Valor original de l'usuari
            }

            if ($canvi_contrasenya) { // Si canviem la contrasenya
                $hash = encriptar_contrasenya($nova_contrasenya);
                $stmt = $pdo->prepare("
                    UPDATE usuaris 
                    SET nom_usuari = ?, nom_complet = ?, email = ?, telefon = ?, ciutat = ?, edat = ?, contrasenya = ?, email_verificat = ?
                    WHERE id = ?
                ");
                // Fem un Update de tots els camps de la BD: Dades personals + contrasenya
                $stmt->execute([$nom_usuari, $nom_complet, $email, $telefon, $ciutat, $edat, $hash, $nou_estat_verificacio, $usuari_id]);
                registrar_activitat($pdo, $usuari_id, 'restablir-contrasenya');
            } else { // Si no canviem la contrasenya
                $stmt = $pdo->prepare("
                    UPDATE usuaris 
                    SET nom_usuari = ?, nom_complet = ?, email = ?, telefon = ?, ciutat = ?, edat = ?, email_verificat = ?
                    WHERE id = ?
                ");
                // Únicament actualitzem les dades personals
                $stmt->execute([$nom_usuari, $nom_complet, $email, $telefon, $ciutat, $edat, $nou_estat_verificacio, $usuari_id]);
            }

            // Actualizar sessió
            $_SESSION['usuari']['nom_usuari']   = $nom_usuari;
            $_SESSION['usuari']['nom_complet']  = $nom_complet;
            $_SESSION['usuari']['email']        = $email;

            // Actualitzar les dades modificades obtenides a la consulta per mostrar-les al formulari
            $usuari['nom_usuari']  = $nom_usuari;
            $usuari['nom_complet'] = $nom_complet;
            $usuari['email']       = $email;
            $usuari['telefon']     = $telefon;
            $usuari['ciutat']      = $ciutat;
            $usuari['edat']        = $edat;

            if ($email_ha_canviat) { // Si hem canviat l'email
                // Borrar codi de verificació
                unset($_SESSION['codi_verificacio']);
                $correcte = "Perfil actualitzat. Com que has canviat l'email, l'hauràs de tornar a verificar.";
            } else {
                $correcte = "Perfil actualitzat correctament";
            }

            registrar_activitat($pdo, $usuari_id, 'editar-perfil');

        } catch (PDOException $e) {
            $error = "Error en actualitzar les dades: " . $e->getMessage();
        }
    }
}
?>

<!DOCTYPE html>
<html lang="ca">
<head>
    <meta charset="UTF-8">
    <title>Edició de perfil d'usuari</title>
    <link rel="stylesheet" href="./css/editarPerfil.css">
</head>
<body>
    <div class="edit-container">
        <header class="edit-header">
            <h2>Editar el teu perfil</h2>
            <p>Mantén les teves dades actualitzades</p>
        </header>

        <?php if ($error): // En cas que hi hagi un error es mostrarà?>
            <div class="alert alert-error"><?= htmlspecialchars($error) ?></div>
        <?php endif; ?>

        <?php if ($correcte): // En cas que hi hagi un missatge d'èxit es mostrarà?>
            <div class="alert alert-success"><?= htmlspecialchars($correcte) ?></div>
        <?php endif; ?>

        <form method="post" class="edit-card">
            <div class="form-section">
                <h3>Dades personals</h3>
                <div class="input-grid">
                    <div class="input-group">
                        <label>Nom d'usuari</label>
                        <input type="text" name="nom_usuari" value="<?= htmlspecialchars($usuari['nom_usuari']) ?>" required>
                    </div>
                    <div class="input-group">
                        <label>Nom complet</label>
                        <input type="text" name="nom_complet" value="<?= htmlspecialchars($usuari['nom_complet']) ?>" required>
                    </div>
                    <div class="input-group full-width">
                        <label>Email <span class="info-tag">(Es requerirà nova verificació si es canvia)</span></label>
                        <input type="email" name="email" value="<?= htmlspecialchars($usuari['email']) ?>" required>
                    </div>
                    <div class="input-group">
                        <label>Telèfon</label>
                        <input type="text" name="telefon" value="<?= htmlspecialchars($usuari['telefon']) ?>" required>
                    </div>
                    <div class="input-group">
                        <label>Ciutat</label>
                        <input type="text" name="ciutat" value="<?= htmlspecialchars($usuari['ciutat']) ?>" required>
                    </div>
                    <div class="input-group">
                        <label>Edat</label>
                        <input type="number" name="edat" min="0" max="120" value="<?= htmlspecialchars($usuari['edat']) ?>" required>
                    </div>
                </div>
            </div>

            <hr class="divider">

            <div class="form-section">
                <h3>Seguretat <span class="sub-title">(Opcional)</span></h3>
                <div class="input-group">
                    <label>Contrasenya actual</label>
                    <input type="password" name="contrasenya_actual">
                </div>
                <div class="input-grid">
                    <div class="input-group">
                        <label>Nova contrasenya</label>
                        <input type="password" name="nova_contrasenya">
                    </div>
                    <div class="input-group">
                        <label>Confirmar nova contrasenya</label>
                        <input type="password" name="confirmar_contrasenya">
                    </div>
                </div>
            </div>

            <div class="form-actions">
                <a href="privada.php" class="btn-cancel">Tornar enrere</a>
                <button type="submit" class="btn-submit">Desar canvis</button>
            </div>
        </form>
    </div>
</body>
</html>