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\AlertMail; |
|||
|
|||
/** |
|||
* Vérifier les deadlines et envoyer des alertes email |
|||
*/ |
|||
function checkDeadlineAlerts() |
|||
{ |
|||
log_message('info', "=== DÉBUT checkDeadlineAlerts ==="); |
|||
|
|||
$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()); |
|||
|
|||
$avanceModel = new Avance(); |
|||
@ -20,15 +21,16 @@ function checkDeadlineAlerts() |
|||
$today = date('Y-m-d'); |
|||
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 |
|||
->where('DATE(deadline) >=', $today) // Inclut le jour même |
|||
->where('DATE(deadline) >=', $today) |
|||
->where('DATE(deadline) <=', date('Y-m-d', strtotime('+3 days'))) |
|||
->where('active', 1) |
|||
->findAll(); |
|||
|
|||
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') |
|||
->join('user_group', 'user_group.user_id = users.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}"); |
|||
|
|||
// Modification des types d'alerte pour 0, 1, 2, 3 jours |
|||
// Détermination du type d'alerte |
|||
$alertType = match($daysLeft) { |
|||
3 => 'deadline_3_days', |
|||
2 => 'deadline_2_days', |
|||
@ -83,31 +85,35 @@ function checkDeadlineAlerts() |
|||
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)"; |
|||
$message = " |
|||
<h3>⚠️ URGENT : Avance approchant de la deadline</h3> |
|||
<p><strong>ID Avance :</strong> {$avance['avance_id']}</p> |
|||
<p><strong>Client :</strong> {$avance['customer_name']}</p> |
|||
<p><strong>Montant avance :</strong> " . number_format($avance['avance_amount'], 0, ',', ' ') . " Ar</p> |
|||
<p><strong>Montant dû :</strong> " . number_format($avance['amount_due'], 0, ',', ' ') . " Ar</p> |
|||
<p><strong>Deadline :</strong> {$deadline}</p> |
|||
<p><strong>Statut :</strong> <span style='color: red; font-weight: bold;'>{$urgencyText}</span></p> |
|||
<p><strong>Téléphone client :</strong> {$avance['customer_phone']}</p> |
|||
<p><strong>Adresse client :</strong> {$avance['customer_address']}</p> |
|||
<hr> |
|||
<p><em>Cette avance " . ($daysLeft === 0 ? "arrive à échéance aujourd'hui" : "arrivera à échéance dans {$daysLeft} jour(s)") . ". Action requise immédiatement.</em></p> |
|||
<html> |
|||
<body style='font-family: Arial, sans-serif; color: #333;'> |
|||
<h3 style='color: #d9534f;'>⚠️ URGENT : Avance approchant de la deadline</h3> |
|||
<p><strong>ID Avance :</strong> {$avance['avance_id']}</p> |
|||
<p><strong>Client :</strong> {$avance['customer_name']}</p> |
|||
<p><strong>Montant avance :</strong> " . number_format($avance['avance_amount'], 0, ',', ' ') . " Ar</p> |
|||
<p><strong>Montant dû :</strong> " . number_format($avance['amount_due'], 0, ',', ' ') . " Ar</p> |
|||
<p><strong>Deadline :</strong> {$deadline}</p> |
|||
<p><strong>Statut :</strong> <span style='color: red; font-weight: bold;'>{$urgencyText}</span></p> |
|||
<p><strong>Téléphone client :</strong> {$avance['customer_phone']}</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; |
|||
$subject = $daysLeft === 0 |
|||
? "⚠️ AVANCE URGENTE - ÉCHÉANCE AUJOURD'HUI" |
|||
: "⚠️ AVANCE URGENTE - {$daysLeft} jour(s) restant(s)"; |
|||
|
|||
foreach ($emails as $to) { |
|||
log_message('info', "Tentative d'envoi email à: {$to}"); |
|||
|
|||
$subject = $daysLeft === 0 |
|||
? "⚠️ AVANCE URGENTE - ÉCHÉANCE AUJOURD'HUI" |
|||
: "⚠️ AVANCE URGENTE - {$daysLeft} jour(s) restant(s)"; |
|||
|
|||
if (sendEmailInBackground($to, $subject, $message)) { |
|||
if (sendEmailWithBrevo($to, $subject, $message)) { |
|||
$emailsSent++; |
|||
log_message('info', "Email envoyé avec succès à: {$to}"); |
|||
} else { |
|||
@ -115,6 +121,7 @@ function checkDeadlineAlerts() |
|||
} |
|||
} |
|||
|
|||
// Enregistrement de l'alerte si au moins un email a été envoyé |
|||
if ($emailsSent > 0) { |
|||
log_message('info', "Insertion alerte pour avance_id={$avance['avance_id']} avec type {$alertType}"); |
|||
$alertMailModel->insert([ |
|||
@ -128,49 +135,182 @@ function checkDeadlineAlerts() |
|||
log_message('error', "Aucun email envoyé pour avance_id={$avance['avance_id']} avec type {$alertType}"); |
|||
} |
|||
} |
|||
|
|||
checkAndConvertCompletedAvances(); |
|||
|
|||
log_message('info', "=== FIN checkDeadlineAlerts ==="); |
|||
|
|||
// ✅ NOUVELLE FONCTIONNALITÉ : Gérer les avances expirées |
|||
handleExpiredAvances(); |
|||
} |
|||
|
|||
/** |
|||
* ✅ 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 ==="); |
|||
} |
|||
|
|||
function sendEmailInBackground($to, $subject, $message) |
|||
|
|||
/** |
|||
* Envoyer un email via Brevo |
|||
*/ |
|||
function sendEmailWithBrevo($to, $subject, $message) |
|||
{ |
|||
try { |
|||
log_message('info', "Préparation envoi email à: {$to}"); |
|||
log_message('info', "Préparation envoi email via Brevo à: {$to}"); |
|||
|
|||
$email = \Config\Services::email(); |
|||
|
|||
// Configuration Brevo depuis le fichier .env |
|||
$config = [ |
|||
'protocol' => 'smtp', |
|||
'SMTPHost' => 'smtp.gmail.com', |
|||
'SMTPUser' => '[email protected]', |
|||
'SMTPPass' => 'loirqovmfuxnasrm', |
|||
'SMTPPort' => 587, |
|||
'SMTPCrypto' => 'tls', |
|||
'mailType' => 'html', |
|||
'charset' => 'utf-8', |
|||
'newline' => "\r\n" |
|||
'protocol' => env('email.protocol', 'smtp'), |
|||
'SMTPHost' => env('email.SMTPHost', 'smtp-relay.brevo.com'), |
|||
'SMTPUser' => env('email.SMTPUser'), |
|||
'SMTPPass' => env('email.SMTPPass'), |
|||
'SMTPPort' => env('email.SMTPPort', 587), |
|||
'SMTPCrypto' => env('email.SMTPCrypto', 'tls'), |
|||
'mailType' => 'html', |
|||
'charset' => 'utf-8', |
|||
'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->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->setSubject($subject); |
|||
$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()) { |
|||
$debugInfo = $email->printDebugger(['headers']); |
|||
log_message('error', "Erreur email à {$to}: " . print_r($debugInfo, true)); |
|||
$debugInfo = $email->printDebugger(['headers', 'subject', 'body']); |
|||
log_message('error', "Erreur email Brevo à {$to}: " . print_r($debugInfo, true)); |
|||
return false; |
|||
} |
|||
|
|||
log_message('info', "Email envoyé avec succès à: {$to}"); |
|||
log_message('info', "Email envoyé avec succès via Brevo à: {$to}"); |
|||
return true; |
|||
|
|||
} 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; |
|||
} |
|||
} |
|||
File diff suppressed because it is too large
@ -1,96 +1,201 @@ |
|||
<!DOCTYPE html> |
|||
<html> |
|||
<html lang="fr"> |
|||
<head> |
|||
<meta charset="utf-8"> |
|||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> |
|||
<title>Log in</title> |
|||
<!-- Tell the browser to be responsive to screen width --> |
|||
<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') ?>"> |
|||
<title>Connexion | Motorbike</title> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1"> |
|||
|
|||
<!-- 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/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 --> |
|||
<link rel="stylesheet" href="<?php echo base_url('assets/bower_components/Ionicons/css/ionicons.min.css') ?>"> |
|||
<style> |
|||
body { |
|||
font-family: 'Poppins', sans-serif; |
|||
background: linear-gradient(135deg, #e9ecef, #dee2e6); |
|||
height: 100vh; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
|
|||
<!-- Theme style --> |
|||
<link rel="stylesheet" href="<?php echo base_url('assets/dist/css/AdminLTE.min.css') ?>"> |
|||
<!-- iCheck --> |
|||
<link rel="stylesheet" href="<?php echo base_url('assets/plugins/iCheck/square/blue.css') ?>"> |
|||
.login-card { |
|||
display: flex; |
|||
width: 720px; |
|||
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 --> |
|||
<!-- WARNING: Respond.js doesn't work if you view the page via file:// --> |
|||
<!--[if lt IE 9]> |
|||
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script> |
|||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> |
|||
<![endif]--> |
|||
/* Partie gauche : image moto */ |
|||
.login-image { |
|||
flex: 1; |
|||
background: url('https://lh3.googleusercontent.com/p/AF1QipN4iewRbD9iIfbsvyPTD2SGUkxyi952uG30pHD9=s1360-w1360-h1020') center/cover no-repeat; |
|||
/* Alternative possible : |
|||
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 --> |
|||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic"> |
|||
.login-image::after { |
|||
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> |
|||
<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')): ?> |
|||
<div class="alert alert-danger"> |
|||
<?= session()->getFlashdata('error') ?> |
|||
</div> |
|||
<?php endif; ?> |
|||
<body> |
|||
<div class="login-card"> |
|||
|
|||
<form action="<?= base_url('login') ?>" method="post"> |
|||
<div class="form-group has-feedback"> |
|||
<input type="email" class="form-control" name="email" id="email" placeholder="Email" autocomplete="off"> |
|||
<span class="glyphicon glyphicon-envelope form-control-feedback"></span> |
|||
</div> |
|||
<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> |
|||
<!-- Image + message --> |
|||
<div class="login-image"> |
|||
<div> |
|||
<h1>Bienvenue chez Motorbike</h1> |
|||
<p>Gérez vos avances et opérations avec passion pour la moto.</p> |
|||
</div> |
|||
<div class="row"> |
|||
<div class="col-xs-8"> |
|||
<div class="checkbox icheck"> |
|||
<label> |
|||
<input type="checkbox"> Remember Me |
|||
</label> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Formulaire --> |
|||
<div class="login-form"> |
|||
<h2>Connexion</h2> |
|||
|
|||
<?php if (session()->getFlashdata('error')): ?> |
|||
<div class="alert alert-danger"> |
|||
<?= session()->getFlashdata('error') ?> |
|||
</div> |
|||
<!-- /.col --> |
|||
<div class="col-xs-4"> |
|||
<button type="submit" class="btn btn-primary btn-block btn-flat">Sign In</button> |
|||
<?php endif; ?> |
|||
|
|||
<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> |
|||
<!-- /.col --> |
|||
</div> |
|||
</form> |
|||
|
|||
<div class="checkbox"> |
|||
<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> |
|||
<!-- /.login-box-body --> |
|||
</div> |
|||
<!-- /.login-box --> |
|||
|
|||
<!-- 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> |
|||
|
|||
<script src="<?php echo base_url('assets/bower_components/jquery/dist/jquery.min.js') ?>"></script> |
|||
<script src="<?php echo base_url('assets/bower_components/bootstrap/dist/js/bootstrap.min.js') ?>"></script> |
|||
</body> |
|||
</html> |
|||
|
|||
Loading…
Reference in new issue