Autosave: 20260801-192531
This commit is contained in:
parent
d1def919d5
commit
ec0a3af33e
@ -1796,7 +1796,7 @@ require_once 'layout_header.php';
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex flex-column gap-2">
|
||||
<button type="button" class="btn btn-outline-primary btn-sm" id="airDroidCopyButton-<?php echo htmlspecialchars($order['source_key']); ?>" data-phone="<?php echo $phoneHiddenByDay1 ? '' : htmlspecialchars((string) ($order['celular'] ?? '')); ?>" onclick="copyPhoneToClipboard(this.dataset.phone); return false;"<?php echo $phoneHiddenByDay1 ? ' disabled' : ''; ?>><?php echo $phoneHiddenByDay1 ? 'Número oculto' : 'Copiar número'; ?></button>
|
||||
<button type="button" class="btn btn-outline-primary btn-sm" id="airDroidCopyButton-<?php echo htmlspecialchars($order['source_key']); ?>" data-phone="<?php echo $phoneHiddenByDay1 ? '' : htmlspecialchars((string) ($order['celular'] ?? '')); ?>" onclick="copyPhoneButtonAction(this); return false;"<?php echo $phoneHiddenByDay1 ? ' disabled' : ''; ?>><?php echo $phoneHiddenByDay1 ? 'Número oculto' : 'Copiar número'; ?></button>
|
||||
<button type="button" class="btn btn-outline-secondary btn-sm" onclick="openAirDroidWeb()">Abrir AirDroid Web</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -2771,6 +2771,50 @@ function copyTextLegacy(text) {
|
||||
return copied;
|
||||
}
|
||||
|
||||
function flashCopyButtonFeedback(button) {
|
||||
if (!button) {
|
||||
return;
|
||||
}
|
||||
|
||||
const defaultLabel = button.dataset.defaultCopyLabel || button.textContent || 'Copiar número';
|
||||
button.dataset.defaultCopyLabel = defaultLabel;
|
||||
|
||||
if (button._copyFeedbackTimer) {
|
||||
window.clearTimeout(button._copyFeedbackTimer);
|
||||
button._copyFeedbackTimer = null;
|
||||
}
|
||||
|
||||
button.textContent = 'Copiado ✅';
|
||||
button.setAttribute('aria-live', 'polite');
|
||||
|
||||
button._copyFeedbackTimer = window.setTimeout(() => {
|
||||
if (button.textContent === 'Copiado ✅') {
|
||||
button.textContent = defaultLabel;
|
||||
}
|
||||
button.removeAttribute('aria-live');
|
||||
button._copyFeedbackTimer = null;
|
||||
}, 1300);
|
||||
}
|
||||
|
||||
function copyPhoneButtonAction(button) {
|
||||
if (!button) {
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
|
||||
const phone = button.dataset.phone || '';
|
||||
return copyPhoneToClipboard(phone).then(copied => {
|
||||
if (copied) {
|
||||
flashCopyButtonFeedback(button);
|
||||
} else {
|
||||
alert('No se pudo copiar el número automáticamente.');
|
||||
}
|
||||
return copied;
|
||||
}).catch(() => {
|
||||
alert('No se pudo copiar el número automáticamente.');
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
function copyPhoneToClipboard(phone) {
|
||||
if (!phone) {
|
||||
return Promise.resolve(false);
|
||||
@ -2821,24 +2865,26 @@ function showAirDroidHelper(details) {
|
||||
phoneNode.textContent = phone !== '-' ? phone : 'Sin celular';
|
||||
}
|
||||
}
|
||||
if (copyButton) {
|
||||
if (copyButton) {
|
||||
if (phoneHiddenByDay1) {
|
||||
copyButton.dataset.phone = '';
|
||||
copyButton.disabled = true;
|
||||
copyButton.textContent = 'Número oculto';
|
||||
copyButton.dataset.defaultCopyLabel = 'Número oculto';
|
||||
copyButton.removeAttribute('aria-live');
|
||||
copyButton.setAttribute('title', 'Número oculto hasta completar Promo Final');
|
||||
} else {
|
||||
copyButton.dataset.phone = phone !== '-' ? phone : '';
|
||||
copyButton.disabled = false;
|
||||
copyButton.textContent = 'Copiar número';
|
||||
copyButton.dataset.defaultCopyLabel = 'Copiar número';
|
||||
copyButton.removeAttribute('aria-live');
|
||||
copyButton.removeAttribute('title');
|
||||
}
|
||||
}
|
||||
openButton.onclick = function () {
|
||||
openAirDroidWeb();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function registrarLlamada(event, trigger) {
|
||||
@ -2934,12 +2980,7 @@ function registrarLlamada(event, trigger) {
|
||||
const airDroidCopyButton = document.getElementById('airDroidCopyButton');
|
||||
if (airDroidCopyButton) {
|
||||
airDroidCopyButton.addEventListener('click', function () {
|
||||
const phone = this.dataset.phone || '';
|
||||
copyPhoneToClipboard(phone).then(copied => {
|
||||
if (!copied) {
|
||||
alert('No se pudo copiar el número automáticamente.');
|
||||
}
|
||||
});
|
||||
copyPhoneButtonAction(this);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -2285,7 +2285,7 @@ require_once 'layout_header.php';
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex flex-column gap-2">
|
||||
<button type="button" class="btn btn-outline-primary btn-sm" id="airDroidCopyButton-<?php echo htmlspecialchars($order['source_key']); ?>" data-phone="<?php echo $phoneHiddenByDay1 ? '' : htmlspecialchars((string) ($order['celular'] ?? '')); ?>" onclick="copyPhoneToClipboard(this.dataset.phone); return false;"<?php echo $phoneHiddenByDay1 ? ' disabled' : ''; ?>><?php echo $phoneHiddenByDay1 ? 'Número oculto' : 'Copiar número'; ?></button>
|
||||
<button type="button" class="btn btn-outline-primary btn-sm" id="airDroidCopyButton-<?php echo htmlspecialchars($order['source_key']); ?>" data-phone="<?php echo $phoneHiddenByDay1 ? '' : htmlspecialchars((string) ($order['celular'] ?? '')); ?>" onclick="copyPhoneButtonAction(this); return false;"<?php echo $phoneHiddenByDay1 ? ' disabled' : ''; ?>><?php echo $phoneHiddenByDay1 ? 'Número oculto' : 'Copiar número'; ?></button>
|
||||
<button type="button" class="btn btn-outline-secondary btn-sm" onclick="openAirDroidWeb()">Abrir AirDroid Web</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -3306,6 +3306,50 @@ function copyTextLegacy(text) {
|
||||
return copied;
|
||||
}
|
||||
|
||||
function flashCopyButtonFeedback(button) {
|
||||
if (!button) {
|
||||
return;
|
||||
}
|
||||
|
||||
const defaultLabel = button.dataset.defaultCopyLabel || button.textContent || 'Copiar número';
|
||||
button.dataset.defaultCopyLabel = defaultLabel;
|
||||
|
||||
if (button._copyFeedbackTimer) {
|
||||
window.clearTimeout(button._copyFeedbackTimer);
|
||||
button._copyFeedbackTimer = null;
|
||||
}
|
||||
|
||||
button.textContent = 'Copiado ✅';
|
||||
button.setAttribute('aria-live', 'polite');
|
||||
|
||||
button._copyFeedbackTimer = window.setTimeout(() => {
|
||||
if (button.textContent === 'Copiado ✅') {
|
||||
button.textContent = defaultLabel;
|
||||
}
|
||||
button.removeAttribute('aria-live');
|
||||
button._copyFeedbackTimer = null;
|
||||
}, 1300);
|
||||
}
|
||||
|
||||
function copyPhoneButtonAction(button) {
|
||||
if (!button) {
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
|
||||
const phone = button.dataset.phone || '';
|
||||
return copyPhoneToClipboard(phone).then(copied => {
|
||||
if (copied) {
|
||||
flashCopyButtonFeedback(button);
|
||||
} else {
|
||||
alert('No se pudo copiar el número automáticamente.');
|
||||
}
|
||||
return copied;
|
||||
}).catch(() => {
|
||||
alert('No se pudo copiar el número automáticamente.');
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
function copyPhoneToClipboard(phone) {
|
||||
if (!phone) {
|
||||
return Promise.resolve(false);
|
||||
@ -3356,24 +3400,26 @@ function showAirDroidHelper(details) {
|
||||
phoneNode.textContent = phone !== '-' ? phone : 'Sin celular';
|
||||
}
|
||||
}
|
||||
if (copyButton) {
|
||||
if (copyButton) {
|
||||
if (phoneHiddenByDay1) {
|
||||
copyButton.dataset.phone = '';
|
||||
copyButton.disabled = true;
|
||||
copyButton.textContent = 'Número oculto';
|
||||
copyButton.dataset.defaultCopyLabel = 'Número oculto';
|
||||
copyButton.removeAttribute('aria-live');
|
||||
copyButton.setAttribute('title', 'Número oculto hasta completar Promo Final');
|
||||
} else {
|
||||
copyButton.dataset.phone = phone !== '-' ? phone : '';
|
||||
copyButton.disabled = false;
|
||||
copyButton.textContent = 'Copiar número';
|
||||
copyButton.dataset.defaultCopyLabel = 'Copiar número';
|
||||
copyButton.removeAttribute('aria-live');
|
||||
copyButton.removeAttribute('title');
|
||||
}
|
||||
}
|
||||
openButton.onclick = function () {
|
||||
openAirDroidWeb();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function registrarLlamada(event, trigger) {
|
||||
@ -3469,12 +3515,7 @@ function registrarLlamada(event, trigger) {
|
||||
const airDroidCopyButton = document.getElementById('airDroidCopyButton');
|
||||
if (airDroidCopyButton) {
|
||||
airDroidCopyButton.addEventListener('click', function () {
|
||||
const phone = this.dataset.phone || '';
|
||||
copyPhoneToClipboard(phone).then(copied => {
|
||||
if (!copied) {
|
||||
alert('No se pudo copiar el número automáticamente.');
|
||||
}
|
||||
});
|
||||
copyPhoneButtonAction(this);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -1335,6 +1335,16 @@ function cc_test_followup_promo_final_cutoff(): DateTimeImmutable
|
||||
return new DateTimeImmutable('2026-07-29 00:00:00');
|
||||
}
|
||||
|
||||
function cc_test_followup_is_from_promo_final_cutoff(array $order): bool
|
||||
{
|
||||
$startedAt = cc_test_followup_started_at($order);
|
||||
if (!$startedAt instanceof DateTimeImmutable) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $startedAt->format('Y-m-d') >= cc_test_followup_promo_final_cutoff()->format('Y-m-d');
|
||||
}
|
||||
|
||||
function cc_test_followup_promo_final_threshold_day(array $order): int
|
||||
{
|
||||
$startedAt = cc_test_followup_started_at($order);
|
||||
@ -1430,6 +1440,10 @@ function cc_test_followup_pending_promo_final_counts(array $orders): array
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!cc_test_followup_is_from_promo_final_cutoff($order)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$ownerKey = cc_test_followup_owner_lock_key($order);
|
||||
if ($ownerKey === '') {
|
||||
continue;
|
||||
|
||||
74
login.php
74
login.php
@ -1,6 +1,39 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
require_once 'db/config.php';
|
||||
|
||||
if (!function_exists('normalizeLoginIdentifier')) {
|
||||
function normalizeLoginIdentifier(string $value): string
|
||||
{
|
||||
$value = trim($value);
|
||||
return function_exists('mb_strtolower') ? mb_strtolower($value, 'UTF-8') : strtolower($value);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('normalizeSessionRole')) {
|
||||
function normalizeSessionRole(?string $role): string
|
||||
{
|
||||
$role = normalizeLoginIdentifier((string) ($role ?? ''));
|
||||
|
||||
$aliases = [
|
||||
'administrador' => 'admin',
|
||||
'admin' => 'admin',
|
||||
'asesor' => 'asesor',
|
||||
'marketing' => 'marketing',
|
||||
'control logistico' => 'control_logistico',
|
||||
'control_logistico' => 'control_logistico',
|
||||
'soporte logistico' => 'soporte_logistico',
|
||||
'soporte_logistico' => 'soporte_logistico',
|
||||
'verificador de pagos' => 'verificador_pagos',
|
||||
'verificador_pagos' => 'verificador_pagos',
|
||||
'logistica' => 'logistica',
|
||||
];
|
||||
|
||||
return $aliases[$role] ?? $role;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_SESSION['user_id'])) {
|
||||
$currentRole = (string) ($_SESSION['user_role'] ?? '');
|
||||
if (in_array($currentRole, ['Administrador', 'admin'], true)) {
|
||||
@ -15,28 +48,39 @@ if (isset($_SESSION['user_id'])) {
|
||||
exit();
|
||||
}
|
||||
|
||||
require_once 'db/config.php';
|
||||
|
||||
$error = '';
|
||||
$submittedUsername = '';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$username = $_POST['username'];
|
||||
$password = $_POST['password'];
|
||||
$username = trim((string) ($_POST['username'] ?? ''));
|
||||
$password = (string) ($_POST['password'] ?? '');
|
||||
$submittedUsername = $username;
|
||||
|
||||
if (empty($username) || empty($password)) {
|
||||
if ($username === '' || $password === '') {
|
||||
$error = 'Please enter both username and password.';
|
||||
} else {
|
||||
try {
|
||||
$db = db();
|
||||
$stmt = $db->prepare('SELECT * FROM users WHERE username = :username');
|
||||
$stmt->bindParam(':username', $username);
|
||||
$lookup = normalizeLoginIdentifier($username);
|
||||
|
||||
$stmt = $db->prepare('SELECT * FROM users WHERE LOWER(TRIM(username)) = :identifier LIMIT 1');
|
||||
$stmt->bindValue(':identifier', $lookup, PDO::PARAM_STR);
|
||||
$stmt->execute();
|
||||
$user = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($user && password_verify($password, $user['password'])) {
|
||||
if (!$user) {
|
||||
$stmt = $db->prepare("SELECT * FROM users WHERE LOWER(TRIM(COALESCE(nombre_asesor, ''))) = :identifier LIMIT 1");
|
||||
$stmt->bindValue(':identifier', $lookup, PDO::PARAM_STR);
|
||||
$stmt->execute();
|
||||
$user = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
if ($user && password_verify($password, (string) ($user['password'] ?? ''))) {
|
||||
$_SESSION['user_id'] = $user['id'];
|
||||
$_SESSION['username'] = $user['username'];
|
||||
$_SESSION['user_role'] = $user['role'];
|
||||
$_SESSION['username'] = trim((string) ($user['username'] ?? ''));
|
||||
$_SESSION['user_role'] = (string) ($user['role'] ?? '');
|
||||
$_SESSION['role'] = normalizeSessionRole((string) ($user['role'] ?? ''));
|
||||
$_SESSION['nombre_asesor'] = trim((string) ($user['nombre_asesor'] ?? ''));
|
||||
|
||||
// Record session
|
||||
try {
|
||||
@ -75,8 +119,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
header('Location: pedidos.php');
|
||||
}
|
||||
exit();
|
||||
} elseif ($user) {
|
||||
$error = 'Invalid password.';
|
||||
} else {
|
||||
$error = 'Invalid username or password.';
|
||||
$error = 'We could not find an account with that username or advisor name.';
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
$error = 'Database error: ' . $e->getMessage();
|
||||
@ -105,12 +151,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
<div class="card-body">
|
||||
<h3 class="card-title text-center">Login</h3>
|
||||
<?php if ($error): ?>
|
||||
<div class="alert alert-danger"><?php echo $error; ?></div>
|
||||
<div class="alert alert-danger"><?php echo htmlspecialchars($error); ?></div>
|
||||
<?php endif; ?>
|
||||
<form method="POST">
|
||||
<div class="mb-3">
|
||||
<label for="username" class="form-label">Username</label>
|
||||
<input type="text" class="form-control" id="username" name="username" required>
|
||||
<input type="text" class="form-control" id="username" name="username" value="<?php echo htmlspecialchars($submittedUsername); ?>" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="password" class="form-label">Password</label>
|
||||
@ -125,4 +171,4 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
</div>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user