init: projet complet copymail pour Raspberry Pi
Stack: Nginx + PHP 8.2 + MariaDB + Postfix + Dovecot + Samba - install.sh: script installation automatisé pour RPi OS Bookworm - Interface web: visionneuse mails + admin (comptes, domaine, dashboard) - Chaque compte mail génère automatiquement un share Samba - Processeur cron: extraction pièces jointes via zbateson/mail-mime-parser - Zéro injection SQL (PDO + prepared statements) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
65
web/includes/layout.php
Normal file
65
web/includes/layout.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
function html_head(string $title): void {
|
||||
$domain = cfg('domain', 'copymail');
|
||||
echo <<<HTML
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{$title} — CopyMail</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css">
|
||||
<link rel="stylesheet" href="/assets/css/style.css">
|
||||
</head>
|
||||
<body>
|
||||
HTML;
|
||||
}
|
||||
|
||||
function html_navbar(string $active = ''): void {
|
||||
$user = current_user();
|
||||
$pages = [
|
||||
'mail' => ['/', 'bi-envelope-fill', 'Courriers'],
|
||||
'accounts' => ['/admin/accounts.php', 'bi-people-fill', 'Comptes'],
|
||||
'domain' => ['/admin/domain.php', 'bi-gear-fill', 'Configuration'],
|
||||
'status' => ['/admin/index.php', 'bi-activity', 'Tableau de bord'],
|
||||
];
|
||||
echo '<nav class="navbar navbar-expand-lg navbar-dark bg-primary mb-4">';
|
||||
echo '<div class="container-fluid">';
|
||||
echo '<a class="navbar-brand fw-bold" href="/"><i class="bi bi-envelope-arrow-down-fill me-2"></i>CopyMail</a>';
|
||||
echo '<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#nav"><span class="navbar-toggler-icon"></span></button>';
|
||||
echo '<div class="collapse navbar-collapse" id="nav"><ul class="navbar-nav me-auto">';
|
||||
foreach ($pages as $key => [$href, $icon, $label]) {
|
||||
$cls = $key === $active ? 'nav-link active' : 'nav-link';
|
||||
echo "<li class=\"nav-item\"><a class=\"{$cls}\" href=\"{$href}\"><i class=\"bi {$icon} me-1\"></i>{$label}</a></li>";
|
||||
}
|
||||
echo '</ul>';
|
||||
echo "<span class=\"navbar-text me-3\"><i class=\"bi bi-person-circle me-1\"></i>{$user}</span>";
|
||||
echo '<a class="btn btn-outline-light btn-sm" href="/logout.php"><i class="bi bi-box-arrow-right me-1"></i>Déconnexion</a>';
|
||||
echo '</div></div></nav>';
|
||||
}
|
||||
|
||||
function html_foot(): void {
|
||||
echo <<<HTML
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="/assets/js/app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
HTML;
|
||||
}
|
||||
|
||||
function flash(string $type, string $msg): void {
|
||||
$_SESSION['flash'] = ['type' => $type, 'msg' => $msg];
|
||||
}
|
||||
|
||||
function flash_render(): void {
|
||||
if (!empty($_SESSION['flash'])) {
|
||||
$f = $_SESSION['flash'];
|
||||
unset($_SESSION['flash']);
|
||||
$icon = $f['type'] === 'success' ? 'check-circle-fill' : 'exclamation-triangle-fill';
|
||||
echo "<div class=\"alert alert-{$f['type']} d-flex align-items-center alert-dismissible fade show\" role=\"alert\">";
|
||||
echo "<i class=\"bi bi-{$icon} me-2\"></i>{$f['msg']}";
|
||||
echo '<button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user