868 lines
31 KiB
PHP
868 lines
31 KiB
PHP
<?php include('include/headscript.php'); ?>
|
||
<?php
|
||
$db = DBHandlerSelect::getInstance();
|
||
$pdo = $db->getConnection();
|
||
|
||
$userId = (int)($iduserlogin ?? 0);
|
||
|
||
if ($userId <= 0) {
|
||
die('Utente non valido.');
|
||
}
|
||
|
||
if (session_status() === PHP_SESSION_NONE) {
|
||
session_start();
|
||
}
|
||
|
||
if (empty($_SESSION['user_settings_csrf'])) {
|
||
$_SESSION['user_settings_csrf'] = bin2hex(random_bytes(32));
|
||
}
|
||
|
||
$csrfToken = $_SESSION['user_settings_csrf'];
|
||
|
||
$successMessage = '';
|
||
$errorMessage = '';
|
||
|
||
// Load countries.
|
||
$countries = [];
|
||
try {
|
||
$stmtCountries = $pdo->query("
|
||
SELECT id, name, iso_3166_2
|
||
FROM auth_countries
|
||
ORDER BY name ASC
|
||
");
|
||
$countries = $stmtCountries->fetchAll(PDO::FETCH_ASSOC);
|
||
} catch (Exception $e) {
|
||
$countries = [];
|
||
}
|
||
|
||
// Load current user.
|
||
$stmtProfileUser = $pdo->prepare("
|
||
SELECT
|
||
id,
|
||
email,
|
||
password,
|
||
first_name,
|
||
last_name,
|
||
phone,
|
||
avatar,
|
||
address,
|
||
country_id,
|
||
birthday,
|
||
role_id,
|
||
status,
|
||
last_login
|
||
FROM auth_users
|
||
WHERE id = ?
|
||
LIMIT 1
|
||
");
|
||
$stmtProfileUser->execute([$userId]);
|
||
$profileUser = $stmtProfileUser->fetch(PDO::FETCH_ASSOC);
|
||
|
||
if (!$profileUser) {
|
||
die('Utente non trovato.');
|
||
}
|
||
|
||
function e($value)
|
||
{
|
||
return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8');
|
||
}
|
||
|
||
function normalizeAvatarPath($avatar)
|
||
{
|
||
$avatar = trim((string)$avatar);
|
||
|
||
if ($avatar === '') {
|
||
return '';
|
||
}
|
||
|
||
// If the database already contains a complete relative path, use it as it is.
|
||
if (
|
||
str_starts_with($avatar, '../') ||
|
||
str_starts_with($avatar, './') ||
|
||
str_starts_with($avatar, '/') ||
|
||
str_starts_with($avatar, 'http://') ||
|
||
str_starts_with($avatar, 'https://')
|
||
) {
|
||
return $avatar;
|
||
}
|
||
|
||
// If the database contains only the filename, build the expected user upload path.
|
||
return '../upload/users/' . $avatar;
|
||
}
|
||
|
||
function getAvatarInitials($profileUser)
|
||
{
|
||
$first = trim((string)($profileUser['first_name'] ?? ''));
|
||
$last = trim((string)($profileUser['last_name'] ?? ''));
|
||
$email = trim((string)($profileUser['email'] ?? ''));
|
||
|
||
$initials = '';
|
||
|
||
if ($first !== '') {
|
||
$initials .= mb_substr($first, 0, 1);
|
||
}
|
||
|
||
if ($last !== '') {
|
||
$initials .= mb_substr($last, 0, 1);
|
||
}
|
||
|
||
if ($initials === '' && $email !== '') {
|
||
$initials = mb_substr($email, 0, 1);
|
||
}
|
||
|
||
return strtoupper($initials ?: 'U');
|
||
}
|
||
|
||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||
$postedToken = $_POST['csrf_token'] ?? '';
|
||
|
||
if (!hash_equals($csrfToken, $postedToken)) {
|
||
$errorMessage = 'Sessione non valida. Ricarica la pagina e riprova.';
|
||
} else {
|
||
$email = trim($_POST['email'] ?? '');
|
||
$firstName = trim($_POST['first_name'] ?? '');
|
||
$lastName = trim($_POST['last_name'] ?? '');
|
||
$phone = trim($_POST['phone'] ?? '');
|
||
$address = trim($_POST['address'] ?? '');
|
||
$countryId = $_POST['country_id'] !== '' ? (int)$_POST['country_id'] : null;
|
||
$birthday = trim($_POST['birthday'] ?? '');
|
||
|
||
$currentPassword = $_POST['current_password'] ?? '';
|
||
$newPassword = $_POST['new_password'] ?? '';
|
||
$confirmPassword = $_POST['confirm_password'] ?? '';
|
||
|
||
$birthdayValue = null;
|
||
$avatarToSave = $profileUser['avatar'];
|
||
|
||
if ($birthday !== '') {
|
||
$dateObj = DateTime::createFromFormat('Y-m-d', $birthday);
|
||
|
||
if (!$dateObj || $dateObj->format('Y-m-d') !== $birthday) {
|
||
$errorMessage = 'La data di nascita non è valida.';
|
||
} else {
|
||
$birthdayValue = $birthday;
|
||
}
|
||
}
|
||
|
||
if (!$errorMessage && $email === '') {
|
||
$errorMessage = 'L’email è obbligatoria.';
|
||
}
|
||
|
||
if (!$errorMessage && !filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||
$errorMessage = 'L’email inserita non è valida.';
|
||
}
|
||
|
||
// Check unique email.
|
||
if (!$errorMessage) {
|
||
$stmtCheckEmail = $pdo->prepare("
|
||
SELECT id
|
||
FROM auth_users
|
||
WHERE email = ? AND id <> ?
|
||
LIMIT 1
|
||
");
|
||
$stmtCheckEmail->execute([$email, $userId]);
|
||
|
||
if ($stmtCheckEmail->fetchColumn()) {
|
||
$errorMessage = 'Questa email è già utilizzata da un altro utente.';
|
||
}
|
||
}
|
||
|
||
// Avatar upload.
|
||
if (!$errorMessage && isset($_FILES['avatar']) && $_FILES['avatar']['error'] !== UPLOAD_ERR_NO_FILE) {
|
||
if ($_FILES['avatar']['error'] !== UPLOAD_ERR_OK) {
|
||
$errorMessage = 'Errore durante il caricamento dell’avatar.';
|
||
} else {
|
||
$maxFileSize = 2 * 1024 * 1024; // 2 MB
|
||
|
||
if ($_FILES['avatar']['size'] > $maxFileSize) {
|
||
$errorMessage = 'L’avatar non può superare 2 MB.';
|
||
} else {
|
||
$tmpFile = $_FILES['avatar']['tmp_name'];
|
||
$originalName = $_FILES['avatar']['name'];
|
||
|
||
$allowedMimeTypes = [
|
||
'image/jpeg' => 'jpg',
|
||
'image/png' => 'png',
|
||
'image/webp' => 'webp',
|
||
'image/gif' => 'gif',
|
||
];
|
||
|
||
$finfo = new finfo(FILEINFO_MIME_TYPE);
|
||
$mimeType = $finfo->file($tmpFile);
|
||
|
||
if (!array_key_exists($mimeType, $allowedMimeTypes)) {
|
||
$errorMessage = 'Formato avatar non valido. Sono consentiti JPG, PNG, WEBP o GIF.';
|
||
} else {
|
||
$uploadDir = __DIR__ . '/../upload/users/';
|
||
|
||
if (!is_dir($uploadDir)) {
|
||
mkdir($uploadDir, 0755, true);
|
||
}
|
||
|
||
$extension = $allowedMimeTypes[$mimeType];
|
||
$safeOriginalName = preg_replace('/[^A-Za-z0-9_\-\.]/', '_', pathinfo($originalName, PATHINFO_FILENAME));
|
||
$fileName = time() . '_' . $userId . '_' . $safeOriginalName . '.' . $extension;
|
||
|
||
$destination = $uploadDir . $fileName;
|
||
|
||
if (!move_uploaded_file($tmpFile, $destination)) {
|
||
$errorMessage = 'Impossibile salvare il file avatar.';
|
||
} else {
|
||
// Path used by pages inside userarea, for example:
|
||
// <img src="../upload/users/file.jpg">
|
||
$avatarToSave = $fileName;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
$passwordToSave = null;
|
||
$wantsPasswordChange = ($currentPassword !== '' || $newPassword !== '' || $confirmPassword !== '');
|
||
|
||
if (!$errorMessage && $wantsPasswordChange) {
|
||
if ($currentPassword === '') {
|
||
$errorMessage = 'Inserisci la password attuale.';
|
||
} elseif ($newPassword === '') {
|
||
$errorMessage = 'Inserisci la nuova password.';
|
||
} elseif (strlen($newPassword) < 8) {
|
||
$errorMessage = 'La nuova password deve contenere almeno 8 caratteri.';
|
||
} elseif ($newPassword !== $confirmPassword) {
|
||
$errorMessage = 'La conferma password non corrisponde.';
|
||
} elseif (!password_verify($currentPassword, $profileUser['password'])) {
|
||
$errorMessage = 'La password attuale non è corretta.';
|
||
} else {
|
||
// Password is encrypted before saving.
|
||
$passwordToSave = password_hash($newPassword, PASSWORD_DEFAULT);
|
||
}
|
||
}
|
||
|
||
if (!$errorMessage) {
|
||
try {
|
||
$pdo->beginTransaction();
|
||
|
||
$stmtUpdate = $pdo->prepare("
|
||
UPDATE auth_users
|
||
SET
|
||
email = :email,
|
||
first_name = :first_name,
|
||
last_name = :last_name,
|
||
phone = :phone,
|
||
avatar = :avatar,
|
||
address = :address,
|
||
country_id = :country_id,
|
||
birthday = :birthday,
|
||
updated_at = NOW()
|
||
WHERE id = :id
|
||
LIMIT 1
|
||
");
|
||
|
||
$stmtUpdate->execute([
|
||
':email' => $email,
|
||
':first_name' => $firstName !== '' ? $firstName : null,
|
||
':last_name' => $lastName !== '' ? $lastName : null,
|
||
':phone' => $phone !== '' ? $phone : null,
|
||
':avatar' => $avatarToSave !== '' ? $avatarToSave : null,
|
||
':address' => $address !== '' ? $address : null,
|
||
':country_id' => $countryId,
|
||
':birthday' => $birthdayValue,
|
||
':id' => $userId,
|
||
]);
|
||
|
||
if ($passwordToSave !== null) {
|
||
$stmtPassword = $pdo->prepare("
|
||
UPDATE auth_users
|
||
SET password = ?, updated_at = NOW()
|
||
WHERE id = ?
|
||
LIMIT 1
|
||
");
|
||
$stmtPassword->execute([$passwordToSave, $userId]);
|
||
}
|
||
|
||
$pdo->commit();
|
||
|
||
$successMessage = $passwordToSave !== null
|
||
? 'Profilo, avatar e password aggiornati correttamente.'
|
||
: 'Profilo aggiornato correttamente.';
|
||
|
||
// Reload updated user.
|
||
$stmtProfileUser->execute([$userId]);
|
||
$profileUser = $stmtProfileUser->fetch(PDO::FETCH_ASSOC);
|
||
|
||
$_SESSION['user_settings_csrf'] = bin2hex(random_bytes(32));
|
||
$csrfToken = $_SESSION['user_settings_csrf'];
|
||
} catch (Exception $e) {
|
||
if ($pdo->inTransaction()) {
|
||
$pdo->rollBack();
|
||
}
|
||
|
||
$errorMessage = 'Errore durante il salvataggio delle impostazioni.';
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
$avatarPath = normalizeAvatarPath($profileUser['avatar'] ?? '');
|
||
?>
|
||
<!doctype html>
|
||
<html lang="it">
|
||
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<link rel="icon" href="assets/images/favicon-32x32.png" type="image/png" />
|
||
<?php include('cssinclude.php'); ?>
|
||
<title>Impostazioni Utente <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?></title>
|
||
|
||
<style>
|
||
body {
|
||
background: linear-gradient(135deg, #f3f6f8, #e8eef3);
|
||
font-family: 'Segoe UI', sans-serif;
|
||
color: #2b3e50;
|
||
}
|
||
|
||
.page-content {
|
||
padding: 1.4rem 1rem;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
}
|
||
|
||
.settings-wrap {
|
||
width: 100%;
|
||
max-width: 1280px;
|
||
}
|
||
|
||
h3.settings-title {
|
||
text-align: center;
|
||
font-weight: 800;
|
||
color: #2b3e50;
|
||
margin-bottom: 1.2rem;
|
||
letter-spacing: 0.3px;
|
||
}
|
||
|
||
.settings-card {
|
||
background: #fff;
|
||
border-radius: 16px;
|
||
box-shadow: 0 5px 12px rgba(0, 0, 0, 0.08);
|
||
margin-bottom: 16px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.settings-header {
|
||
padding: 16px 18px;
|
||
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
}
|
||
|
||
.settings-icon {
|
||
font-size: 1.8rem;
|
||
line-height: 1;
|
||
}
|
||
|
||
.settings-heading {
|
||
margin: 0;
|
||
font-weight: 800;
|
||
font-size: 1.1rem;
|
||
}
|
||
|
||
.settings-subtitle {
|
||
margin: 0;
|
||
color: #6b7a89;
|
||
font-size: 0.92rem;
|
||
}
|
||
|
||
.settings-body {
|
||
padding: 20px;
|
||
}
|
||
|
||
.profile-layout {
|
||
display: grid;
|
||
grid-template-columns: 280px 1fr;
|
||
gap: 24px;
|
||
align-items: flex-start;
|
||
}
|
||
|
||
.avatar-panel {
|
||
background: linear-gradient(135deg, #f7fbff, #edf5ff);
|
||
border: 1px solid #dbeafe;
|
||
border-radius: 18px;
|
||
padding: 20px;
|
||
text-align: center;
|
||
}
|
||
|
||
.avatar-box {
|
||
width: 132px;
|
||
height: 132px;
|
||
border-radius: 34px;
|
||
background: linear-gradient(135deg, #cde5ff, #dff0ff);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 3rem;
|
||
font-weight: 800;
|
||
color: #2b3e50;
|
||
box-shadow: 0 5px 12px rgba(0, 0, 0, 0.08);
|
||
overflow: hidden;
|
||
margin: 0 auto 14px auto;
|
||
}
|
||
|
||
.avatar-box img {
|
||
width: 100%;
|
||
height: 100%;
|
||
object-fit: cover;
|
||
}
|
||
|
||
.avatar-name {
|
||
font-size: 1.1rem;
|
||
font-weight: 800;
|
||
margin: 0;
|
||
color: #2b3e50;
|
||
}
|
||
|
||
.avatar-email {
|
||
color: #6b7a89;
|
||
margin: 4px 0 14px 0;
|
||
font-size: 0.92rem;
|
||
word-break: break-word;
|
||
}
|
||
|
||
.avatar-upload-label {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 100%;
|
||
border-radius: 14px;
|
||
padding: 11px 14px;
|
||
cursor: pointer;
|
||
font-weight: 800;
|
||
color: #2b3e50;
|
||
background: linear-gradient(135deg, #e5e7eb, #f3f4f6);
|
||
box-shadow: 0 5px 12px rgba(0, 0, 0, 0.08);
|
||
transition: all 0.2s ease;
|
||
margin-top: 8px;
|
||
}
|
||
|
||
.avatar-upload-label:hover {
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 8px 18px rgba(0, 0, 0, 0.13);
|
||
}
|
||
|
||
.avatar-upload-input {
|
||
display: none;
|
||
}
|
||
|
||
.avatar-help {
|
||
font-size: 0.82rem;
|
||
color: #6b7a89;
|
||
margin-top: 10px;
|
||
line-height: 1.35;
|
||
}
|
||
|
||
.profile-meta {
|
||
color: #6b7a89;
|
||
font-size: 0.88rem;
|
||
margin-top: 14px;
|
||
}
|
||
|
||
.form-label {
|
||
font-weight: 700;
|
||
color: #2b3e50;
|
||
margin-bottom: 6px;
|
||
}
|
||
|
||
.form-control,
|
||
.form-select {
|
||
border-radius: 12px;
|
||
border: 1px solid #d8e0e7;
|
||
padding: 10px 12px;
|
||
font-size: 0.95rem;
|
||
}
|
||
|
||
.form-control:focus,
|
||
.form-select:focus {
|
||
border-color: #8bbcf7;
|
||
box-shadow: 0 0 0 0.18rem rgba(139, 188, 247, 0.25);
|
||
}
|
||
|
||
.help-text {
|
||
font-size: 0.86rem;
|
||
color: #6b7a89;
|
||
margin-top: 6px;
|
||
}
|
||
|
||
.password-box {
|
||
background: linear-gradient(135deg, #fff7e6, #fffaf0);
|
||
border-radius: 16px;
|
||
padding: 16px;
|
||
border: 1px solid rgba(255, 184, 107, 0.45);
|
||
}
|
||
|
||
.btn-save-settings {
|
||
border: 0;
|
||
border-radius: 16px;
|
||
padding: 13px 24px;
|
||
font-size: 1rem;
|
||
font-weight: 800;
|
||
color: #fff;
|
||
background: linear-gradient(135deg, #61ce5dff, #61ce5dff);
|
||
box-shadow: 0 5px 12px rgba(0, 0, 0, 0.08);
|
||
transition: all 0.2s ease;
|
||
}
|
||
|
||
.btn-save-settings:hover {
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 8px 18px rgba(0, 0, 0, 0.13);
|
||
color: #fff;
|
||
}
|
||
|
||
.btn-back {
|
||
border: 0;
|
||
border-radius: 16px;
|
||
padding: 13px 20px;
|
||
font-size: 1rem;
|
||
font-weight: 800;
|
||
color: #2b3e50;
|
||
background: linear-gradient(135deg, #e5e7eb, #f3f4f6);
|
||
box-shadow: 0 5px 12px rgba(0, 0, 0, 0.08);
|
||
transition: all 0.2s ease;
|
||
text-decoration: none;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.btn-back:hover {
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 8px 18px rgba(0, 0, 0, 0.13);
|
||
color: #2b3e50;
|
||
}
|
||
|
||
.alert {
|
||
border-radius: 16px;
|
||
border: 0;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.readonly-note {
|
||
background: linear-gradient(135deg, #cde5ff, #dff0ff);
|
||
border-radius: 16px;
|
||
padding: 14px 16px;
|
||
color: #2b3e50;
|
||
font-weight: 600;
|
||
margin-bottom: 18px;
|
||
}
|
||
|
||
.actions-row {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
gap: 12px;
|
||
flex-wrap: wrap;
|
||
margin-top: 18px;
|
||
}
|
||
|
||
.selected-file-name {
|
||
font-size: 0.84rem;
|
||
color: #2b3e50;
|
||
margin-top: 8px;
|
||
font-weight: 600;
|
||
word-break: break-word;
|
||
}
|
||
|
||
@media (max-width: 992px) {
|
||
.profile-layout {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
|
||
.avatar-panel {
|
||
max-width: 420px;
|
||
margin: 0 auto;
|
||
width: 100%;
|
||
}
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.settings-body {
|
||
padding: 16px;
|
||
}
|
||
|
||
.actions-row {
|
||
flex-direction: column;
|
||
}
|
||
|
||
.btn-save-settings,
|
||
.btn-back {
|
||
width: 100%;
|
||
justify-content: center;
|
||
}
|
||
}
|
||
</style>
|
||
</head>
|
||
|
||
<body>
|
||
<div class="wrapper toggled">
|
||
<?php include('include/navbar.php'); ?>
|
||
<?php include('include/topbar.php'); ?>
|
||
|
||
<div class="page-wrapper">
|
||
<div class="page-content">
|
||
|
||
<div class="settings-wrap">
|
||
<h3 class="settings-title">Impostazioni Utente</h3>
|
||
|
||
<?php if ($successMessage): ?>
|
||
<div class="alert alert-success">
|
||
<?= e($successMessage); ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<?php if ($errorMessage): ?>
|
||
<div class="alert alert-danger">
|
||
<?= e($errorMessage); ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<form method="post" enctype="multipart/form-data" autocomplete="off">
|
||
<input type="hidden" name="csrf_token" value="<?= e($csrfToken); ?>">
|
||
|
||
<div class="settings-card">
|
||
<div class="settings-header">
|
||
<div class="settings-icon">👤</div>
|
||
<div>
|
||
<p class="settings-heading">Profilo personale</p>
|
||
<p class="settings-subtitle">Dati anagrafici, contatti e avatar utente</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="settings-body">
|
||
|
||
<div class="readonly-note">
|
||
Ruolo, stato account e impostazioni di sicurezza avanzate non sono modificabili da questa pagina.
|
||
</div>
|
||
|
||
<div class="profile-layout">
|
||
<div class="avatar-panel">
|
||
<div class="avatar-box" id="avatarPreviewBox">
|
||
<?php if (!empty($avatarPath)): ?>
|
||
<img src="<?= e($avatarPath); ?>" class="user-img" alt="user avatar" id="avatarPreviewImage">
|
||
<?php else: ?>
|
||
<span id="avatarInitials"><?= e(getAvatarInitials($profileUser)); ?></span>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<p class="avatar-name">
|
||
<?= e(trim(($profileUser['first_name'] ?? '') . ' ' . ($profileUser['last_name'] ?? '')) ?: 'Utente'); ?>
|
||
</p>
|
||
|
||
<p class="avatar-email">
|
||
<?= e($profileUser['email']); ?>
|
||
</p>
|
||
|
||
<label for="avatar" class="avatar-upload-label">
|
||
Carica avatar
|
||
</label>
|
||
|
||
<input type="file"
|
||
class="avatar-upload-input"
|
||
id="avatar"
|
||
name="avatar"
|
||
accept="image/jpeg,image/png,image/webp,image/gif">
|
||
|
||
<div id="selectedFileName" class="selected-file-name"></div>
|
||
|
||
<div class="avatar-help">
|
||
Formati consentiti: JPG, PNG, WEBP, GIF.<br>
|
||
Dimensione massima: 2 MB.
|
||
</div>
|
||
|
||
<div class="profile-meta">
|
||
Stato account: <?= e($profileUser['status']); ?>
|
||
<?php if (!empty($profileUser['last_login'])): ?>
|
||
<br>Ultimo accesso: <?= e(date('d/m/Y H:i', strtotime($profileUser['last_login']))); ?>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<div class="row g-3">
|
||
<div class="col-md-6">
|
||
<label class="form-label" for="first_name">Nome</label>
|
||
<input type="text"
|
||
class="form-control"
|
||
id="first_name"
|
||
name="first_name"
|
||
value="<?= e($profileUser['first_name']); ?>">
|
||
</div>
|
||
|
||
<div class="col-md-6">
|
||
<label class="form-label" for="last_name">Cognome</label>
|
||
<input type="text"
|
||
class="form-control"
|
||
id="last_name"
|
||
name="last_name"
|
||
value="<?= e($profileUser['last_name']); ?>">
|
||
</div>
|
||
|
||
<div class="col-md-6">
|
||
<label class="form-label" for="email">Email</label>
|
||
<input type="email"
|
||
class="form-control"
|
||
id="email"
|
||
name="email"
|
||
value="<?= e($profileUser['email']); ?>"
|
||
required>
|
||
</div>
|
||
|
||
<div class="col-md-6">
|
||
<label class="form-label" for="phone">Telefono</label>
|
||
<input type="text"
|
||
class="form-control"
|
||
id="phone"
|
||
name="phone"
|
||
value="<?= e($profileUser['phone']); ?>">
|
||
</div>
|
||
|
||
<div class="col-md-6">
|
||
<label class="form-label" for="birthday">Data di nascita</label>
|
||
<input type="date"
|
||
class="form-control"
|
||
id="birthday"
|
||
name="birthday"
|
||
value="<?= e($profileUser['birthday']); ?>">
|
||
</div>
|
||
|
||
<div class="col-md-6">
|
||
<label class="form-label" for="country_id">Paese</label>
|
||
<select class="form-select" id="country_id" name="country_id">
|
||
<option value="">Seleziona...</option>
|
||
<?php foreach ($countries as $country): ?>
|
||
<option value="<?= (int)$country['id']; ?>"
|
||
<?= ((int)$profileUser['country_id'] === (int)$country['id']) ? 'selected' : ''; ?>>
|
||
<?= e($country['name'] . (!empty($country['iso_3166_2']) ? ' (' . $country['iso_3166_2'] . ')' : '')); ?>
|
||
</option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="col-md-12">
|
||
<label class="form-label" for="address">Indirizzo</label>
|
||
<input type="text"
|
||
class="form-control"
|
||
id="address"
|
||
name="address"
|
||
value="<?= e($profileUser['address']); ?>">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<div class="settings-card">
|
||
<div class="settings-header">
|
||
<div class="settings-icon">🔐</div>
|
||
<div>
|
||
<p class="settings-heading">Cambio password</p>
|
||
<p class="settings-subtitle">Compila questa sezione solo se vuoi modificare la password</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="settings-body">
|
||
<div class="password-box">
|
||
<div class="row g-3">
|
||
<div class="col-md-4">
|
||
<label class="form-label" for="current_password">Password attuale</label>
|
||
<input type="password"
|
||
class="form-control"
|
||
id="current_password"
|
||
name="current_password"
|
||
autocomplete="current-password">
|
||
</div>
|
||
|
||
<div class="col-md-4">
|
||
<label class="form-label" for="new_password">Nuova password</label>
|
||
<input type="password"
|
||
class="form-control"
|
||
id="new_password"
|
||
name="new_password"
|
||
autocomplete="new-password">
|
||
</div>
|
||
|
||
<div class="col-md-4">
|
||
<label class="form-label" for="confirm_password">Conferma nuova password</label>
|
||
<input type="password"
|
||
class="form-control"
|
||
id="confirm_password"
|
||
name="confirm_password"
|
||
autocomplete="new-password">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="help-text">
|
||
Se lasci questi campi vuoti, la password attuale rimane invariata.
|
||
La nuova password deve avere almeno 8 caratteri.
|
||
</div>
|
||
</div>
|
||
|
||
<div class="actions-row">
|
||
<a href="production_dashboard.php" class="btn-back">← Torna alla dashboard</a>
|
||
<button type="submit" class="btn-save-settings">Salva impostazioni</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<?php include('jsinclude.php'); ?>
|
||
<?php include('include/footer.php'); ?>
|
||
</div>
|
||
|
||
<script>
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
const avatarInput = document.getElementById('avatar');
|
||
const previewBox = document.getElementById('avatarPreviewBox');
|
||
const selectedFileName = document.getElementById('selectedFileName');
|
||
|
||
if (!avatarInput || !previewBox) {
|
||
return;
|
||
}
|
||
|
||
avatarInput.addEventListener('change', function() {
|
||
const file = this.files && this.files[0] ? this.files[0] : null;
|
||
|
||
if (!file) {
|
||
selectedFileName.textContent = '';
|
||
return;
|
||
}
|
||
|
||
selectedFileName.textContent = file.name;
|
||
|
||
if (!file.type.startsWith('image/')) {
|
||
return;
|
||
}
|
||
|
||
const reader = new FileReader();
|
||
|
||
reader.onload = function(event) {
|
||
previewBox.innerHTML = '';
|
||
|
||
const img = document.createElement('img');
|
||
img.src = event.target.result;
|
||
img.className = 'user-img';
|
||
img.alt = 'user avatar';
|
||
|
||
previewBox.appendChild(img);
|
||
};
|
||
|
||
reader.readAsDataURL(file);
|
||
});
|
||
});
|
||
</script>
|
||
</body>
|
||
|
||
</html>
|