Files
html/office-365/office-import.php
2026-04-12 22:57:03 +02:00

755 lines
32 KiB
PHP

<?php
/**
* Office 365 Import - WEVAL
* Import des comptes depuis fichier Excel/CSV
* CORRIGÉ: Conversion de date DD/MM/YYYY -> YYYY-MM-DD
*/
session_start();
header('Content-Type: text/html; charset=utf-8');
try {
$pdo = new PDO("pgsql:host=10.1.0.3;dbname=adx_system", "admin", "admin123");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (Exception $e) {
die("Erreur DB: " . $e->getMessage());
}
// Ajouter colonnes si pas présentes
try {
$pdo->exec("ALTER TABLE admin.office_accounts ADD COLUMN IF NOT EXISTS source VARCHAR(100)");
$pdo->exec("ALTER TABLE admin.office_accounts ADD COLUMN IF NOT EXISTS account_type VARCHAR(50)");
$pdo->exec("ALTER TABLE admin.office_accounts ADD COLUMN IF NOT EXISTS client_id VARCHAR(100)");
$pdo->exec("ALTER TABLE admin.office_accounts ADD COLUMN IF NOT EXISTS secret_id TEXT");
$pdo->exec("ALTER TABLE admin.office_accounts ADD COLUMN IF NOT EXISTS comment TEXT");
$pdo->exec("ALTER TABLE admin.office_accounts ADD COLUMN IF NOT EXISTS import_date DATE");
} catch (Exception $e) {}
/**
* Convertit une date en format YYYY-MM-DD pour PostgreSQL
* Supporte: DD/MM/YYYY, MM/DD/YYYY, YYYY-MM-DD, DD-MM-YYYY
*/
function parseDate($dateStr) {
$dateStr = trim($dateStr);
if (empty($dateStr)) return date('Y-m-d');
// Déjà au format YYYY-MM-DD ?
if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $dateStr)) {
return $dateStr;
}
// Format DD/MM/YYYY ou DD-MM-YYYY (format européen)
if (preg_match('/^(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})$/', $dateStr, $m)) {
$day = intval($m[1]);
$month = intval($m[2]);
$year = intval($m[3]);
// Si le jour > 12, c'est forcément DD/MM/YYYY
// Si le mois > 12, c'est forcément MM/DD/YYYY (mais invalide)
// On assume DD/MM/YYYY (format européen) par défaut
// Validation basique
if ($day > 31) {
// Peut-être MM/DD/YYYY inversé ?
list($day, $month) = [$month, $day];
}
if ($month > 12) {
// Mois invalide, inverser
list($day, $month) = [$month, $day];
}
// Vérification finale
if ($month > 12 || $day > 31) {
return date('Y-m-d'); // Date invalide, utiliser aujourd'hui
}
return sprintf('%04d-%02d-%02d', $year, $month, $day);
}
// Essayer strtotime en dernier recours
$ts = strtotime($dateStr);
if ($ts !== false) {
return date('Y-m-d', $ts);
}
return date('Y-m-d');
}
$message = '';
$messageType = '';
$importResults = [];
$previewData = [];
$showPreview = false;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Action: Aperçu
if (isset($_POST['action']) && $_POST['action'] === 'preview' && isset($_FILES['excel_file'])) {
$file = $_FILES['excel_file'];
if ($file['error'] === UPLOAD_ERR_OK) {
$content = file_get_contents($file['tmp_name']);
$lines = explode("\n", $content);
$isFirstLine = true;
$lineNum = 0;
foreach ($lines as $line) {
$line = trim($line);
if (empty($line)) continue;
$lineNum++;
if (strpos($line, "\t") !== false) $parts = explode("\t", $line);
elseif (strpos($line, ';') !== false) $parts = explode(';', $line);
else $parts = explode(',', $line);
if ($isFirstLine) {
$isFirstLine = false;
$h = strtolower(trim($parts[0] ?? ''));
if (in_array($h, ['source', 'account', 'email', 'account mail'])) continue;
}
$email = trim($parts[1] ?? '');
if (empty($email) || strpos($email, '@') === false) continue;
$check = $pdo->prepare("SELECT id, admin_password FROM admin.office_accounts WHERE admin_email = ?");
$check->execute([$email]);
$existing = $check->fetch(PDO::FETCH_ASSOC);
$previewData[] = [
'line' => $lineNum,
'source' => trim($parts[0] ?? ''),
'email' => $email,
'password' => trim($parts[2] ?? ''),
'type' => trim($parts[3] ?? ''),
'date_raw' => trim($parts[7] ?? ''),
'date_parsed' => parseDate(trim($parts[7] ?? '')),
'exists' => $existing ? true : false,
'existing_id' => $existing['id'] ?? null,
'password_changed' => $existing ? ($existing['admin_password'] !== trim($parts[2] ?? '')) : false
];
if (count($previewData) >= 100) break;
}
$showPreview = true;
$tempFile = '/tmp/office_import_' . session_id() . '.csv';
move_uploaded_file($file['tmp_name'], $tempFile);
$_SESSION['import_file'] = $tempFile;
}
}
// Action: Import
if (isset($_POST['action']) && $_POST['action'] === 'import') {
$duplicateAction = $_POST['duplicate_action'] ?? 'update';
$tempFile = $_SESSION['import_file'] ?? null;
if ($tempFile && file_exists($tempFile)) {
$content = file_get_contents($tempFile);
$lines = explode("\n", $content);
$inserted = 0;
$updated = 0;
$skipped = 0;
$errors = [];
$isFirstLine = true;
foreach ($lines as $line) {
$line = trim($line);
if (empty($line)) continue;
if (strpos($line, "\t") !== false) $parts = explode("\t", $line);
elseif (strpos($line, ';') !== false) $parts = explode(';', $line);
else $parts = explode(',', $line);
if ($isFirstLine) {
$isFirstLine = false;
$h = strtolower(trim($parts[0] ?? ''));
if (in_array($h, ['source', 'account', 'email', 'account mail'])) continue;
}
$source = trim($parts[0] ?? '');
$email = trim($parts[1] ?? '');
$password = trim($parts[2] ?? '');
$type = trim($parts[3] ?? '');
$clientId = trim($parts[4] ?? '');
$tenantId = trim($parts[5] ?? '');
$secretId = trim($parts[6] ?? '');
$importDateRaw = trim($parts[7] ?? '');
$comment = trim($parts[8] ?? '');
if (empty($email) || strpos($email, '@') === false) {
$skipped++;
continue;
}
$emailParts = explode('@', $email);
$name = $emailParts[0] ?? 'Account';
$tenantDomain = $emailParts[1] ?? '';
// CORRECTION: Utiliser la fonction parseDate
$importDate = parseDate($importDateRaw);
try {
$check = $pdo->prepare("SELECT id FROM admin.office_accounts WHERE admin_email = ?");
$check->execute([$email]);
$existing = $check->fetch();
if ($existing) {
if ($duplicateAction === 'skip') {
$skipped++;
continue;
} elseif ($duplicateAction === 'update') {
$stmt = $pdo->prepare("UPDATE admin.office_accounts SET
admin_password = COALESCE(NULLIF(?, ''), admin_password),
source = COALESCE(NULLIF(?, ''), source),
account_type = COALESCE(NULLIF(?, ''), account_type),
client_id = COALESCE(NULLIF(?, ''), client_id),
tenant_id = COALESCE(NULLIF(?, ''), tenant_id),
secret_id = COALESCE(NULLIF(?, ''), secret_id),
comment = COALESCE(NULLIF(?, ''), comment),
last_update = NOW()
WHERE admin_email = ?");
$stmt->execute([$password, $source, $type, $clientId, $tenantId, $secretId, $comment, $email]);
$updated++;
} elseif ($duplicateAction === 'replace') {
$stmt = $pdo->prepare("UPDATE admin.office_accounts SET
admin_password = ?,
source = ?,
account_type = ?,
client_id = ?,
tenant_id = ?,
secret_id = ?,
comment = ?,
last_update = NOW(),
password_status = NULL,
has_mfa = NULL,
has_license = NULL,
status = 'Pending'
WHERE admin_email = ?");
$stmt->execute([$password, $source ?: null, $type ?: null, $clientId ?: null, $tenantId ?: null, $secretId ?: null, $comment ?: null, $email]);
$updated++;
}
} else {
$stmt = $pdo->prepare("INSERT INTO admin.office_accounts
(name, tenant_domain, admin_email, admin_password, source, account_type,
client_id, tenant_id, secret_id, import_date, status, created_by, comment)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'Pending', 'Import', ?)");
$stmt->execute([
$name, $tenantDomain, $email, $password,
$source ?: null, $type ?: null, $clientId ?: null,
$tenantId ?: null, $secretId ?: null, $importDate, $comment ?: null
]);
$inserted++;
}
} catch (Exception $e) {
$errors[] = "$email: " . $e->getMessage();
}
}
unlink($tempFile);
unset($_SESSION['import_file']);
$message = "Import terminé : $inserted nouveaux, $updated mis à jour, $skipped ignorés";
$messageType = "success";
$importResults = compact('inserted', 'updated', 'skipped', 'errors');
} else {
$message = "Fichier non trouvé. Veuillez réuploader.";
$messageType = "error";
}
}
// Import direct
if (isset($_POST['action']) && $_POST['action'] === 'direct_import' && isset($_FILES['excel_file'])) {
$file = $_FILES['excel_file'];
$duplicateAction = $_POST['duplicate_action'] ?? 'update';
if ($file['error'] === UPLOAD_ERR_OK) {
$content = file_get_contents($file['tmp_name']);
$lines = explode("\n", $content);
$inserted = 0;
$updated = 0;
$skipped = 0;
$errors = [];
$isFirstLine = true;
foreach ($lines as $line) {
$line = trim($line);
if (empty($line)) continue;
if (strpos($line, "\t") !== false) $parts = explode("\t", $line);
elseif (strpos($line, ';') !== false) $parts = explode(';', $line);
else $parts = explode(',', $line);
if ($isFirstLine) {
$isFirstLine = false;
$h = strtolower(trim($parts[0] ?? ''));
if (in_array($h, ['source', 'account', 'email', 'account mail'])) continue;
}
$source = trim($parts[0] ?? '');
$email = trim($parts[1] ?? '');
$password = trim($parts[2] ?? '');
$type = trim($parts[3] ?? '');
$clientId = trim($parts[4] ?? '');
$tenantId = trim($parts[5] ?? '');
$secretId = trim($parts[6] ?? '');
$importDateRaw = trim($parts[7] ?? '');
$comment = trim($parts[8] ?? '');
if (empty($email) || strpos($email, '@') === false) {
$skipped++;
continue;
}
$emailParts = explode('@', $email);
$name = $emailParts[0] ?? 'Account';
$tenantDomain = $emailParts[1] ?? '';
// CORRECTION: Utiliser la fonction parseDate
$importDate = parseDate($importDateRaw);
try {
$check = $pdo->prepare("SELECT id FROM admin.office_accounts WHERE admin_email = ?");
$check->execute([$email]);
$existing = $check->fetch();
if ($existing) {
if ($duplicateAction === 'skip') {
$skipped++;
continue;
} elseif ($duplicateAction === 'update') {
$stmt = $pdo->prepare("UPDATE admin.office_accounts SET
admin_password = COALESCE(NULLIF(?, ''), admin_password),
source = COALESCE(NULLIF(?, ''), source),
account_type = COALESCE(NULLIF(?, ''), account_type),
client_id = COALESCE(NULLIF(?, ''), client_id),
tenant_id = COALESCE(NULLIF(?, ''), tenant_id),
secret_id = COALESCE(NULLIF(?, ''), secret_id),
comment = COALESCE(NULLIF(?, ''), comment),
last_update = NOW()
WHERE admin_email = ?");
$stmt->execute([$password, $source, $type, $clientId, $tenantId, $secretId, $comment, $email]);
$updated++;
} elseif ($duplicateAction === 'replace') {
$stmt = $pdo->prepare("UPDATE admin.office_accounts SET
admin_password = ?,
source = ?,
account_type = ?,
client_id = ?,
tenant_id = ?,
secret_id = ?,
comment = ?,
last_update = NOW(),
password_status = NULL,
has_mfa = NULL,
has_license = NULL,
status = 'Pending'
WHERE admin_email = ?");
$stmt->execute([$password, $source ?: null, $type ?: null, $clientId ?: null, $tenantId ?: null, $secretId ?: null, $comment ?: null, $email]);
$updated++;
}
} else {
$stmt = $pdo->prepare("INSERT INTO admin.office_accounts
(name, tenant_domain, admin_email, admin_password, source, account_type,
client_id, tenant_id, secret_id, import_date, status, created_by, comment)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'Pending', 'Import', ?)");
$stmt->execute([
$name, $tenantDomain, $email, $password,
$source ?: null, $type ?: null, $clientId ?: null,
$tenantId ?: null, $secretId ?: null, $importDate, $comment ?: null
]);
$inserted++;
}
} catch (Exception $e) {
$errors[] = "$email: " . $e->getMessage();
}
}
$message = "Import terminé : $inserted nouveaux, $updated mis à jour, $skipped ignorés";
$messageType = "success";
$importResults = compact('inserted', 'updated', 'skipped', 'errors');
}
}
}
$stats = $pdo->query("SELECT COUNT(*) as total FROM admin.office_accounts")->fetch();
$duplicateCount = 0;
if (!empty($previewData)) {
$duplicateCount = count(array_filter($previewData, fn($p) => $p['exists']));
}
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Import Office 365 - WEVAL</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Segoe UI', system-ui, sans-serif;
background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 50%, #f8fafc 100%);
min-height: 100vh;
color: #1e293b;
padding: 20px;
}
.container { max-width: 1200px; margin: 0 auto; }
.header {
background: #ffffff;
border-radius: 16px;
padding: 24px 32px;
margin-bottom: 24px;
border: 1px solid #e2e8f0;
display: flex;
justify-content: space-between;
align-items: center;
}
.header h1 {
font-size: 28px;
background: linear-gradient(135deg, #0891b2, #0e7490);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.header p { color: #64748b; margin-top: 4px; }
.btn {
padding: 10px 20px;
border: none;
border-radius: 8px;
cursor: pointer;
font-weight: 600;
font-size: 13px;
display: inline-flex;
align-items: center;
gap: 8px;
text-decoration: none;
transition: all 0.2s;
}
.btn-primary { background: linear-gradient(135deg, #0891b2, #06b6d4); color: white; }
.btn-secondary { background: #f1f5f9; color: #475569; border: 1px solid #e2e8f0; }
.btn-success { background: linear-gradient(135deg, #059669, #10b981); color: white; }
.btn-purple { background: linear-gradient(135deg, #7c3aed, #8b5cf6); color: white; }
.card {
background: #ffffff;
border-radius: 12px;
border: 1px solid #e2e8f0;
margin-bottom: 20px;
}
.card-header {
background: #f8fafc;
padding: 16px 20px;
border-bottom: 1px solid #e2e8f0;
border-radius: 12px 12px 0 0;
}
.card-header h3 { font-size: 16px; color: #0891b2; }
.card-body { padding: 24px; }
.upload-zone {
border: 2px dashed #06b6d4;
border-radius: 12px;
padding: 40px;
text-align: center;
background: #f0f9ff;
cursor: pointer;
transition: all 0.3s;
}
.upload-zone:hover { background: #e0f2fe; }
.upload-zone i { font-size: 48px; color: #06b6d4; margin-bottom: 16px; }
.upload-zone h4 { color: #0891b2; margin-bottom: 8px; }
input[type="file"] { display: none; }
.format-box {
background: #f0f9ff;
border: 1px solid #e0f2fe;
border-radius: 8px;
padding: 16px;
margin-top: 20px;
}
.format-box h5 { color: #0891b2; margin-bottom: 12px; }
.format-box code {
display: block;
background: #fff;
padding: 12px;
border-radius: 6px;
font-size: 11px;
overflow-x: auto;
}
.message {
padding: 14px 20px;
border-radius: 10px;
margin-bottom: 20px;
}
.message-success { background: #dcfce7; color: #16a34a; }
.message-error { background: #fee2e2; color: #dc2626; }
.results { background: #f8fafc; border-radius: 8px; padding: 16px; margin-top: 16px; }
.result-row { display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid #e2e8f0; }
.result-row:last-child { border: none; }
.stats-row { display: flex; gap: 20px; margin-top: 20px; }
.stat-box { background: #f0f9ff; padding: 16px 24px; border-radius: 8px; text-align: center; flex: 1; }
.stat-value { font-size: 28px; font-weight: 700; color: #0891b2; }
.stat-label { font-size: 12px; color: #64748b; }
.options-box {
background: #fef3c7;
border: 1px solid #fde68a;
border-radius: 8px;
padding: 16px;
margin: 20px 0;
}
.options-box h5 { color: #d97706; margin-bottom: 12px; }
.radio-group { display: flex; gap: 20px; flex-wrap: wrap; }
.radio-item {
display: flex;
align-items: center;
gap: 8px;
padding: 10px 16px;
background: #fff;
border-radius: 8px;
cursor: pointer;
border: 2px solid transparent;
}
.radio-item:has(input:checked) { border-color: #d97706; background: #fffbeb; }
.preview-table {
width: 100%;
border-collapse: collapse;
font-size: 12px;
margin-top: 16px;
}
.preview-table th, .preview-table td {
padding: 10px;
border: 1px solid #e2e8f0;
text-align: left;
}
.preview-table th { background: #f0f9ff; color: #0891b2; }
.preview-table tr.duplicate { background: #fef3c7; }
.preview-table tr.new { background: #dcfce7; }
.badge {
padding: 3px 8px;
border-radius: 4px;
font-size: 10px;
font-weight: 600;
}
.badge-new { background: #dcfce7; color: #16a34a; }
.badge-duplicate { background: #fef3c7; color: #d97706; }
.badge-changed { background: #fee2e2; color: #dc2626; }
.badge-date { background: #e0f2fe; color: #0891b2; }
.preview-summary {
display: flex;
gap: 16px;
margin-bottom: 16px;
}
.summary-item {
padding: 12px 20px;
border-radius: 8px;
text-align: center;
}
.summary-new { background: #dcfce7; }
.summary-duplicate { background: #fef3c7; }
.errors-box {
background: #fef2f2;
border: 1px solid #fecaca;
border-radius: 8px;
padding: 16px;
margin-top: 16px;
max-height: 200px;
overflow-y: auto;
}
.errors-box h5 { color: #dc2626; margin-bottom: 8px; }
.error-item { font-size: 11px; color: #dc2626; padding: 4px 0; border-bottom: 1px solid #fecaca; }
</style>
</head>
<body>
<div class="container">
<div class="header">
<div>
<h1><i class="fas fa-file-import"></i> Import Office 365</h1>
<p>Importer des comptes depuis un fichier CSV/TXT</p>
</div>
<a href="office-management.php" class="btn btn-secondary"><i class="fas fa-arrow-left"></i> Retour</a>
</div>
<?php if ($message): ?>
<div class="message message-<?= $messageType ?>"><?= $message ?></div>
<?php endif; ?>
<?php if (!empty($importResults)): ?>
<div class="card">
<div class="card-header"><h3><i class="fas fa-chart-bar"></i> Résultats de l'import</h3></div>
<div class="card-body">
<div class="results">
<div class="result-row"><span>✅ Nouveaux comptes créés</span><strong style="color:#10b981"><?= $importResults['inserted'] ?></strong></div>
<div class="result-row"><span>🔄 Comptes mis à jour</span><strong style="color:#d97706"><?= $importResults['updated'] ?></strong></div>
<div class="result-row"><span>⏭️ Lignes ignorées</span><strong style="color:#64748b"><?= $importResults['skipped'] ?></strong></div>
</div>
<?php if (!empty($importResults['errors'])): ?>
<div class="errors-box">
<h5><i class="fas fa-exclamation-triangle"></i> Erreurs (<?= count($importResults['errors']) ?>)</h5>
<?php foreach (array_slice($importResults['errors'], 0, 50) as $e): ?>
<div class="error-item"><?= htmlspecialchars($e) ?></div>
<?php endforeach; ?>
<?php if (count($importResults['errors']) > 50): ?>
<div class="error-item">... et <?= count($importResults['errors']) - 50 ?> autres erreurs</div>
<?php endif; ?>
</div>
<?php endif; ?>
<div style="margin-top: 16px; text-align: center;">
<a href="office-management.php" class="btn btn-primary"><i class="fas fa-list"></i> Voir les comptes</a>
<a href="office-import.php" class="btn btn-secondary"><i class="fas fa-redo"></i> Nouvel import</a>
</div>
</div>
</div>
<?php endif; ?>
<?php if ($showPreview && !empty($previewData)): ?>
<div class="card">
<div class="card-header"><h3><i class="fas fa-eye"></i> Aperçu (<?= count($previewData) ?> lignes)</h3></div>
<div class="card-body">
<div class="preview-summary">
<div class="summary-item summary-new">
<div style="font-size: 24px; font-weight: 700; color: #16a34a;"><?= count($previewData) - $duplicateCount ?></div>
<div style="font-size: 12px; color: #16a34a;">Nouveaux</div>
</div>
<div class="summary-item summary-duplicate">
<div style="font-size: 24px; font-weight: 700; color: #d97706;"><?= $duplicateCount ?></div>
<div style="font-size: 12px; color: #d97706;">Doublons</div>
</div>
</div>
<form method="POST">
<input type="hidden" name="action" value="import">
<?php if ($duplicateCount > 0): ?>
<div class="options-box">
<h5><i class="fas fa-copy"></i> Que faire avec les <?= $duplicateCount ?> doublons ?</h5>
<div class="radio-group">
<label class="radio-item"><input type="radio" name="duplicate_action" value="update" checked><span>🔄 Mettre à jour</span></label>
<label class="radio-item"><input type="radio" name="duplicate_action" value="skip"><span>⏭️ Ignorer</span></label>
<label class="radio-item"><input type="radio" name="duplicate_action" value="replace"><span>🔁 Remplacer</span></label>
</div>
</div>
<?php else: ?>
<input type="hidden" name="duplicate_action" value="update">
<?php endif; ?>
<div style="max-height: 400px; overflow-y: auto;">
<table class="preview-table">
<thead>
<tr><th>#</th><th>Email</th><th>Source</th><th>Date brute</th><th>Date convertie</th><th>Status</th></tr>
</thead>
<tbody>
<?php foreach ($previewData as $p): ?>
<tr class="<?= $p['exists'] ? 'duplicate' : 'new' ?>">
<td><?= $p['line'] ?></td>
<td style="font-size: 11px;"><?= htmlspecialchars($p['email']) ?></td>
<td><?= htmlspecialchars($p['source']) ?></td>
<td><code style="font-size: 10px;"><?= htmlspecialchars($p['date_raw']) ?></code></td>
<td><span class="badge badge-date"><?= $p['date_parsed'] ?></span></td>
<td>
<?php if ($p['exists']): ?>
<span class="badge badge-duplicate">Doublon #<?= $p['existing_id'] ?></span>
<?php if ($p['password_changed']): ?><span class="badge badge-changed">PWD</span><?php endif; ?>
<?php else: ?>
<span class="badge badge-new">Nouveau</span>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<div style="margin-top: 20px; text-align: center; display: flex; gap: 12px; justify-content: center;">
<a href="office-import.php" class="btn btn-secondary"><i class="fas fa-times"></i> Annuler</a>
<button type="submit" class="btn btn-success"><i class="fas fa-check"></i> Confirmer l'import</button>
</div>
</form>
</div>
</div>
<?php else: ?>
<div class="card">
<div class="card-header"><h3><i class="fas fa-upload"></i> Upload fichier</h3></div>
<div class="card-body">
<form method="POST" enctype="multipart/form-data" id="uploadForm">
<input type="hidden" name="action" value="preview">
<label for="fileInput">
<div class="upload-zone" id="dropZone">
<i class="fas fa-cloud-upload-alt"></i>
<h4>Glissez votre fichier ici</h4>
<p style="color:#64748b">ou cliquez pour sélectionner (CSV, TXT)</p>
<p id="fileName" style="margin-top:10px; color:#0891b2; font-weight:600;"></p>
</div>
</label>
<input type="file" name="excel_file" id="fileInput" accept=".csv,.txt">
<div class="format-box">
<h5><i class="fas fa-info-circle"></i> Format attendu</h5>
<code>Source;Account mail;Password;Type;ClientId;TenantId;SecretId;date;Comment</code>
<p style="margin-top:10px; font-size:12px; color:#64748b;">
<strong>Date:</strong> Format DD/MM/YYYY (ex: 13/12/2025) - sera converti automatiquement
</p>
</div>
<div style="margin-top:20px; display: flex; gap: 12px; justify-content: center;">
<button type="submit" class="btn btn-purple" id="previewBtn" disabled>
<i class="fas fa-eye"></i> Aperçu avant import
</button>
</div>
</form>
<div class="stats-row">
<div class="stat-box">
<div class="stat-value"><?= $stats['total'] ?></div>
<div class="stat-label">Comptes en base</div>
</div>
</div>
</div>
</div>
<?php endif; ?>
</div>
<script>
const fileInput = document.getElementById('fileInput');
const fileName = document.getElementById('fileName');
const previewBtn = document.getElementById('previewBtn');
const dropZone = document.getElementById('dropZone');
if (dropZone) {
dropZone.addEventListener('dragover', e => { e.preventDefault(); dropZone.style.background = '#cffafe'; });
dropZone.addEventListener('dragleave', () => { dropZone.style.background = '#f0f9ff'; });
dropZone.addEventListener('drop', e => {
e.preventDefault();
dropZone.style.background = '#f0f9ff';
if (e.dataTransfer.files.length) {
fileInput.files = e.dataTransfer.files;
updateFile();
}
});
}
if (fileInput) fileInput.addEventListener('change', updateFile);
function updateFile() {
if (fileInput.files.length) {
fileName.textContent = '📄 ' + fileInput.files[0].name;
if (previewBtn) previewBtn.disabled = false;
}
}
</script>
<?php include("includes/chatbot-widget.php"); ?>
</body>
</html>