19 changed files with 4946 additions and 1223 deletions
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -4,13 +4,14 @@ use App\Models\Users; |
|||||
use App\Models\Avance; |
use App\Models\Avance; |
||||
use App\Models\AlertMail; |
use App\Models\AlertMail; |
||||
|
|
||||
|
/** |
||||
|
* Vérifier les deadlines et envoyer des alertes email |
||||
|
*/ |
||||
function checkDeadlineAlerts() |
function checkDeadlineAlerts() |
||||
{ |
{ |
||||
log_message('info', "=== DÉBUT checkDeadlineAlerts ==="); |
log_message('info', "=== DÉBUT checkDeadlineAlerts ==="); |
||||
|
|
||||
$cacheFile = WRITEPATH . 'cache/check_deadline_last_run.txt'; |
$cacheFile = WRITEPATH . 'cache/check_deadline_last_run.txt'; |
||||
|
|
||||
// On enlève la vérification de 24h pour s'assurer que le script tourne quotidiennement |
|
||||
file_put_contents($cacheFile, time()); |
file_put_contents($cacheFile, time()); |
||||
|
|
||||
$avanceModel = new Avance(); |
$avanceModel = new Avance(); |
||||
@ -20,15 +21,16 @@ function checkDeadlineAlerts() |
|||||
$today = date('Y-m-d'); |
$today = date('Y-m-d'); |
||||
log_message('info', "Date du jour: {$today}"); |
log_message('info', "Date du jour: {$today}"); |
||||
|
|
||||
// Modification pour vérifier les avances dans 0-3 jours |
// Récupération des avances dans 0-3 jours |
||||
$avances = $avanceModel |
$avances = $avanceModel |
||||
->where('DATE(deadline) >=', $today) // Inclut le jour même |
->where('DATE(deadline) >=', $today) |
||||
->where('DATE(deadline) <=', date('Y-m-d', strtotime('+3 days'))) |
->where('DATE(deadline) <=', date('Y-m-d', strtotime('+3 days'))) |
||||
->where('active', 1) |
->where('active', 1) |
||||
->findAll(); |
->findAll(); |
||||
|
|
||||
log_message('info', "Nombre d'avances trouvées (0-3 jours): " . count($avances)); |
log_message('info', "Nombre d'avances trouvées (0-3 jours): " . count($avances)); |
||||
|
|
||||
|
// Récupération des utilisateurs DAF |
||||
$users = $usersModel->select('users.email, users.firstname, users.lastname') |
$users = $usersModel->select('users.email, users.firstname, users.lastname') |
||||
->join('user_group', 'user_group.user_id = users.id') |
->join('user_group', 'user_group.user_id = users.id') |
||||
->join('groups', 'groups.id = user_group.group_id') |
->join('groups', 'groups.id = user_group.group_id') |
||||
@ -56,7 +58,7 @@ function checkDeadlineAlerts() |
|||||
|
|
||||
log_message('info', "Avance ID: {$avance['avance_id']}, Deadline: {$deadline}, Jours restants: {$daysLeft}"); |
log_message('info', "Avance ID: {$avance['avance_id']}, Deadline: {$deadline}, Jours restants: {$daysLeft}"); |
||||
|
|
||||
// Modification des types d'alerte pour 0, 1, 2, 3 jours |
// Détermination du type d'alerte |
||||
$alertType = match($daysLeft) { |
$alertType = match($daysLeft) { |
||||
3 => 'deadline_3_days', |
3 => 'deadline_3_days', |
||||
2 => 'deadline_2_days', |
2 => 'deadline_2_days', |
||||
@ -83,31 +85,35 @@ function checkDeadlineAlerts() |
|||||
continue; |
continue; |
||||
} |
} |
||||
|
|
||||
// Message modifié pour inclure le cas du jour même |
// Construction du message |
||||
$urgencyText = $daysLeft === 0 ? "ÉCHÉANCE AUJOURD'HUI" : "{$daysLeft} jour(s) restant(s)"; |
$urgencyText = $daysLeft === 0 ? "ÉCHÉANCE AUJOURD'HUI" : "{$daysLeft} jour(s) restant(s)"; |
||||
$message = " |
$message = " |
||||
<h3>⚠️ URGENT : Avance approchant de la deadline</h3> |
<html> |
||||
<p><strong>ID Avance :</strong> {$avance['avance_id']}</p> |
<body style='font-family: Arial, sans-serif; color: #333;'> |
||||
<p><strong>Client :</strong> {$avance['customer_name']}</p> |
<h3 style='color: #d9534f;'>⚠️ URGENT : Avance approchant de la deadline</h3> |
||||
<p><strong>Montant avance :</strong> " . number_format($avance['avance_amount'], 0, ',', ' ') . " Ar</p> |
<p><strong>ID Avance :</strong> {$avance['avance_id']}</p> |
||||
<p><strong>Montant dû :</strong> " . number_format($avance['amount_due'], 0, ',', ' ') . " Ar</p> |
<p><strong>Client :</strong> {$avance['customer_name']}</p> |
||||
<p><strong>Deadline :</strong> {$deadline}</p> |
<p><strong>Montant avance :</strong> " . number_format($avance['avance_amount'], 0, ',', ' ') . " Ar</p> |
||||
<p><strong>Statut :</strong> <span style='color: red; font-weight: bold;'>{$urgencyText}</span></p> |
<p><strong>Montant dû :</strong> " . number_format($avance['amount_due'], 0, ',', ' ') . " Ar</p> |
||||
<p><strong>Téléphone client :</strong> {$avance['customer_phone']}</p> |
<p><strong>Deadline :</strong> {$deadline}</p> |
||||
<p><strong>Adresse client :</strong> {$avance['customer_address']}</p> |
<p><strong>Statut :</strong> <span style='color: red; font-weight: bold;'>{$urgencyText}</span></p> |
||||
<hr> |
<p><strong>Téléphone client :</strong> {$avance['customer_phone']}</p> |
||||
<p><em>Cette avance " . ($daysLeft === 0 ? "arrive à échéance aujourd'hui" : "arrivera à échéance dans {$daysLeft} jour(s)") . ". Action requise immédiatement.</em></p> |
<p><strong>Adresse client :</strong> {$avance['customer_address']}</p> |
||||
|
<hr style='border: 1px solid #ddd;'> |
||||
|
<p><em>Cette avance " . ($daysLeft === 0 ? "arrive à échéance aujourd'hui" : "arrivera à échéance dans {$daysLeft} jour(s)") . ". Action requise immédiatement.</em></p> |
||||
|
</body> |
||||
|
</html> |
||||
"; |
"; |
||||
|
|
||||
$emailsSent = 0; |
$emailsSent = 0; |
||||
|
$subject = $daysLeft === 0 |
||||
|
? "⚠️ AVANCE URGENTE - ÉCHÉANCE AUJOURD'HUI" |
||||
|
: "⚠️ AVANCE URGENTE - {$daysLeft} jour(s) restant(s)"; |
||||
|
|
||||
foreach ($emails as $to) { |
foreach ($emails as $to) { |
||||
log_message('info', "Tentative d'envoi email à: {$to}"); |
log_message('info', "Tentative d'envoi email à: {$to}"); |
||||
|
|
||||
$subject = $daysLeft === 0 |
if (sendEmailWithBrevo($to, $subject, $message)) { |
||||
? "⚠️ AVANCE URGENTE - ÉCHÉANCE AUJOURD'HUI" |
|
||||
: "⚠️ AVANCE URGENTE - {$daysLeft} jour(s) restant(s)"; |
|
||||
|
|
||||
if (sendEmailInBackground($to, $subject, $message)) { |
|
||||
$emailsSent++; |
$emailsSent++; |
||||
log_message('info', "Email envoyé avec succès à: {$to}"); |
log_message('info', "Email envoyé avec succès à: {$to}"); |
||||
} else { |
} else { |
||||
@ -115,6 +121,7 @@ function checkDeadlineAlerts() |
|||||
} |
} |
||||
} |
} |
||||
|
|
||||
|
// Enregistrement de l'alerte si au moins un email a été envoyé |
||||
if ($emailsSent > 0) { |
if ($emailsSent > 0) { |
||||
log_message('info', "Insertion alerte pour avance_id={$avance['avance_id']} avec type {$alertType}"); |
log_message('info', "Insertion alerte pour avance_id={$avance['avance_id']} avec type {$alertType}"); |
||||
$alertMailModel->insert([ |
$alertMailModel->insert([ |
||||
@ -128,49 +135,182 @@ function checkDeadlineAlerts() |
|||||
log_message('error', "Aucun email envoyé pour avance_id={$avance['avance_id']} avec type {$alertType}"); |
log_message('error', "Aucun email envoyé pour avance_id={$avance['avance_id']} avec type {$alertType}"); |
||||
} |
} |
||||
} |
} |
||||
|
checkAndConvertCompletedAvances(); |
||||
|
|
||||
log_message('info', "=== FIN checkDeadlineAlerts ==="); |
log_message('info', "=== FIN checkDeadlineAlerts ==="); |
||||
|
|
||||
|
// ✅ NOUVELLE FONCTIONNALITÉ : Gérer les avances expirées |
||||
|
handleExpiredAvances(); |
||||
} |
} |
||||
|
|
||||
function sendEmailInBackground($to, $subject, $message) |
/** |
||||
|
* ✅ NOUVELLE FONCTION : Gérer automatiquement les avances expirées |
||||
|
* - Libérer les produits (remettre en stock) |
||||
|
* - Désactiver les avances |
||||
|
*/ |
||||
|
function handleExpiredAvances() |
||||
|
{ |
||||
|
log_message('info', "=== DÉBUT handleExpiredAvances ==="); |
||||
|
|
||||
|
$avanceModel = new Avance(); |
||||
|
$productsModel = new \App\Models\Products(); |
||||
|
|
||||
|
$today = date('Y-m-d'); |
||||
|
log_message('info', "Vérification des avances expirées au: {$today}"); |
||||
|
|
||||
|
// Récupérer les avances expirées et encore actives |
||||
|
$expiredAvances = $avanceModel |
||||
|
->where('DATE(deadline) <', $today) |
||||
|
->where('active', 1) |
||||
|
->where('is_order', 0) |
||||
|
->findAll(); |
||||
|
|
||||
|
log_message('info', "Nombre d'avances expirées trouvées: " . count($expiredAvances)); |
||||
|
|
||||
|
if (empty($expiredAvances)) { |
||||
|
log_message('info', "Aucune avance expirée à traiter"); |
||||
|
log_message('info', "=== FIN handleExpiredAvances ==="); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
$processedCount = 0; |
||||
|
$errorCount = 0; |
||||
|
|
||||
|
foreach ($expiredAvances as $avance) { |
||||
|
try { |
||||
|
log_message('info', "Traitement avance expirée ID: {$avance['avance_id']}, Client: {$avance['customer_name']}, Deadline: {$avance['deadline']}"); |
||||
|
|
||||
|
// ✅ Désactiver l'avance |
||||
|
$updateResult = $avanceModel->update($avance['avance_id'], ['active' => 0]); |
||||
|
|
||||
|
if (!$updateResult) { |
||||
|
log_message('error', "Échec désactivation avance ID: {$avance['avance_id']}"); |
||||
|
$errorCount++; |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
log_message('info', "Avance ID {$avance['avance_id']} désactivée avec succès"); |
||||
|
|
||||
|
// ✅ Libérer le produit UNIQUEMENT pour les avances "sur terre" avec product_id |
||||
|
if ($avance['type_avance'] === 'terre' && !empty($avance['product_id'])) { |
||||
|
$productUpdateResult = $productsModel->update($avance['product_id'], ['product_sold' => 0]); |
||||
|
|
||||
|
if ($productUpdateResult) { |
||||
|
log_message('info', "Produit ID {$avance['product_id']} libéré (remis en stock)"); |
||||
|
} else { |
||||
|
log_message('warning', "Échec libération produit ID: {$avance['product_id']}"); |
||||
|
} |
||||
|
} elseif ($avance['type_avance'] === 'mere') { |
||||
|
log_message('info', "Avance 'sur mer' - Pas de produit à libérer (product_name: {$avance['product_name']})"); |
||||
|
} else { |
||||
|
log_message('info', "Pas de product_id à libérer pour avance ID: {$avance['avance_id']}"); |
||||
|
} |
||||
|
|
||||
|
$processedCount++; |
||||
|
|
||||
|
} catch (\Exception $e) { |
||||
|
log_message('error', "Erreur traitement avance expirée ID {$avance['avance_id']}: " . $e->getMessage()); |
||||
|
$errorCount++; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
log_message('info', "Avances expirées traitées: {$processedCount}, Erreurs: {$errorCount}"); |
||||
|
log_message('info', "=== FIN handleExpiredAvances ==="); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* ✅ Vérifier et convertir automatiquement les avances complètes en commandes |
||||
|
* À appeler dans checkDeadlineAlerts() ou via un cron job |
||||
|
*/ |
||||
|
function checkAndConvertCompletedAvances() |
||||
|
{ |
||||
|
log_message('info', "=== DÉBUT checkAndConvertCompletedAvances ==="); |
||||
|
|
||||
|
$avanceModel = new \App\Models\Avance(); |
||||
|
|
||||
|
// Récupérer toutes les avances complètes non encore converties |
||||
|
$completedAvances = $avanceModel |
||||
|
->where('amount_due', 0) |
||||
|
->where('is_order', 0) // Pas encore converties |
||||
|
->where('active', 1) // Encore actives |
||||
|
->findAll(); |
||||
|
|
||||
|
log_message('info', "Avances complètes trouvées : " . count($completedAvances)); |
||||
|
|
||||
|
$convertedCount = 0; |
||||
|
$errorCount = 0; |
||||
|
|
||||
|
foreach ($completedAvances as $avance) { |
||||
|
log_message('info', "Traitement avance complète ID: {$avance['avance_id']}, Client: {$avance['customer_name']}"); |
||||
|
|
||||
|
$order_id = $avanceModel->convertToOrder($avance['avance_id']); |
||||
|
|
||||
|
if ($order_id) { |
||||
|
$convertedCount++; |
||||
|
log_message('info', "✅ Avance {$avance['avance_id']} convertie en commande {$order_id}"); |
||||
|
} else { |
||||
|
$errorCount++; |
||||
|
log_message('error', "❌ Échec conversion avance {$avance['avance_id']}"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
log_message('info', "Avances converties : {$convertedCount}, Erreurs : {$errorCount}"); |
||||
|
log_message('info', "=== FIN checkAndConvertCompletedAvances ==="); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Envoyer un email via Brevo |
||||
|
*/ |
||||
|
function sendEmailWithBrevo($to, $subject, $message) |
||||
{ |
{ |
||||
try { |
try { |
||||
log_message('info', "Préparation envoi email à: {$to}"); |
log_message('info', "Préparation envoi email via Brevo à: {$to}"); |
||||
|
|
||||
$email = \Config\Services::email(); |
$email = \Config\Services::email(); |
||||
|
|
||||
|
// Configuration Brevo depuis le fichier .env |
||||
$config = [ |
$config = [ |
||||
'protocol' => 'smtp', |
'protocol' => env('email.protocol', 'smtp'), |
||||
'SMTPHost' => 'smtp.gmail.com', |
'SMTPHost' => env('email.SMTPHost', 'smtp-relay.brevo.com'), |
||||
'SMTPUser' => '[email protected]', |
'SMTPUser' => env('email.SMTPUser'), |
||||
'SMTPPass' => 'loirqovmfuxnasrm', |
'SMTPPass' => env('email.SMTPPass'), |
||||
'SMTPPort' => 587, |
'SMTPPort' => env('email.SMTPPort', 587), |
||||
'SMTPCrypto' => 'tls', |
'SMTPCrypto' => env('email.SMTPCrypto', 'tls'), |
||||
'mailType' => 'html', |
'mailType' => 'html', |
||||
'charset' => 'utf-8', |
'charset' => 'utf-8', |
||||
'newline' => "\r\n" |
'newline' => "\r\n", |
||||
|
'wordWrap' => true, |
||||
|
'validation' => true |
||||
]; |
]; |
||||
|
|
||||
|
log_message('info', "Configuration Brevo - Host: {$config['SMTPHost']}, Port: {$config['SMTPPort']}, User: {$config['SMTPUser']}"); |
||||
|
|
||||
$email->initialize($config); |
$email->initialize($config); |
||||
|
|
||||
$email->setFrom('[email protected]', 'Système Motorbike - Alertes Avances'); |
// Utilisation de l'email configuré dans .env |
||||
|
$fromEmail = env('email.fromEmail', '[email protected]'); |
||||
|
$fromName = env('email.fromName', 'Système Motorbike - Alertes'); |
||||
|
|
||||
|
$email->setFrom($fromEmail, $fromName); |
||||
$email->setTo($to); |
$email->setTo($to); |
||||
$email->setSubject($subject); |
$email->setSubject($subject); |
||||
$email->setMessage($message); |
$email->setMessage($message); |
||||
|
|
||||
log_message('info', "Configuration email terminée, tentative d'envoi..."); |
log_message('info', "Configuration email Brevo terminée, tentative d'envoi..."); |
||||
|
|
||||
if (!$email->send()) { |
if (!$email->send()) { |
||||
$debugInfo = $email->printDebugger(['headers']); |
$debugInfo = $email->printDebugger(['headers', 'subject', 'body']); |
||||
log_message('error', "Erreur email à {$to}: " . print_r($debugInfo, true)); |
log_message('error', "Erreur email Brevo à {$to}: " . print_r($debugInfo, true)); |
||||
return false; |
return false; |
||||
} |
} |
||||
|
|
||||
log_message('info', "Email envoyé avec succès à: {$to}"); |
log_message('info', "Email envoyé avec succès via Brevo à: {$to}"); |
||||
return true; |
return true; |
||||
|
|
||||
} catch (\Exception $e) { |
} catch (\Exception $e) { |
||||
log_message('error', "Exception email à {$to}: " . $e->getMessage()); |
log_message('error', "Exception email Brevo à {$to}: " . $e->getMessage()); |
||||
|
log_message('error', "Stack trace: " . $e->getTraceAsString()); |
||||
return false; |
return false; |
||||
} |
} |
||||
} |
} |
||||
File diff suppressed because it is too large
@ -1,96 +1,201 @@ |
|||||
<!DOCTYPE html> |
<!DOCTYPE html> |
||||
<html> |
<html lang="fr"> |
||||
<head> |
<head> |
||||
<meta charset="utf-8"> |
<meta charset="utf-8"> |
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> |
||||
<title>Log in</title> |
<title>Connexion | Motorbike</title> |
||||
<!-- Tell the browser to be responsive to screen width --> |
<meta name="viewport" content="width=device-width, initial-scale=1"> |
||||
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"> |
|
||||
<!-- Bootstrap 3.3.7 --> |
|
||||
<link rel="stylesheet" href="<?php echo base_url('assets/bower_components/bootstrap/dist/css/bootstrap.min.css') ?>"> |
|
||||
|
|
||||
<!-- Font Awesome --> |
<!-- Bootstrap --> |
||||
|
<link rel="stylesheet" href="<?php echo base_url('assets/bower_components/bootstrap/dist/css/bootstrap.min.css') ?>"> |
||||
<link rel="stylesheet" href="<?php echo base_url('assets/bower_components/font-awesome/css/font-awesome.min.css') ?>"> |
<link rel="stylesheet" href="<?php echo base_url('assets/bower_components/font-awesome/css/font-awesome.min.css') ?>"> |
||||
|
<link rel="stylesheet" href="<?php echo base_url('assets/dist/css/AdminLTE.min.css') ?>"> |
||||
|
|
||||
|
<!-- Google Font --> |
||||
|
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet"> |
||||
|
|
||||
<!-- Ionicons --> |
<style> |
||||
<link rel="stylesheet" href="<?php echo base_url('assets/bower_components/Ionicons/css/ionicons.min.css') ?>"> |
body { |
||||
|
font-family: 'Poppins', sans-serif; |
||||
|
background: linear-gradient(135deg, #e9ecef, #dee2e6); |
||||
|
height: 100vh; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
|
||||
<!-- Theme style --> |
.login-card { |
||||
<link rel="stylesheet" href="<?php echo base_url('assets/dist/css/AdminLTE.min.css') ?>"> |
display: flex; |
||||
<!-- iCheck --> |
width: 720px; |
||||
<link rel="stylesheet" href="<?php echo base_url('assets/plugins/iCheck/square/blue.css') ?>"> |
max-width: 95%; |
||||
|
background: #fff; |
||||
|
border-radius: 15px; |
||||
|
overflow: hidden; |
||||
|
box-shadow: 0 6px 20px rgba(0,0,0,0.15); |
||||
|
animation: fadeIn 0.8s ease; |
||||
|
} |
||||
|
|
||||
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> |
/* Partie gauche : image moto */ |
||||
<!-- WARNING: Respond.js doesn't work if you view the page via file:// --> |
.login-image { |
||||
<!--[if lt IE 9]> |
flex: 1; |
||||
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script> |
background: url('https://lh3.googleusercontent.com/p/AF1QipN4iewRbD9iIfbsvyPTD2SGUkxyi952uG30pHD9=s1360-w1360-h1020') center/cover no-repeat; |
||||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> |
/* Alternative possible : |
||||
<![endif]--> |
https://images.unsplash.com/photo-1520975661595-6453be3f7070?auto=format&fit=crop&w=1000&q=80 |
||||
|
(casque de moto) |
||||
|
*/ |
||||
|
position: relative; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
color: #fff; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
<!-- Google Font --> |
.login-image::after { |
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic"> |
content: ""; |
||||
|
position: absolute; |
||||
|
inset: 0; |
||||
|
background: rgba(0, 0, 0, 0.55); |
||||
|
} |
||||
|
|
||||
|
.login-image h1 { |
||||
|
position: relative; |
||||
|
z-index: 1; |
||||
|
font-size: 1.8em; |
||||
|
font-weight: 600; |
||||
|
color: #ffcc00; |
||||
|
} |
||||
|
|
||||
|
.login-image p { |
||||
|
position: relative; |
||||
|
z-index: 1; |
||||
|
font-size: 1em; |
||||
|
max-width: 250px; |
||||
|
margin: 10px auto 0; |
||||
|
line-height: 1.4; |
||||
|
color: #eee; |
||||
|
} |
||||
|
|
||||
|
/* Partie droite : formulaire */ |
||||
|
.login-form { |
||||
|
flex: 1; |
||||
|
padding: 35px 30px; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
|
||||
|
.login-form h2 { |
||||
|
font-weight: 600; |
||||
|
margin-bottom: 25px; |
||||
|
color: #007bff; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.input-group { |
||||
|
margin-bottom: 15px; |
||||
|
} |
||||
|
|
||||
|
.input-group .form-control { |
||||
|
border-radius: 30px; |
||||
|
padding: 10px 20px; |
||||
|
box-shadow: none; |
||||
|
border: 1px solid #ccc; |
||||
|
} |
||||
|
|
||||
|
.input-group-addon { |
||||
|
border-radius: 30px 0 0 30px; |
||||
|
background-color: #f8f9fa; |
||||
|
border: 1px solid #ccc; |
||||
|
border-right: none; |
||||
|
color: #007bff; |
||||
|
} |
||||
|
|
||||
|
.btn-primary { |
||||
|
border-radius: 30px; |
||||
|
background-color: #007bff; |
||||
|
border: none; |
||||
|
padding: 10px 20px; |
||||
|
font-weight: 600; |
||||
|
transition: 0.3s; |
||||
|
} |
||||
|
|
||||
|
.btn-primary:hover { |
||||
|
background-color: #0056b3; |
||||
|
} |
||||
|
|
||||
|
.checkbox label { |
||||
|
font-weight: 400; |
||||
|
color: #555; |
||||
|
} |
||||
|
|
||||
|
.alert { |
||||
|
border-radius: 10px; |
||||
|
} |
||||
|
|
||||
|
@keyframes fadeIn { |
||||
|
from { opacity: 0; transform: translateY(20px); } |
||||
|
to { opacity: 1; transform: translateY(0); } |
||||
|
} |
||||
|
|
||||
|
@media (max-width: 768px) { |
||||
|
.login-card { |
||||
|
flex-direction: column; |
||||
|
width: 90%; |
||||
|
} |
||||
|
.login-image { |
||||
|
height: 160px; |
||||
|
} |
||||
|
.login-form { |
||||
|
padding: 25px; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
</head> |
</head> |
||||
<body class="hold-transition login-page"> |
|
||||
<div class="login-box"> |
|
||||
<div class="login-logo"> |
|
||||
<a href=""><b>Login</b></a> |
|
||||
</div> |
|
||||
<!-- /.login-logo --> |
|
||||
<div class="login-box-body"> |
|
||||
<p class="login-box-msg">Sign in to start your session</p> |
|
||||
|
|
||||
<?php if (session()->getFlashdata('error')): ?> |
<body> |
||||
<div class="alert alert-danger"> |
<div class="login-card"> |
||||
<?= session()->getFlashdata('error') ?> |
|
||||
</div> |
|
||||
<?php endif; ?> |
|
||||
|
|
||||
<form action="<?= base_url('login') ?>" method="post"> |
<!-- Image + message --> |
||||
<div class="form-group has-feedback"> |
<div class="login-image"> |
||||
<input type="email" class="form-control" name="email" id="email" placeholder="Email" autocomplete="off"> |
<div> |
||||
<span class="glyphicon glyphicon-envelope form-control-feedback"></span> |
<h1>Bienvenue chez Motorbike</h1> |
||||
</div> |
<p>Gérez vos avances et opérations avec passion pour la moto.</p> |
||||
<div class="form-group has-feedback"> |
|
||||
<input type="password" class="form-control" name="password" id="password" placeholder="Password" autocomplete="off"> |
|
||||
<span class="glyphicon glyphicon-lock form-control-feedback"></span> |
|
||||
</div> |
</div> |
||||
<div class="row"> |
</div> |
||||
<div class="col-xs-8"> |
|
||||
<div class="checkbox icheck"> |
<!-- Formulaire --> |
||||
<label> |
<div class="login-form"> |
||||
<input type="checkbox"> Remember Me |
<h2>Connexion</h2> |
||||
</label> |
|
||||
</div> |
<?php if (session()->getFlashdata('error')): ?> |
||||
|
<div class="alert alert-danger"> |
||||
|
<?= session()->getFlashdata('error') ?> |
||||
</div> |
</div> |
||||
<!-- /.col --> |
<?php endif; ?> |
||||
<div class="col-xs-4"> |
|
||||
<button type="submit" class="btn btn-primary btn-block btn-flat">Sign In</button> |
<form action="<?= base_url('login') ?>" method="post"> |
||||
|
<div class="input-group"> |
||||
|
<span class="input-group-addon"><i class="fa fa-envelope"></i></span> |
||||
|
<input type="email" class="form-control" name="email" placeholder="Email" required> |
||||
|
</div> |
||||
|
|
||||
|
<div class="input-group"> |
||||
|
<span class="input-group-addon"><i class="fa fa-lock"></i></span> |
||||
|
<input type="password" class="form-control" name="password" placeholder="Mot de passe" required> |
||||
</div> |
</div> |
||||
<!-- /.col --> |
|
||||
</div> |
<div class="checkbox"> |
||||
</form> |
<label><input type="checkbox"> Se souvenir de moi</label> |
||||
|
</div> |
||||
|
|
||||
|
<button type="submit" class="btn btn-primary btn-block">Se connecter</button> |
||||
|
</form> |
||||
|
</div> |
||||
|
|
||||
</div> |
</div> |
||||
<!-- /.login-box-body --> |
|
||||
</div> |
<script src="<?php echo base_url('assets/bower_components/jquery/dist/jquery.min.js') ?>"></script> |
||||
<!-- /.login-box --> |
<script src="<?php echo base_url('assets/bower_components/bootstrap/dist/js/bootstrap.min.js') ?>"></script> |
||||
|
|
||||
<!-- jQuery 3 --> |
|
||||
<script src="<?php echo base_url('assets/bower_components/jquery/dist/jquery.min.js') ?>"></script> |
|
||||
<!-- Bootstrap 3.3.7 --> |
|
||||
<script src="<?php echo base_url('assets/bower_components/bootstrap/dist/js/bootstrap.min.js') ?>"></script> |
|
||||
<!-- iCheck --> |
|
||||
<script src="<?php echo base_url('assets/plugins/iCheck/icheck.min.js') ?>"></script> |
|
||||
|
|
||||
<script> |
|
||||
$(function () { |
|
||||
$('input').iCheck({ |
|
||||
checkboxClass: 'icheckbox_square-blue', |
|
||||
radioClass: 'iradio_square-blue', |
|
||||
increaseArea: '20%' // optional |
|
||||
}); |
|
||||
}); |
|
||||
</script> |
|
||||
</body> |
</body> |
||||
</html> |
</html> |
||||
|
|||||
Loading…
Reference in new issue