| Server IP : 80.211.21.168 / Your IP : 216.73.217.33 Web Server : Apache System : Linux alex-webdesign.it 3.10.0-1160.119.1.el7.tuxcare.els22.x86_64 #1 SMP Mon Aug 18 06:07:12 UTC 2025 x86_64 User : admin_japan ( 10003) PHP Version : 8.2.32 Disable Function : opcache_get_status MySQL : OFF | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : /var/www/vhosts/cerchijapan.it/ai4dealers.com/MRC2/ |
Upload File : |
<?php
session_start();
if (!isset($_SESSION['user_id'])) {
header("Location: login.php");
exit();
}
$mysqli = new mysqli('localhost', 'admin_valucrm', 'RCMvalus1994!', 'admin_valucrm');
if ($mysqli->connect_error) {
die("Connessione fallita: " . $mysqli->connect_error);
}
// Dati utente loggato
$user_id = (int)$_SESSION['user_id'];
$username = $_SESSION['username'];
$is_admin = ($username === 'valutatoreAuto');
// Status particolari
$ACTIVE_STATUS = 'Cliente attivo';
$PROTECTED_STATUSES = ['Cliente attivo', 'Demo in corso'];
// =======================
// == Handle POST (RIASSEGNA) ==
// =======================
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$action = $_POST['action'] ?? '';
if ($action === 'reassign_self' || $action === 'reassign_admin') {
$client_id = isset($_POST['client_id']) && ctype_digit((string)$_POST['client_id'])
? (int)$_POST['client_id']
: 0;
if ($client_id <= 0) {
header("Location: " . $_SERVER['REQUEST_URI']);
exit();
}
// Carico record cliente
$stmt = $mysqli->prepare("SELECT id, user_id, status, last_modified FROM clients WHERE id = ?");
$stmt->bind_param('i', $client_id);
$stmt->execute();
$res = $stmt->get_result();
$client = $res->fetch_assoc();
$stmt->close();
if (!$client) {
header("Location: " . $_SERVER['REQUEST_URI']);
exit();
}
$owner_id = (int)$client['user_id'];
$status = trim((string)$client['status']);
// Calcolo giorni trascorsi da last_modified
$days_since_last = null;
if (!empty($client['last_modified'])) {
$ts = strtotime($client['last_modified']);
if ($ts !== false) {
$days_since_last = (int)floor((time() - $ts) / 86400);
}
}
// === RIASSEGNA A SE STESSO (UTENTE / ANCHE ADMIN SE VUOLE) ===
if ($action === 'reassign_self') {
$can_reassign = true;
// Non puoi riassegnare se è già tuo
if ($owner_id === $user_id) {
$can_reassign = false;
}
// Solo se NON in stati protetti
if (in_array($status, $PROTECTED_STATUSES, true)) {
$can_reassign = false;
}
// Solo se sono passati almeno 15 giorni dall'ultima modifica
if ($days_since_last === null || $days_since_last < 15) {
$can_reassign = false;
}
if ($can_reassign) {
$upd = $mysqli->prepare("UPDATE clients SET user_id = ?, last_modified = NOW() WHERE id = ?");
$upd->bind_param('ii', $user_id, $client_id);
$upd->execute();
$upd->close();
}
header("Location: " . $_SERVER['REQUEST_URI']);
exit();
}
// === RIASSEGNA DA ADMIN A QUALSIASI UTENTE ===
if ($action === 'reassign_admin' && $is_admin) {
$target_user_id = isset($_POST['target_user_id']) && ctype_digit((string)$_POST['target_user_id'])
? (int)$_POST['target_user_id']
: 0;
if ($target_user_id > 0) {
// opzionale: verifica che l'utente esista
$check = $mysqli->prepare("SELECT id FROM users WHERE id = ? LIMIT 1");
$check->bind_param('i', $target_user_id);
$check->execute();
$r = $check->get_result()->fetch_assoc();
$check->close();
if ($r) {
$upd = $mysqli->prepare("UPDATE clients SET user_id = ?, last_modified = NOW() WHERE id = ?");
$upd->bind_param('ii', $target_user_id, $client_id);
$upd->execute();
$upd->close();
}
}
header("Location: " . $_SERVER['REQUEST_URI']);
exit();
}
}
}
// =======================
// == Filtri GET ==
// =======================
// Filtro utente: di default mostro i clienti dell'utente loggato
if (isset($_GET['filter_user'])) {
$filter_user = $mysqli->real_escape_string($_GET['filter_user']);
} else {
$filter_user = $mysqli->real_escape_string($username);
}
// Filtro status (facoltativo)
$filter_status = isset($_GET['filter_status'])
? $mysqli->real_escape_string($_GET['filter_status'])
: '';
// Sort (aggiunto created_asc)
$allowed_sorts = ['created_desc', 'created_asc', 'last_modified_desc', 'last_modified_asc'];
$sort = isset($_GET['sort']) && in_array($_GET['sort'], $allowed_sorts, true)
? $_GET['sort']
: 'created_desc';
switch ($sort) {
case 'created_asc':
$orderBy = "clients.created_at ASC";
break;
case 'last_modified_asc':
$orderBy = "clients.last_modified ASC";
break;
case 'last_modified_desc':
$orderBy = "clients.last_modified DESC";
break;
case 'created_desc':
default:
$orderBy = "clients.created_at DESC";
break;
}
// Preleva lista utenti (per filtri + riassegnazione admin) e lista status per i dropdown
$users_for_filter = $mysqli->query("SELECT DISTINCT username FROM users ORDER BY username");
$users_for_assign = $mysqli->query("SELECT id, username FROM users ORDER BY username");
$users_assign_array = [];
if ($users_for_assign) {
while ($u = $users_for_assign->fetch_assoc()) {
$users_assign_array[] = $u;
}
}
$status_list_rs = $mysqli->query("SELECT DISTINCT status FROM clients ORDER BY status");
// Costruisci WHERE dinamico
$where = [];
// Tutti possono filtrare per utente
if ($filter_user !== '') {
$where[] = "users.username = '$filter_user'";
}
// Tutti possono filtrare per status
if ($filter_status !== '') {
$where[] = "clients.status = '$filter_status'";
}
// Restrizione di visibilità per NON admin:
// - Possono vedere tutti i clienti tranne quelli con status 'Cliente attivo' che non sono loro.
// - I loro 'Cliente attivo' restano visibili.
if (!$is_admin) {
$where[] = "(clients.status != '" . $mysqli->real_escape_string($ACTIVE_STATUS) . "' OR clients.user_id = $user_id)";
}
// Query clienti con join e filtri
$sql = "
SELECT clients.*, users.username
FROM clients
JOIN users ON clients.user_id = users.id
";
if (!empty($where)) {
$sql .= " WHERE " . implode(' AND ', $where);
}
$sql .= " ORDER BY $orderBy";
$result = $mysqli->query($sql);
if (!$result) {
die("Errore nella query clienti: " . $mysqli->error);
}
// Calcola conteggi per summary (in base ai risultati effettivamente visibili)
$status_counts = [];
if ($result) {
while ($r = $result->fetch_assoc()) {
$st = $r['status'];
if (!isset($status_counts[$st])) {
$status_counts[$st] = 0;
}
$status_counts[$st]++;
}
// Riporta il puntatore del result set all'inizio per la stampa della tabella
$result->data_seek(0);
}
?>
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ValuCRM - Dashboard</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/futuristic-theme.css">
<style>
.page-header {
background: var(--color-white);
border-bottom: 1px solid var(--color-border);
padding: 1rem 0;
margin-bottom: 1rem;
}
.page-title {
font-size: 1.5rem;
font-weight: 600;
margin: 0;
color: var(--color-text-primary);
}
.welcome-text {
color: var(--color-text-secondary);
font-size: 0.875rem;
margin: 0;
}
.stats-summary {
background: var(--color-white);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
padding: 0.75rem 1rem;
margin-bottom: 1rem;
display: flex;
flex-wrap: wrap;
gap: 1.5rem;
align-items: center;
}
.stat-item {
display: flex;
align-items: center;
gap: 0.5rem;
}
.stat-label {
font-size: 0.8125rem;
color: var(--color-text-tertiary);
}
.stat-value {
font-size: 0.875rem;
font-weight: 600;
color: var(--color-primary);
}
.filters-bar {
background: var(--color-white);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
padding: 0.75rem 1rem;
margin-bottom: 1rem;
}
.table-container {
width: 100%;
}
.table td.email-column,
.table td.notes-column {
max-width: 200px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.table td.email-column:hover,
.table td.notes-column:hover {
overflow: visible;
white-space: normal;
max-width: none;
position: relative;
z-index: 10;
}
.action-buttons {
display: flex;
flex-wrap: wrap;
gap: 0.25rem;
}
.status-badge {
display: inline-block;
padding: 0.25rem 0.625rem;
border-radius: var(--radius-full);
font-size: 0.75rem;
font-weight: 500;
white-space: nowrap;
}
.status-active {
background: var(--color-success-light);
color: #065F46;
}
.status-demo {
background: var(--color-warning-light);
color: #92400E;
}
.status-default {
background: var(--color-gray-100);
color: var(--color-text-secondary);
}
</style>
</head>
<body>
<div class="dashboard-container">
<div class="page-header">
<div class="d-flex justify-content-between align-items-center flex-wrap gap-2">
<div>
<h1 class="page-title">Dashboard CRM</h1>
<p class="welcome-text">Benvenuto, <strong><?php echo htmlspecialchars($username); ?></strong></p>
</div>
<div class="d-flex gap-2">
<a href="index.php" class="btn btn-secondary btn-sm">Home</a>
<a href="add_client.php" class="btn btn-success btn-sm">+ Aggiungi Cliente</a>
<a href="riassunto_clienti.php" class="btn btn-secondary btn-sm">Riassunto</a>
</div>
</div>
</div>
<!-- Stats Summary -->
<?php if (!empty($status_counts)): ?>
<div class="stats-summary">
<strong style="font-size: 0.875rem; color: var(--color-text-primary);">Riepilogo:</strong>
<?php foreach ($status_counts as $st => $cnt): ?>
<div class="stat-item">
<span class="stat-label"><?php echo htmlspecialchars($st); ?>:</span>
<span class="stat-value"><?php echo (int)$cnt; ?></span>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
<!-- Filters -->
<div class="filters-bar">
<div class="d-flex justify-content-between align-items-center flex-wrap gap-2">
<div class="d-flex gap-2 flex-wrap">
<!-- Filtro utente: visibile a tutti -->
<form method="GET" id="form_user" class="mr-3 form-inline">
<label class="mr-2" for="filter_user">Filtra utente:</label>
<select name="filter_user" class="form-control form-control-sm"
onchange="document.getElementById('form_user').submit()">
<option value="">Tutti</option>
<?php if ($users_for_filter): ?>
<?php while ($u = $users_for_filter->fetch_assoc()): ?>
<?php $uname = $u['username']; ?>
<option value="<?php echo htmlspecialchars($uname); ?>"
<?php if ($filter_user === $uname) echo 'selected'; ?>>
<?php echo htmlspecialchars($uname); ?>
</option>
<?php endwhile; ?>
<?php endif; ?>
</select>
<?php if ($filter_status !== ''): ?>
<input type="hidden" name="filter_status"
value="<?php echo htmlspecialchars($filter_status); ?>">
<?php endif; ?>
<?php if ($sort !== ''): ?>
<input type="hidden" name="sort" value="<?php echo htmlspecialchars($sort); ?>">
<?php endif; ?>
</form>
<!-- Filtro status: visibile a tutti -->
<form method="GET" id="form_status" class="mr-3 form-inline">
<?php if ($filter_user !== ''): ?>
<input type="hidden" name="filter_user"
value="<?php echo htmlspecialchars($filter_user); ?>">
<?php endif; ?>
<?php if ($sort !== ''): ?>
<input type="hidden" name="sort"
value="<?php echo htmlspecialchars($sort); ?>">
<?php endif; ?>
<label class="mr-2" for="filter_status">Filtra status:</label>
<select name="filter_status" class="form-control form-control-sm"
onchange="document.getElementById('form_status').submit()">
<option value="">Tutti</option>
<?php if ($status_list_rs): ?>
<?php while ($s = $status_list_rs->fetch_assoc()): ?>
<?php $st_val = $s['status']; ?>
<option value="<?php echo htmlspecialchars($st_val); ?>"
<?php if ($filter_status === $st_val) echo 'selected'; ?>>
<?php echo htmlspecialchars($st_val); ?>
</option>
<?php endwhile; ?>
<?php endif; ?>
</select>
</form>
<!-- Ordina per -->
<form method="GET" id="form_sort" class="form-inline">
<?php if ($filter_user !== ''): ?>
<input type="hidden" name="filter_user"
value="<?php echo htmlspecialchars($filter_user); ?>">
<?php endif; ?>
<?php if ($filter_status !== ''): ?>
<input type="hidden" name="filter_status"
value="<?php echo htmlspecialchars($filter_status); ?>">
<?php endif; ?>
<label class="mr-2" for="sort">Ordina per:</label>
<select name="sort"
id="sort"
class="form-control form-control-sm"
onchange="document.getElementById('form_sort').submit()">
<option value="created_desc" <?php if ($sort === 'created_desc') echo 'selected'; ?>>
Data creazione (nuovi prima)
</option>
<option value="created_asc" <?php if ($sort === 'created_asc') echo 'selected'; ?>>
Data creazione (più vecchi prima)
</option>
<option value="last_modified_desc" <?php if ($sort === 'last_modified_desc') echo 'selected'; ?>>
Ultima modifica (recenti prima)
</option>
<option value="last_modified_asc" <?php if ($sort === 'last_modified_asc') echo 'selected'; ?>>
Ultima modifica (meno recenti prima)
</option>
</select>
</form>
</div>
</div>
</div>
</div>
<!-- Tabella clienti -->
<div class="table-container">
<div class="table-responsive">
<table class="table table-striped table-bordered">
<thead class="thead-dark">
<tr>
<th>Nome azienda</th>
<th>Telefono</th>
<th>Indirizzo</th>
<th class="email-column">Email</th>
<th>Status</th>
<th>Aggiunto il</th>
<th>Ultima modifica</th>
<th>Caricato da</th>
<th class="notes-column">Note</th>
<th>Azione</th>
</tr>
</thead>
<tbody>
<?php if ($result && $result->num_rows > 0): ?>
<?php while ($row = $result->fetch_assoc()): ?>
<?php
$row_owner_id = (int)$row['user_id'];
$row_status = trim((string)$row['status']);
$is_owner = ($row_owner_id === $user_id);
// Calcolo giorni da last_modified
$days_since_last = null;
if (!empty($row['last_modified'])) {
$ts = strtotime($row['last_modified']);
if ($ts !== false) {
$days_since_last = (int)floor((time() - $ts) / 86400);
}
}
// Regole riassegnazione per utente NON admin
$can_reassign_self = false;
if (!$is_admin) {
if (
!$is_owner
&& !in_array($row_status, $PROTECTED_STATUSES, true)
&& $days_since_last !== null
&& $days_since_last >= 15
) {
$can_reassign_self = true;
}
}
$last_mod_str = $row['last_modified']
? date('d-m-Y H:i', strtotime($row['last_modified']))
: 'N/D';
?>
<tr>
<td><?php echo htmlspecialchars($row['company_name']); ?></td>
<td><?php echo htmlspecialchars($row['phone_number']); ?></td>
<td><?php echo htmlspecialchars($row['address']); ?></td>
<td class="email-column"
title="<?php echo htmlspecialchars($row['email_contacted']); ?>">
<?php echo htmlspecialchars($row['email_contacted']); ?>
</td>
<td>
<?php
$badge_class = 'status-default';
if ($row_status === 'Cliente attivo') {
$badge_class = 'status-active';
} elseif ($row_status === 'Demo in corso') {
$badge_class = 'status-demo';
}
?>
<span class="status-badge <?php echo $badge_class; ?>">
<?php echo htmlspecialchars($row_status); ?>
</span>
</td>
<td><?php echo date('d-m-Y', strtotime($row['created_at'])); ?></td>
<td><?php echo htmlspecialchars($last_mod_str); ?></td>
<td><?php echo htmlspecialchars($row['username']); ?></td>
<td class="notes-column">
<span title="<?php echo htmlspecialchars($row['notes']); ?>">
<?php echo htmlspecialchars($row['notes']); ?>
</span>
</td>
<td>
<div class="action-buttons">
<?php if ($is_admin || $is_owner): ?>
<a href="edit_client.php?client_id=<?php echo (int)$row['id']; ?>"
class="btn btn-primary btn-sm">Modifica</a>
<?php endif; ?>
<?php if (!$is_admin && $can_reassign_self): ?>
<form method="POST" style="margin: 0;">
<input type="hidden" name="client_id" value="<?php echo (int)$row['id']; ?>">
<button type="submit" name="action" value="reassign_self"
class="btn btn-warning btn-sm">Riassegna</button>
</form>
<?php endif; ?>
<?php if ($is_admin): ?>
<form method="POST" style="margin: 0;">
<input type="hidden" name="client_id" value="<?php echo (int)$row['id']; ?>">
<div class="input-group input-group-sm" style="min-width: 180px;">
<select name="target_user_id" class="form-control" style="font-size: 0.75rem;">
<?php foreach ($users_assign_array as $ua): ?>
<option value="<?php echo (int)$ua['id']; ?>"
<?php if ((int)$ua['id'] === $row_owner_id) echo 'selected'; ?>>
<?php echo htmlspecialchars($ua['username']); ?>
</option>
<?php endforeach; ?>
</select>
<div class="input-group-append">
<button type="submit" name="action" value="reassign_admin"
class="btn btn-warning btn-sm">OK</button>
</div>
</div>
</form>
<?php endif; ?>
</div>
</td>
</tr>
<?php endwhile; ?>
<?php else: ?>
<tr>
<td colspan="10" class="text-center">Nessun cliente trovato.</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>