mirror of
https://github.com/tips-of-mine/gestion-certificats2.git
synced 2025-07-02 11:38:42 +02:00
Add files via upload
This commit is contained in:
51
app/src/Views/auth/login.php
Normal file
51
app/src/Views/auth/login.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
// On assume que $translations, $currentLang, $darkModeClass et $error sont définis par le contrôleur
|
||||
// global $translations; // Déjà global dans index.php si utilisé ici
|
||||
// global $currentLang;
|
||||
// global $darkModeClass;
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="<?= htmlspecialchars($currentLang) ?>">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title><?= htmlspecialchars($translations['login_title']) ?></title>
|
||||
<link rel="stylesheet" href="/style.css">
|
||||
<link rel="stylesheet" href="/dark-mode.css">
|
||||
</head>
|
||||
<body class="<?= htmlspecialchars($darkModeClass) ?>">
|
||||
<div class="container">
|
||||
<h1><?= htmlspecialchars($translations['login_heading']) ?></h1>
|
||||
|
||||
<?php if (isset($error)): ?>
|
||||
<p class="error-message"><?= htmlspecialchars($error); ?></p>
|
||||
<?php endif; ?>
|
||||
|
||||
<form action="/login" method="post">
|
||||
<label for="username"><?= htmlspecialchars($translations['username']) ?>:</label><br>
|
||||
<input type="text" id="username" name="username" required autocomplete="username"><br><br>
|
||||
|
||||
<label for="password"><?= htmlspecialchars($translations['password']) ?>:</label><br>
|
||||
<input type="password" id="password" name="password" required autocomplete="current-password"><br><br>
|
||||
|
||||
<button type="submit" class="button primary-button"><?= htmlspecialchars($translations['login_button']) ?></button>
|
||||
</form>
|
||||
|
||||
<div class="options">
|
||||
<!-- Boutons de changement de langue -->
|
||||
<div class="language-switcher">
|
||||
<?php foreach (SUPPORTED_LANGUAGES as $lang): ?>
|
||||
<a href="?lang=<?= htmlspecialchars($lang) ?>" class="<?= $currentLang === $lang ? 'active' : '' ?>"><?= htmlspecialchars(strtoupper($lang)) ?></a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<!-- Bouton de bascule du mode sombre -->
|
||||
<div class="dark-mode-switcher">
|
||||
<a href="?dark_mode=<?= \App\Utils\DarkMode::isEnabled() ? 'off' : 'on' ?>" class="button secondary-button">
|
||||
<?= \App\Utils\DarkMode::isEnabled() ? htmlspecialchars($translations['light_mode']) : htmlspecialchars($translations['dark_mode']) ?>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
32
app/src/Views/certificates/create.php
Normal file
32
app/src/Views/certificates/create.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
// Variables attendues du contrôleur: $perimeters, $translations, $currentLang, $darkModeClass, $errorMessage
|
||||
require_once APP_ROOT_DIR . '/src/Views/shared/header.php';
|
||||
?>
|
||||
|
||||
<div class="container">
|
||||
<h1><?= htmlspecialchars($translations['new_certificate_heading']) ?></h1>
|
||||
<a href="/certificates" class="button secondary-button"><?= htmlspecialchars($translations['back_to_cert_list']) ?></a>
|
||||
|
||||
<?php if (isset($errorMessage)): ?>
|
||||
<p class="error-message"><?= htmlspecialchars($errorMessage); ?></p>
|
||||
<?php endif; ?>
|
||||
|
||||
<form action="/certificates/create" method="post">
|
||||
<label for="subdomain_name"><?= htmlspecialchars($translations['subdomain_name']) ?>:</label><br>
|
||||
<input type="text" id="subdomain_name" name="subdomain_name" required placeholder="ex: www, api, mail"><br><br>
|
||||
|
||||
<label for="functional_perimeter_id"><?= htmlspecialchars($translations['select_perimeter']) ?>:</label><br>
|
||||
<select id="functional_perimeter_id" name="functional_perimeter_id" required>
|
||||
<option value="">-- <?= htmlspecialchars($translations['select_perimeter_placeholder']) ?> --</option>
|
||||
<?php foreach ($perimeters as $perimeter): ?>
|
||||
<option value="<?= htmlspecialchars($perimeter['id']) ?>"><?= htmlspecialchars($perimeter['name']) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select><br><br>
|
||||
|
||||
<button type="submit" class="button primary-button"><?= htmlspecialchars($translations['create_certificate']) ?></button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once APP_ROOT_DIR . '/src/Views/shared/footer.php';
|
||||
?>
|
71
app/src/Views/certificates/index.php
Normal file
71
app/src/Views/certificates/index.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
// Variables attendues du contrôleur: $groupedCertificates, $translations, $currentLang, $darkModeClass, $successMessage, $errorMessage, $userRole
|
||||
require_once APP_ROOT_DIR . '/src/Views/shared/header.php';
|
||||
?>
|
||||
|
||||
<div class="container">
|
||||
<h1><?= htmlspecialchars($translations['certificates']) ?></h1>
|
||||
<div class="actions-bar">
|
||||
<a href="/dashboard" class="button secondary-button"><?= htmlspecialchars($translations['back_to_dashboard']) ?></a>
|
||||
<a href="/certificates/create" class="button primary-button"><?= htmlspecialchars($translations['create_new_certificate']) ?></a>
|
||||
</div>
|
||||
|
||||
<?php if (isset($successMessage)): ?>
|
||||
<p class="success-message"><?= htmlspecialchars($successMessage); ?></p>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($errorMessage)): ?>
|
||||
<p class="error-message"><?= htmlspecialchars($errorMessage); ?></p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (empty($groupedCertificates)): ?>
|
||||
<p><?= htmlspecialchars($translations['no_certificates_yet']) ?></p>
|
||||
<?php else: ?>
|
||||
<?php foreach ($groupedCertificates as $perimeterName => $certsInPerimeter): ?>
|
||||
<h2 class="perimeter-heading"><?= htmlspecialchars($perimeterName) ?></h2>
|
||||
<div class="table-responsive">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?= htmlspecialchars($translations['certificate_name']) ?></th>
|
||||
<th><?= htmlspecialchars($translations['type']) ?></th>
|
||||
<th><?= htmlspecialchars($translations['expiration_date']) ?></th>
|
||||
<th><?= htmlspecialchars($translations['status']) ?></th>
|
||||
<th><?= htmlspecialchars($translations['actions']) ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($certsInPerimeter as $cert): ?>
|
||||
<tr class="<?= $cert['is_revoked'] ? 'revoked-cert' : '' ?>">
|
||||
<td><?= htmlspecialchars($cert['name']) ?></td>
|
||||
<td><?= htmlspecialchars($translations[$cert['type']] ?? $cert['type']) ?></td>
|
||||
<td><?= htmlspecialchars((new DateTime($cert['expiration_date']))->format('Y-m-d')) ?></td>
|
||||
<td>
|
||||
<?php if ($cert['is_revoked']): ?>
|
||||
<span class="status-revoked"><?= htmlspecialchars($translations['revoked']) ?></span>
|
||||
(<?= htmlspecialchars((new DateTime($cert['revoked_at']))->format('Y-m-d')) ?>)
|
||||
<?php else: ?>
|
||||
<span class="status-active"><?= htmlspecialchars($translations['active']) ?></span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php
|
||||
// Seuls les certificats 'simple' et non révoqués peuvent être révoqués via l'interface
|
||||
if (!$cert['is_revoked'] && $cert['type'] === 'simple'): ?>
|
||||
<form action="/certificates/revoke" method="post" class="inline-form" onsubmit="return confirm('<?= htmlspecialchars($translations['confirm_revoke']) ?>');">
|
||||
<input type="hidden" name="certificate_id" value="<?= htmlspecialchars($cert['id']) ?>">
|
||||
<button type="submit" class="button danger-button"><?= htmlspecialchars($translations['revoke_certificate']) ?></button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once APP_ROOT_DIR . '/src/Views/shared/footer.php';
|
||||
?>
|
34
app/src/Views/dashboard/index.php
Normal file
34
app/src/Views/dashboard/index.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
// Variables attendues du contrôleur: $translations, $currentLang, $darkModeClass, $username, $userRole
|
||||
require_once APP_ROOT_DIR . '/src/Views/shared/header.php';
|
||||
?>
|
||||
|
||||
<div class="container">
|
||||
<h1><?= str_replace('{username}', htmlspecialchars($username), htmlspecialchars($translations['welcome'])) ?></h1>
|
||||
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="/certificates"><?= htmlspecialchars($translations['certificates']) ?></a></li>
|
||||
<li><a href="/perimeters"><?= htmlspecialchars($translations['functional_perimeters']) ?></a></li>
|
||||
<?php if ($userRole === 'admin'): ?>
|
||||
<li><a href="/users"><?= htmlspecialchars($translations['users']) ?></a></li>
|
||||
<?php endif; ?>
|
||||
<li><a href="/logout" class="button logout-button"><?= htmlspecialchars($translations['logout']) ?></a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<section class="quick-actions">
|
||||
<h2><?= htmlspecialchars($translations['quick_actions']) ?></h2>
|
||||
<ul>
|
||||
<li><a href="/certificates/create" class="button create-button"><?= htmlspecialchars($translations['create_new_certificate']) ?></a></li>
|
||||
<li><a href="/perimeters/create" class="button create-button"><?= htmlspecialchars($translations['create_new_perimeter']) ?></a></li>
|
||||
<?php if ($userRole === 'admin'): ?>
|
||||
<li><a href="/users/create" class="button create-button"><?= htmlspecialchars($translations['new_user']) ?></a></li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once APP_ROOT_DIR . '/src/Views/shared/footer.php';
|
||||
?>
|
24
app/src/Views/perimeters/create.php
Normal file
24
app/src/Views/perimeters/create.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
// Variables attendues du contrôleur: $translations, $currentLang, $darkModeClass, $errorMessage
|
||||
require_once APP_ROOT_DIR . '/src/Views/shared/header.php';
|
||||
?>
|
||||
|
||||
<div class="container">
|
||||
<h1><?= htmlspecialchars($translations['create_new_perimeter']) ?></h1>
|
||||
<a href="/perimeters" class="button secondary-button"><?= htmlspecialchars($translations['back_to_perimeter_list']) ?></a>
|
||||
|
||||
<?php if (isset($errorMessage)): ?>
|
||||
<p class="error-message"><?= htmlspecialchars($errorMessage); ?></p>
|
||||
<?php endif; ?>
|
||||
|
||||
<form action="/perimeters/create" method="post">
|
||||
<label for="name"><?= htmlspecialchars($translations['perimeter_name']) ?>:</label><br>
|
||||
<input type="text" id="name" name="name" required placeholder="ex: Finance, RH, Marketing"><br><br>
|
||||
|
||||
<button type="submit" class="button primary-button"><?= htmlspecialchars($translations['create_perimeter_button']) ?></button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once APP_ROOT_DIR . '/src/Views/shared/footer.php';
|
||||
?>
|
51
app/src/Views/perimeters/index.php
Normal file
51
app/src/Views/perimeters/index.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
// Variables attendues du contrôleur: $perimeters, $translations, $currentLang, $darkModeClass, $successMessage, $errorMessage
|
||||
require_once APP_ROOT_DIR . '/src/Views/shared/header.php';
|
||||
?>
|
||||
|
||||
<div class="container">
|
||||
<h1><?= htmlspecialchars($translations['functional_perimeters']) ?></h1>
|
||||
<div class="actions-bar">
|
||||
<a href="/dashboard" class="button secondary-button"><?= htmlspecialchars($translations['back_to_dashboard']) ?></a>
|
||||
<?php if ($userRole === 'admin'): ?>
|
||||
<a href="/perimeters/create" class="button primary-button"><?= htmlspecialchars($translations['create_new_perimeter']) ?></a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if (isset($successMessage)): ?>
|
||||
<p class="success-message"><?= htmlspecialchars($successMessage); ?></p>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($errorMessage)): ?>
|
||||
<p class="error-message"><?= htmlspecialchars($errorMessage); ?></p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (empty($perimeters)): ?>
|
||||
<p><?= htmlspecialchars($translations['no_perimeters_yet']) ?></p>
|
||||
<?php else: ?>
|
||||
<div class="table-responsive">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?= htmlspecialchars($translations['perimeter_name']) ?></th>
|
||||
<th><?= htmlspecialchars($translations['intermediate_cert_file']) ?></th>
|
||||
<th><?= htmlspecialchars($translations['created_at']) ?></th>
|
||||
<!-- Ajouter des actions ici si nécessaire, comme supprimer un périmètre (avec prudence!) -->
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($perimeters as $perimeter): ?>
|
||||
<tr>
|
||||
<td><?= htmlspecialchars($perimeter['name']) ?></td>
|
||||
<td><?= htmlspecialchars($perimeter['intermediate_cert_name']) ?></td>
|
||||
<td><?= htmlspecialchars((new DateTime($perimeter['created_at']))->format('Y-m-d H:i:s')) ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once APP_ROOT_DIR . '/src/Views/shared/footer.php';
|
||||
?>
|
8
app/src/Views/shared/footer.php
Normal file
8
app/src/Views/shared/footer.php
Normal file
@ -0,0 +1,8 @@
|
||||
</main>
|
||||
<footer class="app-footer">
|
||||
<div class="container">
|
||||
<p>© <?= date('Y') ?> <?= htmlspecialchars($translations['app_name'] ?? 'Gestion Certificat') ?>. Tous droits réservés.</p>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
39
app/src/Views/shared/header.php
Normal file
39
app/src/Views/shared/header.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
// Variables attendues: $translations, $currentLang, $darkModeClass
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="<?= htmlspecialchars($currentLang) ?>">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title><?= htmlspecialchars($translations['app_name'] ?? 'Gestion Certificat') ?></title>
|
||||
<link rel="stylesheet" href="/css/style.css">
|
||||
<link rel="stylesheet" href="/css/dark-mode.css">
|
||||
<!-- Font Awesome pour les icônes si besoin -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
|
||||
</head>
|
||||
<body class="<?= htmlspecialchars($darkModeClass) ?>">
|
||||
<header class="app-header">
|
||||
<div class="header-content container">
|
||||
<div class="app-title">
|
||||
<h1><?= htmlspecialchars($translations['app_name'] ?? 'Gestion Certificat') ?></h1>
|
||||
</div>
|
||||
<div class="header-controls">
|
||||
<div class="language-switcher">
|
||||
<?php foreach (SUPPORTED_LANGUAGES as $lang): ?>
|
||||
<a href="?lang=<?= htmlspecialchars($lang) ?>" class="lang-button <?= $currentLang === $lang ? 'active' : '' ?>"><?= htmlspecialchars(strtoupper($lang)) ?></a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<div class="dark-mode-switcher">
|
||||
<a href="?dark_mode=<?= \App\Utils\DarkMode::isEnabled() ? 'off' : 'on' ?>" class="dark-mode-button">
|
||||
<?php if (\App\Utils\DarkMode::isEnabled()): ?>
|
||||
<i class="fas fa-sun"></i> <?= htmlspecialchars($translations['light_mode']) ?>
|
||||
<?php else: ?>
|
||||
<i class="fas fa-moon"></i> <?= htmlspecialchars($translations['dark_mode']) ?>
|
||||
<?php endif; ?>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main>
|
33
app/src/Views/users/create.php
Normal file
33
app/src/Views/users/create.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
// Variables attendues du contrôleur: $translations, $currentLang, $darkModeClass, $errorMessage
|
||||
require_once APP_ROOT_DIR . '/src/Views/shared/header.php';
|
||||
?>
|
||||
|
||||
<div class="container">
|
||||
<h1><?= htmlspecialchars($translations['create_new_user']) ?></h1>
|
||||
<a href="/users" class="button secondary-button"><?= htmlspecialchars($translations['back_to_user_list']) ?></a>
|
||||
|
||||
<?php if (isset($errorMessage)): ?>
|
||||
<p class="error-message"><?= htmlspecialchars($errorMessage); ?></p>
|
||||
<?php endif; ?>
|
||||
|
||||
<form action="/users/create" method="post">
|
||||
<label for="username"><?= htmlspecialchars($translations['username']) ?>:</label><br>
|
||||
<input type="text" id="username" name="username" required autocomplete="new-username"><br><br>
|
||||
|
||||
<label for="password"><?= htmlspecialchars($translations['password']) ?>:</label><br>
|
||||
<input type="password" id="password" name="password" required autocomplete="new-password"><br><br>
|
||||
|
||||
<label for="role"><?= htmlspecialchars($translations['user_role']) ?>:</label><br>
|
||||
<select id="role" name="role" required>
|
||||
<option value="user"><?= htmlspecialchars($translations['user']) ?></option>
|
||||
<option value="admin"><?= htmlspecialchars($translations['admin']) ?></option>
|
||||
</select><br><br>
|
||||
|
||||
<button type="submit" class="button primary-button"><?= htmlspecialchars($translations['create_user_button']) ?></button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once APP_ROOT_DIR . '/src/Views/shared/footer.php';
|
||||
?>
|
59
app/src/Views/users/index.php
Normal file
59
app/src/Views/users/index.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
// Variables attendues du contrôleur: $users, $translations, $currentLang, $darkModeClass, $successMessage, $errorMessage, $authService (pour getUserId)
|
||||
require_once APP_ROOT_DIR . '/src/Views/shared/header.php';
|
||||
?>
|
||||
|
||||
<div class="container">
|
||||
<h1><?= htmlspecialchars($translations['users']) ?></h1>
|
||||
<div class="actions-bar">
|
||||
<a href="/dashboard" class="button secondary-button"><?= htmlspecialchars($translations['back_to_dashboard']) ?></a>
|
||||
<a href="/users/create" class="button primary-button"><?= htmlspecialchars($translations['create_new_user']) ?></a>
|
||||
</div>
|
||||
|
||||
<?php if (isset($successMessage)): ?>
|
||||
<p class="success-message"><?= htmlspecialchars($successMessage); ?></p>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($errorMessage)): ?>
|
||||
<p class="error-message"><?= htmlspecialchars($errorMessage); ?></p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (empty($users)): ?>
|
||||
<p><?= htmlspecialchars($translations['no_users_yet']) ?></p>
|
||||
<?php else: ?>
|
||||
<div class="table-responsive">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?= htmlspecialchars($translations['username']) ?></th>
|
||||
<th><?= htmlspecialchars($translations['user_role']) ?></th>
|
||||
<th><?= htmlspecialchars($translations['created_at']) ?></th>
|
||||
<th><?= htmlspecialchars($translations['actions']) ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($users as $user): ?>
|
||||
<tr>
|
||||
<td><?= htmlspecialchars($user['username']) ?></td>
|
||||
<td><?= htmlspecialchars($translations[$user['role']] ?? $user['role']) ?></td>
|
||||
<td><?= htmlspecialchars((new DateTime($user['created_at']))->format('Y-m-d H:i:s')) ?></td>
|
||||
<td>
|
||||
<?php if ($user['id'] !== $authService->getUserId()): // Impossible de supprimer son propre compte ?>
|
||||
<form action="/users/delete" method="post" class="inline-form" onsubmit="return confirm('<?= htmlspecialchars($translations['confirm_delete_user']) ?>');">
|
||||
<input type="hidden" name="user_id" value="<?= htmlspecialchars($user['id']) ?>">
|
||||
<button type="submit" class="button danger-button"><?= htmlspecialchars($translations['delete_user']) ?></button>
|
||||
</form>
|
||||
<?php else: ?>
|
||||
<em><?= htmlspecialchars($translations['self_delete_not_allowed']) ?></em>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once APP_ROOT_DIR . '/src/Views/shared/footer.php';
|
||||
?>
|
Reference in New Issue
Block a user