Initial New Repo & Env new method
This commit is contained in:
commit
e859270e65
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
_conf/.env
|
||||||
|
.git
|
5
_conf/.env.example
Normal file
5
_conf/.env.example
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
DB_HOST=localhost
|
||||||
|
DB_PORT=3306
|
||||||
|
DB_NAME=my_webapp
|
||||||
|
DB_USER=my_webapp
|
||||||
|
DB_PASSWORD=mypassword
|
19
_conf/db.php
Normal file
19
_conf/db.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
include_once __DIR__ . '/env.php';
|
||||||
|
|
||||||
|
// Database configuration
|
||||||
|
$db['host'] = $env['DB_HOST'] ?? 'localhost';
|
||||||
|
$db['name'] = $env['DB_NAME'] ?? 'my_webapp';
|
||||||
|
$db['user'] = $env['DB_USER'] ?? 'my_webapp';
|
||||||
|
$db['pass'] = $env['DB_PASS'] ?? 'my_webapp_pass';
|
||||||
|
$db['port'] = $env['DB_PORT'] ?? '3306';
|
||||||
|
|
||||||
|
if (!$db['host'] || !$db['name'] || !$db['user'] || !$db['pass'] || !$db['port']) {
|
||||||
|
die("DB configuration error: missing parameters. Please check your environment variables.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$db['dsn'] = 'mysql:host=' . $db['host'] . ';port='. $db['port'] .';dbname=' . $db['name'] . ';charset=utf8mb4';
|
||||||
|
|
||||||
|
?>
|
24
_conf/env.php
Normal file
24
_conf/env.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
function loadEnv($path) {
|
||||||
|
if (!file_exists($path)) return;
|
||||||
|
|
||||||
|
$lines = file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||||
|
|
||||||
|
foreach ($lines as $line) {
|
||||||
|
if (str_starts_with(trim($line), '#')) continue;
|
||||||
|
|
||||||
|
list($key, $value) = explode('=', $line, 2);
|
||||||
|
$key = trim($key);
|
||||||
|
$value = trim($value);
|
||||||
|
|
||||||
|
putenv("$key=$value");
|
||||||
|
$_ENV[$key] = $value;
|
||||||
|
$_SERVER[$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loadEnv(__DIR__ . '/.env');
|
||||||
|
$env = $_ENV;
|
||||||
|
|
||||||
|
?>
|
14
_conf/global.php
Normal file
14
_conf/global.php
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$config['site'] = [
|
||||||
|
'name' => "KVS.FYI",
|
||||||
|
'main_domain' => "kvs.fyi",
|
||||||
|
'imgs_domain' => "xbb.kvs.fyi"
|
||||||
|
];
|
||||||
|
|
||||||
|
$config['author'] = [
|
||||||
|
'name' => "Kryscau",
|
||||||
|
'bio' => "https://e-z.bio/kryscau"
|
||||||
|
];
|
||||||
|
|
||||||
|
?>
|
153
admin/--edit-pwd
Normal file
153
admin/--edit-pwd
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
// Message d'erreur/succès
|
||||||
|
$message = '';
|
||||||
|
|
||||||
|
// Traitement du formulaire
|
||||||
|
if (isset($_POST['submit'])) {
|
||||||
|
$new_password = $_POST['password'];
|
||||||
|
|
||||||
|
if (empty($new_password)) {
|
||||||
|
$message = '<div style="color: red; margin-bottom: 15px;">Le mot de passe ne peut pas être vide!</div>';
|
||||||
|
} else {
|
||||||
|
// Générer le hash avec bcrypt
|
||||||
|
$hash = password_hash($new_password, PASSWORD_BCRYPT);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Connexion à la base de données
|
||||||
|
$pdo = new PDO("mysql:host=$db_host;dbname=$db_name;charset=utf8mb4", $db_user, $db_pass);
|
||||||
|
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||||
|
|
||||||
|
// Vérifier si la table admin existe
|
||||||
|
$tables = $pdo->query("SHOW TABLES LIKE 'admin'")->fetchAll();
|
||||||
|
|
||||||
|
if (count($tables) === 0) {
|
||||||
|
// Créer la table admin si elle n'existe pas
|
||||||
|
$pdo->exec("CREATE TABLE IF NOT EXISTS `admin` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`password_hash` varchar(255) NOT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
|
||||||
|
|
||||||
|
// Insérer le nouveau mot de passe
|
||||||
|
$stmt = $pdo->prepare("INSERT INTO admin (password_hash) VALUES (?)");
|
||||||
|
$stmt->execute([$hash]);
|
||||||
|
} else {
|
||||||
|
// Vérifier si un enregistrement existe déjà
|
||||||
|
$count = $pdo->query("SELECT COUNT(*) FROM admin")->fetchColumn();
|
||||||
|
|
||||||
|
if ($count > 0) {
|
||||||
|
// Mettre à jour le mot de passe existant
|
||||||
|
$stmt = $pdo->prepare("UPDATE admin SET password_hash = ? WHERE id = 1");
|
||||||
|
$stmt->execute([$hash]);
|
||||||
|
} else {
|
||||||
|
// Insérer un nouveau mot de passe
|
||||||
|
$stmt = $pdo->prepare("INSERT INTO admin (password_hash) VALUES (?)");
|
||||||
|
$stmt->execute([$hash]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$message = '<div style="color: green; margin-bottom: 15px;">
|
||||||
|
<p><strong>Mot de passe mis à jour avec succès!</strong></p>
|
||||||
|
<p>Votre nouveau mot de passe: <strong>' . htmlspecialchars($new_password) . '</strong></p>
|
||||||
|
<p>Hash généré: <code>' . $hash . '</code></p>
|
||||||
|
<p><strong>IMPORTANT:</strong> Supprimez ce fichier immédiatement après utilisation!</p>
|
||||||
|
</div>';
|
||||||
|
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$message = '<div style="color: red; margin-bottom: 15px;">Erreur: ' . $e->getMessage() . '</div>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Mise à jour du mot de passe admin</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
||||||
|
line-height: 1.6;
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #f8fafc;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
color: #4f46e5;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.card {
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 20px;
|
||||||
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
input[type="password"] {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 16px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
background-color: #4f46e5;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 10px 15px;
|
||||||
|
font-size: 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
button:hover {
|
||||||
|
background-color: #4338ca;
|
||||||
|
}
|
||||||
|
.warning {
|
||||||
|
background-color: #fee2e2;
|
||||||
|
border-left: 4px solid #ef4444;
|
||||||
|
padding: 10px 15px;
|
||||||
|
margin: 20px 0;
|
||||||
|
color: #b91c1c;
|
||||||
|
}
|
||||||
|
code {
|
||||||
|
background-color: #f1f5f9;
|
||||||
|
padding: 2px 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-family: monospace;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Mise à jour du mot de passe admin</h1>
|
||||||
|
|
||||||
|
<div class="warning">
|
||||||
|
<strong>ATTENTION:</strong> Ce fichier est destiné à un usage unique. Supprimez-le immédiatement après avoir mis à jour votre mot de passe!
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php echo $message; ?>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<form method="post">
|
||||||
|
<div>
|
||||||
|
<label for="password">Nouveau mot de passe admin:</label>
|
||||||
|
<input type="password" id="password" name="password" required>
|
||||||
|
</div>
|
||||||
|
<button type="submit" name="submit">Mettre à jour le mot de passe</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="warning" style="margin-top: 20px;">
|
||||||
|
<strong>RAPPEL:</strong> N'oubliez pas de supprimer ce fichier après utilisation!
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
303
admin/assets/css/edit-services.css
Normal file
303
admin/assets/css/edit-services.css
Normal file
@ -0,0 +1,303 @@
|
|||||||
|
/* Custom CSS */
|
||||||
|
:root {
|
||||||
|
--primary-color: #6366f1;
|
||||||
|
--secondary-color: #4f46e5;
|
||||||
|
--background-color: #f8fafc;
|
||||||
|
--card-bg: #ffffff;
|
||||||
|
--text-color: #1e293b;
|
||||||
|
--shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: var(--background-color);
|
||||||
|
color: var(--text-color);
|
||||||
|
min-height: 100vh;
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
font-weight: 800;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
background-clip: text;
|
||||||
|
color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
background-color: var(--card-bg);
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 1.5rem;
|
||||||
|
box-shadow: var(--shadow);
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"],
|
||||||
|
input[type="password"] {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.75rem;
|
||||||
|
border: 1px solid #e2e8f0;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
background-color: var(--primary-color);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
padding: 0.75rem 1.5rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background-color: var(--secondary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-danger {
|
||||||
|
background-color: #ef4444;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-danger:hover {
|
||||||
|
background-color: #dc2626;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary {
|
||||||
|
background-color: #64748b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary:hover {
|
||||||
|
background-color: #475569;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert {
|
||||||
|
padding: 1rem;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-danger {
|
||||||
|
background-color: #fee2e2;
|
||||||
|
color: #b91c1c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-success {
|
||||||
|
background-color: #dcfce7;
|
||||||
|
color: #15803d;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
padding: 0.75rem;
|
||||||
|
text-align: left;
|
||||||
|
border-bottom: 1px solid #e2e8f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.service-icon {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-link {
|
||||||
|
display: inline-block;
|
||||||
|
margin-top: 1rem;
|
||||||
|
color: #64748b;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-link:hover {
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.drag-handle {
|
||||||
|
cursor: move;
|
||||||
|
color: #64748b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Icon Selector Styles */
|
||||||
|
.icon-input-group {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-input {
|
||||||
|
flex-grow: 1;
|
||||||
|
padding-right: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-preview {
|
||||||
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
font-size: 1.2rem;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-select-btn {
|
||||||
|
margin-left: 10px;
|
||||||
|
background-color: #e2e8f0;
|
||||||
|
color: #475569;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-select-btn:hover {
|
||||||
|
background-color: #cbd5e1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-selector-modal {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 2000;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-selector-content {
|
||||||
|
position: relative;
|
||||||
|
background-color: white;
|
||||||
|
margin: 50px auto;
|
||||||
|
padding: 20px;
|
||||||
|
width: 90%;
|
||||||
|
max-width: 800px;
|
||||||
|
border-radius: 8px;
|
||||||
|
max-height: 80vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-selector-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
background-color: white;
|
||||||
|
padding: 10px 0;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-selector-close {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #64748b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-search {
|
||||||
|
padding: 8px 12px;
|
||||||
|
border: 1px solid #e2e8f0;
|
||||||
|
border-radius: 4px;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 300px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-categories {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 10px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-category {
|
||||||
|
background-color: #e2e8f0;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 5px 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-category.active {
|
||||||
|
background-color: var(--primary-color);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-item:hover {
|
||||||
|
background-color: #f1f5f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-item.selected {
|
||||||
|
background-color: #e0e7ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-item i {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-item span {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
text-align: center;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
952
admin/assets/js/icon-selector.js
Normal file
952
admin/assets/js/icon-selector.js
Normal file
@ -0,0 +1,952 @@
|
|||||||
|
$(document).ready(function () {
|
||||||
|
// Drag-and-drop functionality to rearrange services
|
||||||
|
$("#sortable").sortable({
|
||||||
|
handle: ".drag-handle",
|
||||||
|
update: function () {
|
||||||
|
updateServiceIds();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update service IDs for the reorganization form
|
||||||
|
function updateServiceIds() {
|
||||||
|
var serviceIds = [];
|
||||||
|
$("#sortable tr").each(function () {
|
||||||
|
serviceIds.push($(this).data("id"));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Empty the ID container
|
||||||
|
$("#service-ids-container").empty();
|
||||||
|
|
||||||
|
// Add hidden fields for each ID
|
||||||
|
$.each(serviceIds, function (index, id) {
|
||||||
|
$("#service-ids-container").append(
|
||||||
|
'<input type="hidden" name="service_ids[]" value="' + id + '">'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize service IDs
|
||||||
|
updateServiceIds();
|
||||||
|
|
||||||
|
// Editing functionality
|
||||||
|
$(".edit-btn").click(function () {
|
||||||
|
var id = $(this).data("id");
|
||||||
|
var name = $(this).data("name");
|
||||||
|
var icon = $(this).data("icon");
|
||||||
|
var url = $(this).data("url");
|
||||||
|
|
||||||
|
$("#edit-id").val(id);
|
||||||
|
$("#edit-name").val(name);
|
||||||
|
$("#edit-icon").val(icon);
|
||||||
|
$("#edit-url").val(url);
|
||||||
|
$("#edit-icon-preview").attr("class", icon + " icon-preview");
|
||||||
|
|
||||||
|
$("#edit-modal").show();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Close the edit modal
|
||||||
|
$("#cancel-edit").click(function () {
|
||||||
|
$("#edit-modal").hide();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update icon preview during input
|
||||||
|
$("#icon").on("input", function () {
|
||||||
|
$("#icon-preview").attr("class", $(this).val() + " icon-preview");
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#edit-icon").on("input", function () {
|
||||||
|
$("#edit-icon-preview").attr("class", $(this).val() + " icon-preview");
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initialize the icon selector
|
||||||
|
initIconSelector();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Global variables for the icon selector
|
||||||
|
let currentIconInput = "";
|
||||||
|
let currentIconPreview = "";
|
||||||
|
|
||||||
|
// Function to open the icon selector
|
||||||
|
function openIconSelector(inputId, previewId) {
|
||||||
|
currentIconInput = inputId;
|
||||||
|
currentIconPreview = previewId;
|
||||||
|
|
||||||
|
// Select the current icon if it exists
|
||||||
|
const currentIcon = $("#" + inputId).val();
|
||||||
|
if (currentIcon) {
|
||||||
|
$(".icon-item").removeClass("selected");
|
||||||
|
$(`.icon-item[data-icon="${currentIcon}"]`).addClass("selected");
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#icon-selector-modal").show();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to close the icon selector
|
||||||
|
function closeIconSelector() {
|
||||||
|
$("#icon-selector-modal").hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to select an icon
|
||||||
|
function selectIcon(iconClass) {
|
||||||
|
$("#" + currentIconInput).val(iconClass);
|
||||||
|
$("#" + currentIconPreview).attr("class", iconClass + " icon-preview");
|
||||||
|
closeIconSelector();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to initialize the icon selector
|
||||||
|
function initIconSelector() {
|
||||||
|
// List of popular icons by category
|
||||||
|
const icons = {
|
||||||
|
solid: [
|
||||||
|
"fa-solid fa-envelope",
|
||||||
|
"fa-solid fa-home",
|
||||||
|
"fa-solid fa-user",
|
||||||
|
"fa-solid fa-cog",
|
||||||
|
"fa-solid fa-bell",
|
||||||
|
"fa-solid fa-calendar",
|
||||||
|
"fa-solid fa-search",
|
||||||
|
"fa-solid fa-heart",
|
||||||
|
"fa-solid fa-star",
|
||||||
|
"fa-solid fa-check",
|
||||||
|
"fa-solid fa-times",
|
||||||
|
"fa-solid fa-plus",
|
||||||
|
"fa-solid fa-minus",
|
||||||
|
"fa-solid fa-trash",
|
||||||
|
"fa-solid fa-edit",
|
||||||
|
"fa-solid fa-save",
|
||||||
|
"fa-solid fa-download",
|
||||||
|
"fa-solid fa-upload",
|
||||||
|
"fa-solid fa-link",
|
||||||
|
"fa-solid fa-image",
|
||||||
|
"fa-solid fa-video",
|
||||||
|
"fa-solid fa-music",
|
||||||
|
"fa-solid fa-file",
|
||||||
|
"fa-solid fa-folder",
|
||||||
|
"fa-solid fa-lock",
|
||||||
|
"fa-solid fa-unlock",
|
||||||
|
"fa-solid fa-key",
|
||||||
|
"fa-solid fa-shield",
|
||||||
|
"fa-solid fa-chart-bar",
|
||||||
|
"fa-solid fa-chart-line",
|
||||||
|
"fa-solid fa-chart-pie",
|
||||||
|
"fa-solid fa-globe",
|
||||||
|
"fa-solid fa-map",
|
||||||
|
"fa-solid fa-location-dot",
|
||||||
|
"fa-solid fa-phone",
|
||||||
|
"fa-solid fa-mobile",
|
||||||
|
"fa-solid fa-tablet",
|
||||||
|
"fa-solid fa-laptop",
|
||||||
|
"fa-solid fa-desktop",
|
||||||
|
"fa-solid fa-server",
|
||||||
|
"fa-solid fa-database",
|
||||||
|
"fa-solid fa-cloud",
|
||||||
|
"fa-solid fa-cloud-upload",
|
||||||
|
"fa-solid fa-cloud-download",
|
||||||
|
"fa-solid fa-comments",
|
||||||
|
"fa-solid fa-comment",
|
||||||
|
"fa-solid fa-message",
|
||||||
|
"fa-solid fa-paper-plane",
|
||||||
|
"fa-solid fa-share",
|
||||||
|
"fa-solid fa-reply",
|
||||||
|
"fa-solid fa-thumbs-up",
|
||||||
|
"fa-solid fa-thumbs-down",
|
||||||
|
"fa-solid fa-clock",
|
||||||
|
"fa-solid fa-sync",
|
||||||
|
"fa-solid fa-spinner",
|
||||||
|
"fa-solid fa-exclamation",
|
||||||
|
"fa-solid fa-question",
|
||||||
|
"fa-solid fa-info",
|
||||||
|
"fa-solid fa-warning",
|
||||||
|
"fa-solid fa-ban",
|
||||||
|
"fa-solid fa-sign-in",
|
||||||
|
"fa-solid fa-sign-out",
|
||||||
|
"fa-solid fa-arrow-up",
|
||||||
|
"fa-solid fa-arrow-down",
|
||||||
|
"fa-solid fa-arrow-left",
|
||||||
|
"fa-solid fa-arrow-right",
|
||||||
|
"fa-solid fa-expand",
|
||||||
|
"fa-solid fa-compress",
|
||||||
|
"fa-solid fa-print",
|
||||||
|
"fa-solid fa-copy",
|
||||||
|
"fa-solid fa-paste",
|
||||||
|
"fa-solid fa-code",
|
||||||
|
"fa-solid fa-terminal",
|
||||||
|
"fa-solid fa-bug",
|
||||||
|
"fa-solid fa-filter",
|
||||||
|
"fa-solid fa-sort",
|
||||||
|
"fa-solid fa-camera",
|
||||||
|
"fa-solid fa-microphone",
|
||||||
|
"fa-solid fa-volume-up",
|
||||||
|
"fa-solid fa-volume-down",
|
||||||
|
"fa-solid fa-play",
|
||||||
|
"fa-solid fa-pause",
|
||||||
|
"fa-solid fa-stop",
|
||||||
|
"fa-solid fa-forward",
|
||||||
|
"fa-solid fa-backward",
|
||||||
|
"fa-solid fa-list",
|
||||||
|
"fa-solid fa-th",
|
||||||
|
"fa-solid fa-th-large",
|
||||||
|
"fa-solid fa-align-left",
|
||||||
|
"fa-solid fa-align-center",
|
||||||
|
"fa-solid fa-align-right",
|
||||||
|
"fa-solid fa-align-justify",
|
||||||
|
"fa-solid fa-bold",
|
||||||
|
"fa-solid fa-italic",
|
||||||
|
"fa-solid fa-underline",
|
||||||
|
"fa-solid fa-font",
|
||||||
|
"fa-solid fa-table",
|
||||||
|
"fa-solid fa-tasks",
|
||||||
|
"fa-solid fa-check-square",
|
||||||
|
"fa-solid fa-square",
|
||||||
|
"fa-solid fa-circle",
|
||||||
|
"fa-solid fa-ellipsis-h",
|
||||||
|
"fa-solid fa-ellipsis-v",
|
||||||
|
"fa-solid fa-bars",
|
||||||
|
"fa-solid fa-sliders",
|
||||||
|
"fa-solid fa-toggle-on",
|
||||||
|
"fa-solid fa-toggle-off",
|
||||||
|
"fa-solid fa-caret-up",
|
||||||
|
"fa-solid fa-caret-down",
|
||||||
|
"fa-solid fa-caret-left",
|
||||||
|
"fa-solid fa-caret-right",
|
||||||
|
"fa-solid fa-chevron-up",
|
||||||
|
"fa-solid fa-chevron-down",
|
||||||
|
"fa-solid fa-chevron-left",
|
||||||
|
"fa-solid fa-chevron-right",
|
||||||
|
"fa-solid fa-angle-up",
|
||||||
|
"fa-solid fa-angle-down",
|
||||||
|
"fa-solid fa-angle-left",
|
||||||
|
"fa-solid fa-angle-right",
|
||||||
|
"fa-solid fa-external-link",
|
||||||
|
"fa-solid fa-share-square",
|
||||||
|
"fa-solid fa-plus-square",
|
||||||
|
"fa-solid fa-minus-square",
|
||||||
|
"fa-solid fa-times-circle",
|
||||||
|
"fa-solid fa-check-circle",
|
||||||
|
"fa-solid fa-question-circle",
|
||||||
|
"fa-solid fa-info-circle",
|
||||||
|
"fa-solid fa-exclamation-circle",
|
||||||
|
"fa-solid fa-exclamation-triangle",
|
||||||
|
"fa-solid fa-lightbulb",
|
||||||
|
"fa-solid fa-flag",
|
||||||
|
"fa-solid fa-bookmark",
|
||||||
|
"fa-solid fa-tag",
|
||||||
|
"fa-solid fa-tags",
|
||||||
|
"fa-solid fa-book",
|
||||||
|
"fa-solid fa-newspaper",
|
||||||
|
"fa-solid fa-sticky-note",
|
||||||
|
"fa-solid fa-credit-card",
|
||||||
|
"fa-solid fa-money-bill",
|
||||||
|
"fa-solid fa-dollar-sign",
|
||||||
|
"fa-solid fa-euro-sign",
|
||||||
|
"fa-solid fa-pound-sign",
|
||||||
|
"fa-solid fa-yen-sign",
|
||||||
|
"fa-solid fa-ruble-sign",
|
||||||
|
"fa-solid fa-rupee-sign",
|
||||||
|
"fa-solid fa-won-sign",
|
||||||
|
"fa-solid fa-bitcoin-sign",
|
||||||
|
"fa-solid fa-credit-card",
|
||||||
|
"fa-solid fa-wallet",
|
||||||
|
"fa-solid fa-shopping-cart",
|
||||||
|
"fa-solid fa-shopping-bag",
|
||||||
|
"fa-solid fa-shopping-basket",
|
||||||
|
"fa-solid fa-cart-plus",
|
||||||
|
"fa-solid fa-cart-arrow-down",
|
||||||
|
"fa-solid fa-cash-register",
|
||||||
|
"fa-solid fa-receipt",
|
||||||
|
"fa-solid fa-gift",
|
||||||
|
"fa-solid fa-box",
|
||||||
|
"fa-solid fa-boxes",
|
||||||
|
"fa-solid fa-box-open",
|
||||||
|
"fa-solid fa-truck",
|
||||||
|
"fa-solid fa-shipping-fast",
|
||||||
|
"fa-solid fa-dolly",
|
||||||
|
"fa-solid fa-warehouse",
|
||||||
|
"fa-solid fa-store",
|
||||||
|
"fa-solid fa-store-alt",
|
||||||
|
"fa-solid fa-shop",
|
||||||
|
"fa-solid fa-cash-register",
|
||||||
|
"fa-solid fa-person",
|
||||||
|
"fa-solid fa-people-group",
|
||||||
|
"fa-solid fa-user-group",
|
||||||
|
"fa-solid fa-users",
|
||||||
|
"fa-solid fa-user-plus",
|
||||||
|
"fa-solid fa-user-minus",
|
||||||
|
"fa-solid fa-user-check",
|
||||||
|
"fa-solid fa-user-times",
|
||||||
|
"fa-solid fa-user-edit",
|
||||||
|
"fa-solid fa-user-cog",
|
||||||
|
"fa-solid fa-user-gear",
|
||||||
|
"fa-solid fa-user-shield",
|
||||||
|
"fa-solid fa-user-lock",
|
||||||
|
"fa-solid fa-user-clock",
|
||||||
|
"fa-solid fa-user-doctor",
|
||||||
|
"fa-solid fa-user-nurse",
|
||||||
|
"fa-solid fa-user-graduate",
|
||||||
|
"fa-solid fa-user-tie",
|
||||||
|
"fa-solid fa-user-astronaut",
|
||||||
|
"fa-solid fa-user-ninja",
|
||||||
|
"fa-solid fa-user-secret",
|
||||||
|
"fa-solid fa-address-book",
|
||||||
|
"fa-solid fa-address-card",
|
||||||
|
"fa-solid fa-id-badge",
|
||||||
|
"fa-solid fa-id-card",
|
||||||
|
"fa-solid fa-signature",
|
||||||
|
"fa-solid fa-passport",
|
||||||
|
"fa-solid fa-vcard",
|
||||||
|
"fa-solid fa-building",
|
||||||
|
"fa-solid fa-city",
|
||||||
|
"fa-solid fa-hotel",
|
||||||
|
"fa-solid fa-house",
|
||||||
|
"fa-solid fa-school",
|
||||||
|
"fa-solid fa-university",
|
||||||
|
"fa-solid fa-church",
|
||||||
|
"fa-solid fa-mosque",
|
||||||
|
"fa-solid fa-synagogue",
|
||||||
|
"fa-solid fa-cross",
|
||||||
|
"fa-solid fa-star-of-david",
|
||||||
|
"fa-solid fa-star-and-crescent",
|
||||||
|
"fa-solid fa-om",
|
||||||
|
"fa-solid fa-dharmachakra",
|
||||||
|
"fa-solid fa-yin-yang",
|
||||||
|
"fa-solid fa-peace",
|
||||||
|
"fa-solid fa-menorah",
|
||||||
|
"fa-solid fa-ankh",
|
||||||
|
"fa-solid fa-hamsa",
|
||||||
|
"fa-solid fa-pray",
|
||||||
|
"fa-solid fa-praying-hands",
|
||||||
|
"fa-solid fa-hands",
|
||||||
|
"fa-solid fa-hand",
|
||||||
|
"fa-solid fa-hand-point-up",
|
||||||
|
"fa-solid fa-hand-point-down",
|
||||||
|
"fa-solid fa-hand-point-left",
|
||||||
|
"fa-solid fa-hand-point-right",
|
||||||
|
"fa-solid fa-hand-paper",
|
||||||
|
"fa-solid fa-hand-rock",
|
||||||
|
"fa-solid fa-hand-scissors",
|
||||||
|
"fa-solid fa-hand-spock",
|
||||||
|
"fa-solid fa-hand-lizard",
|
||||||
|
"fa-solid fa-thumbs-up",
|
||||||
|
"fa-solid fa-thumbs-down",
|
||||||
|
"fa-solid fa-fist-raised",
|
||||||
|
"fa-solid fa-hands-helping",
|
||||||
|
"fa-solid fa-handshake",
|
||||||
|
"fa-solid fa-hands-wash",
|
||||||
|
"fa-solid fa-hands-bubbles",
|
||||||
|
"fa-solid fa-hands-clapping",
|
||||||
|
"fa-solid fa-sign-language",
|
||||||
|
"fa-solid fa-american-sign-language-interpreting",
|
||||||
|
"fa-solid fa-assistive-listening-systems",
|
||||||
|
"fa-solid fa-braille",
|
||||||
|
"fa-solid fa-blind",
|
||||||
|
"fa-solid fa-wheelchair",
|
||||||
|
"fa-solid fa-accessible-icon",
|
||||||
|
"fa-solid fa-closed-captioning",
|
||||||
|
],
|
||||||
|
regular: [
|
||||||
|
"fa-regular fa-envelope",
|
||||||
|
"fa-regular fa-user",
|
||||||
|
"fa-regular fa-bell",
|
||||||
|
"fa-regular fa-calendar",
|
||||||
|
"fa-regular fa-heart",
|
||||||
|
"fa-regular fa-star",
|
||||||
|
"fa-regular fa-circle",
|
||||||
|
"fa-regular fa-square",
|
||||||
|
"fa-regular fa-file",
|
||||||
|
"fa-regular fa-folder",
|
||||||
|
"fa-regular fa-image",
|
||||||
|
"fa-regular fa-comment",
|
||||||
|
"fa-regular fa-comments",
|
||||||
|
"fa-regular fa-message",
|
||||||
|
"fa-regular fa-paper-plane",
|
||||||
|
"fa-regular fa-clipboard",
|
||||||
|
"fa-regular fa-copy",
|
||||||
|
"fa-regular fa-paste",
|
||||||
|
"fa-regular fa-save",
|
||||||
|
"fa-regular fa-edit",
|
||||||
|
"fa-regular fa-bookmark",
|
||||||
|
"fa-regular fa-flag",
|
||||||
|
"fa-regular fa-eye",
|
||||||
|
"fa-regular fa-eye-slash",
|
||||||
|
"fa-regular fa-thumbs-up",
|
||||||
|
"fa-regular fa-thumbs-down",
|
||||||
|
"fa-regular fa-check-square",
|
||||||
|
"fa-regular fa-clock",
|
||||||
|
"fa-regular fa-calendar-alt",
|
||||||
|
"fa-regular fa-calendar-check",
|
||||||
|
"fa-regular fa-calendar-minus",
|
||||||
|
"fa-regular fa-calendar-plus",
|
||||||
|
"fa-regular fa-calendar-times",
|
||||||
|
"fa-regular fa-address-book",
|
||||||
|
"fa-regular fa-address-card",
|
||||||
|
"fa-regular fa-building",
|
||||||
|
"fa-regular fa-credit-card",
|
||||||
|
"fa-regular fa-file-alt",
|
||||||
|
"fa-regular fa-file-archive",
|
||||||
|
"fa-regular fa-file-audio",
|
||||||
|
"fa-regular fa-file-code",
|
||||||
|
"fa-regular fa-file-excel",
|
||||||
|
"fa-regular fa-file-image",
|
||||||
|
"fa-regular fa-file-pdf",
|
||||||
|
"fa-regular fa-file-powerpoint",
|
||||||
|
"fa-regular fa-file-video",
|
||||||
|
"fa-regular fa-file-word",
|
||||||
|
"fa-regular fa-folder-open",
|
||||||
|
"fa-regular fa-frown",
|
||||||
|
"fa-regular fa-meh",
|
||||||
|
"fa-regular fa-smile",
|
||||||
|
"fa-regular fa-grin",
|
||||||
|
"fa-regular fa-grin-alt",
|
||||||
|
"fa-regular fa-grin-beam",
|
||||||
|
"fa-regular fa-grin-beam-sweat",
|
||||||
|
"fa-regular fa-grin-hearts",
|
||||||
|
"fa-regular fa-grin-squint",
|
||||||
|
"fa-regular fa-grin-squint-tears",
|
||||||
|
"fa-regular fa-grin-stars",
|
||||||
|
"fa-regular fa-grin-tears",
|
||||||
|
"fa-regular fa-grin-tongue",
|
||||||
|
"fa-regular fa-grin-tongue-squint",
|
||||||
|
"fa-regular fa-grin-tongue-wink",
|
||||||
|
"fa-regular fa-grin-wink",
|
||||||
|
"fa-regular fa-kiss",
|
||||||
|
"fa-regular fa-kiss-beam",
|
||||||
|
"fa-regular fa-kiss-wink-heart",
|
||||||
|
"fa-regular fa-laugh",
|
||||||
|
"fa-regular fa-laugh-beam",
|
||||||
|
"fa-regular fa-laugh-squint",
|
||||||
|
"fa-regular fa-laugh-wink",
|
||||||
|
"fa-regular fa-sad-cry",
|
||||||
|
"fa-regular fa-sad-tear",
|
||||||
|
"fa-regular fa-smile-beam",
|
||||||
|
"fa-regular fa-smile-wink",
|
||||||
|
"fa-regular fa-surprise",
|
||||||
|
"fa-regular fa-tired",
|
||||||
|
"fa-regular fa-angry",
|
||||||
|
"fa-regular fa-dizzy",
|
||||||
|
"fa-regular fa-flushed",
|
||||||
|
"fa-regular fa-grimace",
|
||||||
|
"fa-regular fa-hand-lizard",
|
||||||
|
"fa-regular fa-hand-paper",
|
||||||
|
"fa-regular fa-hand-peace",
|
||||||
|
"fa-regular fa-hand-point-down",
|
||||||
|
"fa-regular fa-hand-point-left",
|
||||||
|
"fa-regular fa-hand-point-right",
|
||||||
|
"fa-regular fa-hand-point-up",
|
||||||
|
"fa-regular fa-hand-pointer",
|
||||||
|
"fa-regular fa-hand-rock",
|
||||||
|
"fa-regular fa-hand-scissors",
|
||||||
|
"fa-regular fa-hand-spock",
|
||||||
|
"fa-regular fa-handshake",
|
||||||
|
"fa-regular fa-hdd",
|
||||||
|
"fa-regular fa-hospital",
|
||||||
|
"fa-regular fa-hourglass",
|
||||||
|
"fa-regular fa-id-badge",
|
||||||
|
"fa-regular fa-id-card",
|
||||||
|
"fa-regular fa-image",
|
||||||
|
"fa-regular fa-images",
|
||||||
|
"fa-regular fa-keyboard",
|
||||||
|
"fa-regular fa-lemon",
|
||||||
|
"fa-regular fa-life-ring",
|
||||||
|
"fa-regular fa-lightbulb",
|
||||||
|
"fa-regular fa-list-alt",
|
||||||
|
"fa-regular fa-map",
|
||||||
|
"fa-regular fa-money-bill-alt",
|
||||||
|
"fa-regular fa-moon",
|
||||||
|
"fa-regular fa-newspaper",
|
||||||
|
"fa-regular fa-object-group",
|
||||||
|
"fa-regular fa-object-ungroup",
|
||||||
|
"fa-regular fa-paper-plane",
|
||||||
|
"fa-regular fa-pause-circle",
|
||||||
|
"fa-regular fa-play-circle",
|
||||||
|
"fa-regular fa-plus-square",
|
||||||
|
"fa-regular fa-question-circle",
|
||||||
|
"fa-regular fa-registered",
|
||||||
|
"fa-regular fa-save",
|
||||||
|
"fa-regular fa-share-square",
|
||||||
|
"fa-regular fa-snowflake",
|
||||||
|
"fa-regular fa-star-half",
|
||||||
|
"fa-regular fa-sticky-note",
|
||||||
|
"fa-regular fa-stop-circle",
|
||||||
|
"fa-regular fa-sun",
|
||||||
|
"fa-regular fa-thumbs-down",
|
||||||
|
"fa-regular fa-thumbs-up",
|
||||||
|
"fa-regular fa-times-circle",
|
||||||
|
"fa-regular fa-trash-alt",
|
||||||
|
"fa-regular fa-user-circle",
|
||||||
|
"fa-regular fa-window-close",
|
||||||
|
"fa-regular fa-window-maximize",
|
||||||
|
"fa-regular fa-window-minimize",
|
||||||
|
"fa-regular fa-window-restore",
|
||||||
|
],
|
||||||
|
brands: [
|
||||||
|
"fa-brands fa-500px",
|
||||||
|
"fa-brands fa-accessible-icon",
|
||||||
|
"fa-brands fa-accusoft",
|
||||||
|
"fa-brands fa-acquisitions-incorporated",
|
||||||
|
"fa-brands fa-adn",
|
||||||
|
"fa-brands fa-adobe",
|
||||||
|
"fa-brands fa-adversal",
|
||||||
|
"fa-brands fa-affiliatetheme",
|
||||||
|
"fa-brands fa-airbnb",
|
||||||
|
"fa-brands fa-algolia",
|
||||||
|
"fa-brands fa-alipay",
|
||||||
|
"fa-brands fa-amazon",
|
||||||
|
"fa-brands fa-amazon-pay",
|
||||||
|
"fa-brands fa-amilia",
|
||||||
|
"fa-brands fa-android",
|
||||||
|
"fa-brands fa-angellist",
|
||||||
|
"fa-brands fa-angrycreative",
|
||||||
|
"fa-brands fa-angular",
|
||||||
|
"fa-brands fa-app-store",
|
||||||
|
"fa-brands fa-app-store-ios",
|
||||||
|
"fa-brands fa-apper",
|
||||||
|
"fa-brands fa-apple",
|
||||||
|
"fa-brands fa-apple-pay",
|
||||||
|
"fa-brands fa-artstation",
|
||||||
|
"fa-brands fa-asymmetrik",
|
||||||
|
"fa-brands fa-atlassian",
|
||||||
|
"fa-brands fa-audible",
|
||||||
|
"fa-brands fa-autoprefixer",
|
||||||
|
"fa-brands fa-avianex",
|
||||||
|
"fa-brands fa-aviato",
|
||||||
|
"fa-brands fa-aws",
|
||||||
|
"fa-brands fa-bandcamp",
|
||||||
|
"fa-brands fa-battle-net",
|
||||||
|
"fa-brands fa-behance",
|
||||||
|
"fa-brands fa-behance-square",
|
||||||
|
"fa-brands fa-bimobject",
|
||||||
|
"fa-brands fa-bitbucket",
|
||||||
|
"fa-brands fa-bitcoin",
|
||||||
|
"fa-brands fa-bity",
|
||||||
|
"fa-brands fa-black-tie",
|
||||||
|
"fa-brands fa-blackberry",
|
||||||
|
"fa-brands fa-blogger",
|
||||||
|
"fa-brands fa-blogger-b",
|
||||||
|
"fa-brands fa-bluetooth",
|
||||||
|
"fa-brands fa-bluetooth-b",
|
||||||
|
"fa-brands fa-bootstrap",
|
||||||
|
"fa-brands fa-btc",
|
||||||
|
"fa-brands fa-buffer",
|
||||||
|
"fa-brands fa-buromobelexperte",
|
||||||
|
"fa-brands fa-buy-n-large",
|
||||||
|
"fa-brands fa-buysellads",
|
||||||
|
"fa-brands fa-canadian-maple-leaf",
|
||||||
|
"fa-brands fa-cc-amazon-pay",
|
||||||
|
"fa-brands fa-cc-amex",
|
||||||
|
"fa-brands fa-cc-apple-pay",
|
||||||
|
"fa-brands fa-cc-diners-club",
|
||||||
|
"fa-brands fa-cc-discover",
|
||||||
|
"fa-brands fa-cc-jcb",
|
||||||
|
"fa-brands fa-cc-mastercard",
|
||||||
|
"fa-brands fa-cc-paypal",
|
||||||
|
"fa-brands fa-cc-stripe",
|
||||||
|
"fa-brands fa-cc-visa",
|
||||||
|
"fa-brands fa-centercode",
|
||||||
|
"fa-brands fa-centos",
|
||||||
|
"fa-brands fa-chrome",
|
||||||
|
"fa-brands fa-chromecast",
|
||||||
|
"fa-brands fa-cloudflare",
|
||||||
|
"fa-brands fa-cloudscale",
|
||||||
|
"fa-brands fa-cloudsmith",
|
||||||
|
"fa-brands fa-cloudversify",
|
||||||
|
"fa-brands fa-codepen",
|
||||||
|
"fa-brands fa-codiepie",
|
||||||
|
"fa-brands fa-confluence",
|
||||||
|
"fa-brands fa-connectdevelop",
|
||||||
|
"fa-brands fa-contao",
|
||||||
|
"fa-brands fa-cotton-bureau",
|
||||||
|
"fa-brands fa-cpanel",
|
||||||
|
"fa-brands fa-creative-commons",
|
||||||
|
"fa-brands fa-css3",
|
||||||
|
"fa-brands fa-css3-alt",
|
||||||
|
"fa-brands fa-cuttlefish",
|
||||||
|
"fa-brands fa-d-and-d",
|
||||||
|
"fa-brands fa-dashcube",
|
||||||
|
"fa-brands fa-deezer",
|
||||||
|
"fa-brands fa-delicious",
|
||||||
|
"fa-brands fa-deploydog",
|
||||||
|
"fa-brands fa-deskpro",
|
||||||
|
"fa-brands fa-dev",
|
||||||
|
"fa-brands fa-deviantart",
|
||||||
|
"fa-brands fa-dhl",
|
||||||
|
"fa-brands fa-diaspora",
|
||||||
|
"fa-brands fa-digg",
|
||||||
|
"fa-brands fa-digital-ocean",
|
||||||
|
"fa-brands fa-discord",
|
||||||
|
"fa-brands fa-discourse",
|
||||||
|
"fa-brands fa-dochub",
|
||||||
|
"fa-brands fa-docker",
|
||||||
|
"fa-brands fa-draft2digital",
|
||||||
|
"fa-brands fa-dribbble",
|
||||||
|
"fa-brands fa-dropbox",
|
||||||
|
"fa-brands fa-drupal",
|
||||||
|
"fa-brands fa-dyalog",
|
||||||
|
"fa-brands fa-earlybirds",
|
||||||
|
"fa-brands fa-ebay",
|
||||||
|
"fa-brands fa-edge",
|
||||||
|
"fa-brands fa-elementor",
|
||||||
|
"fa-brands fa-ello",
|
||||||
|
"fa-brands fa-ember",
|
||||||
|
"fa-brands fa-empire",
|
||||||
|
"fa-brands fa-envira",
|
||||||
|
"fa-brands fa-erlang",
|
||||||
|
"fa-brands fa-ethereum",
|
||||||
|
"fa-brands fa-etsy",
|
||||||
|
"fa-brands fa-evernote",
|
||||||
|
"fa-brands fa-expeditedssl",
|
||||||
|
"fa-brands fa-facebook",
|
||||||
|
"fa-brands fa-facebook-f",
|
||||||
|
"fa-brands fa-facebook-messenger",
|
||||||
|
"fa-brands fa-facebook-square",
|
||||||
|
"fa-brands fa-fantasy-flight-games",
|
||||||
|
"fa-brands fa-fedex",
|
||||||
|
"fa-brands fa-fedora",
|
||||||
|
"fa-brands fa-figma",
|
||||||
|
"fa-brands fa-firefox",
|
||||||
|
"fa-brands fa-firefox-browser",
|
||||||
|
"fa-brands fa-first-order",
|
||||||
|
"fa-brands fa-flickr",
|
||||||
|
"fa-brands fa-flipboard",
|
||||||
|
"fa-brands fa-fly",
|
||||||
|
"fa-brands fa-font-awesome",
|
||||||
|
"fa-brands fa-fonticons",
|
||||||
|
"fa-brands fa-fort-awesome",
|
||||||
|
"fa-brands fa-forumbee",
|
||||||
|
"fa-brands fa-foursquare",
|
||||||
|
"fa-brands fa-free-code-camp",
|
||||||
|
"fa-brands fa-freebsd",
|
||||||
|
"fa-brands fa-fulcrum",
|
||||||
|
"fa-brands fa-galactic-republic",
|
||||||
|
"fa-brands fa-galactic-senate",
|
||||||
|
"fa-brands fa-get-pocket",
|
||||||
|
"fa-brands fa-gg",
|
||||||
|
"fa-brands fa-git",
|
||||||
|
"fa-brands fa-git-alt",
|
||||||
|
"fa-brands fa-github",
|
||||||
|
"fa-brands fa-github-alt",
|
||||||
|
"fa-brands fa-github-square",
|
||||||
|
"fa-brands fa-gitkraken",
|
||||||
|
"fa-brands fa-gitlab",
|
||||||
|
"fa-brands fa-gitter",
|
||||||
|
"fa-brands fa-glide",
|
||||||
|
"fa-brands fa-gofore",
|
||||||
|
"fa-brands fa-goodreads",
|
||||||
|
"fa-brands fa-google",
|
||||||
|
"fa-brands fa-google-drive",
|
||||||
|
"fa-brands fa-google-pay",
|
||||||
|
"fa-brands fa-google-play",
|
||||||
|
"fa-brands fa-google-plus",
|
||||||
|
"fa-brands fa-google-plus-g",
|
||||||
|
"fa-brands fa-google-plus-square",
|
||||||
|
"fa-brands fa-google-wallet",
|
||||||
|
"fa-brands fa-gratipay",
|
||||||
|
"fa-brands fa-grav",
|
||||||
|
"fa-brands fa-gripfire",
|
||||||
|
"fa-brands fa-grunt",
|
||||||
|
"fa-brands fa-gulp",
|
||||||
|
"fa-brands fa-hacker-news",
|
||||||
|
"fa-brands fa-hackerrank",
|
||||||
|
"fa-brands fa-hips",
|
||||||
|
"fa-brands fa-hire-a-helper",
|
||||||
|
"fa-brands fa-hooli",
|
||||||
|
"fa-brands fa-hornbill",
|
||||||
|
"fa-brands fa-hotjar",
|
||||||
|
"fa-brands fa-houzz",
|
||||||
|
"fa-brands fa-html5",
|
||||||
|
"fa-brands fa-hubspot",
|
||||||
|
"fa-brands fa-ideal",
|
||||||
|
"fa-brands fa-imdb",
|
||||||
|
"fa-brands fa-instagram",
|
||||||
|
"fa-brands fa-intercom",
|
||||||
|
"fa-brands fa-internet-explorer",
|
||||||
|
"fa-brands fa-invision",
|
||||||
|
"fa-brands fa-ioxhost",
|
||||||
|
"fa-brands fa-itch-io",
|
||||||
|
"fa-brands fa-itunes",
|
||||||
|
"fa-brands fa-java",
|
||||||
|
"fa-brands fa-jedi-order",
|
||||||
|
"fa-brands fa-jenkins",
|
||||||
|
"fa-brands fa-jira",
|
||||||
|
"fa-brands fa-joget",
|
||||||
|
"fa-brands fa-joomla",
|
||||||
|
"fa-brands fa-js",
|
||||||
|
"fa-brands fa-js-square",
|
||||||
|
"fa-brands fa-jsfiddle",
|
||||||
|
"fa-brands fa-kaggle",
|
||||||
|
"fa-brands fa-keybase",
|
||||||
|
"fa-brands fa-keycdn",
|
||||||
|
"fa-brands fa-kickstarter",
|
||||||
|
"fa-brands fa-laravel",
|
||||||
|
"fa-brands fa-lastfm",
|
||||||
|
"fa-brands fa-leanpub",
|
||||||
|
"fa-brands fa-less",
|
||||||
|
"fa-brands fa-line",
|
||||||
|
"fa-brands fa-linkedin",
|
||||||
|
"fa-brands fa-linkedin-in",
|
||||||
|
"fa-brands fa-linode",
|
||||||
|
"fa-brands fa-linux",
|
||||||
|
"fa-brands fa-lyft",
|
||||||
|
"fa-brands fa-magento",
|
||||||
|
"fa-brands fa-mailchimp",
|
||||||
|
"fa-brands fa-mandalorian",
|
||||||
|
"fa-brands fa-markdown",
|
||||||
|
"fa-brands fa-mastodon",
|
||||||
|
"fa-brands fa-maxcdn",
|
||||||
|
"fa-brands fa-mdb",
|
||||||
|
"fa-brands fa-medapps",
|
||||||
|
"fa-brands fa-medium",
|
||||||
|
"fa-brands fa-medrt",
|
||||||
|
"fa-brands fa-meetup",
|
||||||
|
"fa-brands fa-megaport",
|
||||||
|
"fa-brands fa-mendeley",
|
||||||
|
"fa-brands fa-microblog",
|
||||||
|
"fa-brands fa-microsoft",
|
||||||
|
"fa-brands fa-mix",
|
||||||
|
"fa-brands fa-mixcloud",
|
||||||
|
"fa-brands fa-mixer",
|
||||||
|
"fa-brands fa-mizuni",
|
||||||
|
"fa-brands fa-modx",
|
||||||
|
"fa-brands fa-monero",
|
||||||
|
"fa-brands fa-napster",
|
||||||
|
"fa-brands fa-neos",
|
||||||
|
"fa-brands fa-nimblr",
|
||||||
|
"fa-brands fa-node",
|
||||||
|
"fa-brands fa-node-js",
|
||||||
|
"fa-brands fa-npm",
|
||||||
|
"fa-brands fa-ns8",
|
||||||
|
"fa-brands fa-nutritionix",
|
||||||
|
"fa-brands fa-odnoklassniki",
|
||||||
|
"fa-brands fa-old-republic",
|
||||||
|
"fa-brands fa-opencart",
|
||||||
|
"fa-brands fa-openid",
|
||||||
|
"fa-brands fa-opera",
|
||||||
|
"fa-brands fa-optin-monster",
|
||||||
|
"fa-brands fa-orcid",
|
||||||
|
"fa-brands fa-osi",
|
||||||
|
"fa-brands fa-page4",
|
||||||
|
"fa-brands fa-pagelines",
|
||||||
|
"fa-brands fa-palfed",
|
||||||
|
"fa-brands fa-patreon",
|
||||||
|
"fa-brands fa-paypal",
|
||||||
|
"fa-brands fa-penny-arcade",
|
||||||
|
"fa-brands fa-periscope",
|
||||||
|
"fa-brands fa-phabricator",
|
||||||
|
"fa-brands fa-phoenix-framework",
|
||||||
|
"fa-brands fa-phoenix-squadron",
|
||||||
|
"fa-brands fa-php",
|
||||||
|
"fa-brands fa-pied-piper",
|
||||||
|
"fa-brands fa-pinterest",
|
||||||
|
"fa-brands fa-pinterest-p",
|
||||||
|
"fa-brands fa-pinterest-square",
|
||||||
|
"fa-brands fa-playstation",
|
||||||
|
"fa-brands fa-product-hunt",
|
||||||
|
"fa-brands fa-pushed",
|
||||||
|
"fa-brands fa-python",
|
||||||
|
"fa-brands fa-qq",
|
||||||
|
"fa-brands fa-quinscape",
|
||||||
|
"fa-brands fa-quora",
|
||||||
|
"fa-brands fa-r-project",
|
||||||
|
"fa-brands fa-raspberry-pi",
|
||||||
|
"fa-brands fa-ravelry",
|
||||||
|
"fa-brands fa-react",
|
||||||
|
"fa-brands fa-reacteurope",
|
||||||
|
"fa-brands fa-readme",
|
||||||
|
"fa-brands fa-rebel",
|
||||||
|
"fa-brands fa-red-river",
|
||||||
|
"fa-brands fa-reddit",
|
||||||
|
"fa-brands fa-reddit-alien",
|
||||||
|
"fa-brands fa-reddit-square",
|
||||||
|
"fa-brands fa-redhat",
|
||||||
|
"fa-brands fa-renren",
|
||||||
|
"fa-brands fa-replyd",
|
||||||
|
"fa-brands fa-researchgate",
|
||||||
|
"fa-brands fa-resolving",
|
||||||
|
"fa-brands fa-rev",
|
||||||
|
"fa-brands fa-rocketchat",
|
||||||
|
"fa-brands fa-rockrms",
|
||||||
|
"fa-brands fa-safari",
|
||||||
|
"fa-brands fa-salesforce",
|
||||||
|
"fa-brands fa-sass",
|
||||||
|
"fa-brands fa-schlix",
|
||||||
|
"fa-brands fa-scribd",
|
||||||
|
"fa-brands fa-searchengin",
|
||||||
|
"fa-brands fa-sellcast",
|
||||||
|
"fa-brands fa-sellsy",
|
||||||
|
"fa-brands fa-servicestack",
|
||||||
|
"fa-brands fa-shirtsinbulk",
|
||||||
|
"fa-brands fa-shopify",
|
||||||
|
"fa-brands fa-shopware",
|
||||||
|
"fa-brands fa-simplybuilt",
|
||||||
|
"fa-brands fa-sistrix",
|
||||||
|
"fa-brands fa-sith",
|
||||||
|
"fa-brands fa-sketch",
|
||||||
|
"fa-brands fa-skyatlas",
|
||||||
|
"fa-brands fa-skype",
|
||||||
|
"fa-brands fa-slack",
|
||||||
|
"fa-brands fa-slack-hash",
|
||||||
|
"fa-brands fa-slideshare",
|
||||||
|
"fa-brands fa-snapchat",
|
||||||
|
"fa-brands fa-snapchat-ghost",
|
||||||
|
"fa-brands fa-snapchat-square",
|
||||||
|
"fa-brands fa-soundcloud",
|
||||||
|
"fa-brands fa-sourcetree",
|
||||||
|
"fa-brands fa-speakap",
|
||||||
|
"fa-brands fa-speaker-deck",
|
||||||
|
"fa-brands fa-spotify",
|
||||||
|
"fa-brands fa-squarespace",
|
||||||
|
"fa-brands fa-stack-exchange",
|
||||||
|
"fa-brands fa-stack-overflow",
|
||||||
|
"fa-brands fa-stackpath",
|
||||||
|
"fa-brands fa-staylinked",
|
||||||
|
"fa-brands fa-steam",
|
||||||
|
"fa-brands fa-steam-square",
|
||||||
|
"fa-brands fa-steam-symbol",
|
||||||
|
"fa-brands fa-sticker-mule",
|
||||||
|
"fa-brands fa-strava",
|
||||||
|
"fa-brands fa-stripe",
|
||||||
|
"fa-brands fa-stripe-s",
|
||||||
|
"fa-brands fa-studiovinari",
|
||||||
|
"fa-brands fa-stumbleupon",
|
||||||
|
"fa-brands fa-stumbleupon-circle",
|
||||||
|
"fa-brands fa-superpowers",
|
||||||
|
"fa-brands fa-supple",
|
||||||
|
"fa-brands fa-suse",
|
||||||
|
"fa-brands fa-swift",
|
||||||
|
"fa-brands fa-symfony",
|
||||||
|
"fa-brands fa-teamspeak",
|
||||||
|
"fa-brands fa-telegram",
|
||||||
|
"fa-brands fa-telegram-plane",
|
||||||
|
"fa-brands fa-tencent-weibo",
|
||||||
|
"fa-brands fa-the-red-yeti",
|
||||||
|
"fa-brands fa-themeco",
|
||||||
|
"fa-brands fa-themeisle",
|
||||||
|
"fa-brands fa-think-peaks",
|
||||||
|
"fa-brands fa-tiktok",
|
||||||
|
"fa-brands fa-trade-federation",
|
||||||
|
"fa-brands fa-trello",
|
||||||
|
"fa-brands fa-tripadvisor",
|
||||||
|
"fa-brands fa-tumblr",
|
||||||
|
"fa-brands fa-tumblr-square",
|
||||||
|
"fa-brands fa-twitch",
|
||||||
|
"fa-brands fa-twitter",
|
||||||
|
"fa-brands fa-twitter-square",
|
||||||
|
"fa-brands fa-typo3",
|
||||||
|
"fa-brands fa-uber",
|
||||||
|
"fa-brands fa-ubuntu",
|
||||||
|
"fa-brands fa-uikit",
|
||||||
|
"fa-brands fa-umbraco",
|
||||||
|
"fa-brands fa-uniregistry",
|
||||||
|
"fa-brands fa-unity",
|
||||||
|
"fa-brands fa-unsplash",
|
||||||
|
"fa-brands fa-untappd",
|
||||||
|
"fa-brands fa-ups",
|
||||||
|
"fa-brands fa-usb",
|
||||||
|
"fa-brands fa-usps",
|
||||||
|
"fa-brands fa-ussunnah",
|
||||||
|
"fa-brands fa-vaadin",
|
||||||
|
"fa-brands fa-viacoin",
|
||||||
|
"fa-brands fa-viadeo",
|
||||||
|
"fa-brands fa-viadeo-square",
|
||||||
|
"fa-brands fa-viber",
|
||||||
|
"fa-brands fa-vimeo",
|
||||||
|
"fa-brands fa-vimeo-square",
|
||||||
|
"fa-brands fa-vimeo-v",
|
||||||
|
"fa-brands fa-vine",
|
||||||
|
"fa-brands fa-vk",
|
||||||
|
"fa-brands fa-vnv",
|
||||||
|
"fa-brands fa-vuejs",
|
||||||
|
"fa-brands fa-waze",
|
||||||
|
"fa-brands fa-weebly",
|
||||||
|
"fa-brands fa-weibo",
|
||||||
|
"fa-brands fa-weixin",
|
||||||
|
"fa-brands fa-whatsapp",
|
||||||
|
"fa-brands fa-whatsapp-square",
|
||||||
|
"fa-brands fa-whmcs",
|
||||||
|
"fa-brands fa-wikipedia-w",
|
||||||
|
"fa-brands fa-windows",
|
||||||
|
"fa-brands fa-wix",
|
||||||
|
"fa-brands fa-wizards-of-the-coast",
|
||||||
|
"fa-brands fa-wolf-pack-battalion",
|
||||||
|
"fa-brands fa-wordpress",
|
||||||
|
"fa-brands fa-wordpress-simple",
|
||||||
|
"fa-brands fa-wpbeginner",
|
||||||
|
"fa-brands fa-wpexplorer",
|
||||||
|
"fa-brands fa-wpforms",
|
||||||
|
"fa-brands fa-wpressr",
|
||||||
|
"fa-brands fa-xbox",
|
||||||
|
"fa-brands fa-xing",
|
||||||
|
"fa-brands fa-xing-square",
|
||||||
|
"fa-brands fa-y-combinator",
|
||||||
|
"fa-brands fa-yahoo",
|
||||||
|
"fa-brands fa-yammer",
|
||||||
|
"fa-brands fa-yandex",
|
||||||
|
"fa-brands fa-yandex-international",
|
||||||
|
"fa-brands fa-yarn",
|
||||||
|
"fa-brands fa-yelp",
|
||||||
|
"fa-brands fa-yoast",
|
||||||
|
"fa-brands fa-youtube",
|
||||||
|
"fa-brands fa-youtube-square",
|
||||||
|
"fa-brands fa-zhihu",
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function to generate the icon grid
|
||||||
|
function generateIconGrid(category = "all") {
|
||||||
|
const iconGrid = $("#icon-grid");
|
||||||
|
iconGrid.empty();
|
||||||
|
|
||||||
|
let iconsToShow = [];
|
||||||
|
|
||||||
|
if (category === "all") {
|
||||||
|
iconsToShow = [...icons.solid, ...icons.regular, ...icons.brands];
|
||||||
|
} else {
|
||||||
|
iconsToShow = icons[category] || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter by search if necessary
|
||||||
|
const searchTerm = $("#icon-search").val().toLowerCase();
|
||||||
|
if (searchTerm) {
|
||||||
|
iconsToShow = iconsToShow.filter((icon) =>
|
||||||
|
icon.toLowerCase().includes(searchTerm)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Limit to 200 icons for performance reasons
|
||||||
|
const limitedIcons = iconsToShow.slice(0, 200);
|
||||||
|
|
||||||
|
// Generate HTML elements for each icon
|
||||||
|
limitedIcons.forEach((icon) => {
|
||||||
|
const iconName = icon.split(" ").pop().replace("fa-", "");
|
||||||
|
const iconItem = $(`
|
||||||
|
<div class="icon-item" data-icon="${icon}" onclick="selectIcon('${icon}')">
|
||||||
|
<i class="${icon}"></i>
|
||||||
|
<span>${iconName}</span>
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
iconGrid.append(iconItem);
|
||||||
|
});
|
||||||
|
|
||||||
|
// If no icon is found
|
||||||
|
if (limitedIcons.length === 0) {
|
||||||
|
iconGrid.append(
|
||||||
|
'<div style="grid-column: 1 / -1; text-align: center; padding: 20px;">No icons found</div>'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate the initial icon grid
|
||||||
|
generateIconGrid();
|
||||||
|
|
||||||
|
// Filter icons by category
|
||||||
|
$(".icon-category").click(function () {
|
||||||
|
$(".icon-category").removeClass("active");
|
||||||
|
$(this).addClass("active");
|
||||||
|
generateIconGrid($(this).data("category"));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Filter icons by search
|
||||||
|
$("#icon-search").on("input", function () {
|
||||||
|
const category = $(".icon-category.active").data("category");
|
||||||
|
generateIconGrid(category);
|
||||||
|
});
|
||||||
|
}
|
319
admin/edit-services.php
Normal file
319
admin/edit-services.php
Normal file
@ -0,0 +1,319 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
include_once("../_conf/global.php");
|
||||||
|
include_once("../_conf/db.php");
|
||||||
|
|
||||||
|
// Connecting to the database
|
||||||
|
try {
|
||||||
|
$pdo = new PDO($db['dsn'], $db['user'], $db['pass']);
|
||||||
|
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
die("Database connection error: " . $e->getMessage());
|
||||||
|
}v
|
||||||
|
|
||||||
|
// Error and success messages
|
||||||
|
$error = '';
|
||||||
|
$success = '';
|
||||||
|
|
||||||
|
// Check if the user is logged in
|
||||||
|
$is_logged_in = isset($_SESSION['admin_logged_in']) && $_SESSION['admin_logged_in'] === true;
|
||||||
|
|
||||||
|
// Processing the login form
|
||||||
|
if (isset($_POST['login'])) {
|
||||||
|
$password = $_POST['password'];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$stmt = $pdo->query("SELECT password_hash FROM admin LIMIT 1");
|
||||||
|
$admin = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if ($admin && password_verify($password, $admin['password_hash'])) {
|
||||||
|
$_SESSION['admin_logged_in'] = true;
|
||||||
|
$is_logged_in = true;
|
||||||
|
$success = "Connection successful!";
|
||||||
|
} else {
|
||||||
|
$error = "Incorrect password!";
|
||||||
|
}
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$error = "Error while verifying password: " . $e->getMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Processing the logout form
|
||||||
|
if (isset($_POST['logout'])) {
|
||||||
|
$_SESSION['admin_logged_in'] = false;
|
||||||
|
$is_logged_in = false;
|
||||||
|
$success = "Disconnected successfully!";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Processing the service addition form
|
||||||
|
if ($is_logged_in && isset($_POST['add_service'])) {
|
||||||
|
$name = $_POST['name'];
|
||||||
|
$icon = $_POST['icon'];
|
||||||
|
$url = $_POST['url'];
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Find the next order
|
||||||
|
$stmt = $pdo->query("SELECT MAX(order_num) as max_order FROM services");
|
||||||
|
$result = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
$next_order = ($result['max_order'] ?? 0) + 1;
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare("INSERT INTO services (name, icon, url, order_num) VALUES (?, ?, ?, ?)");
|
||||||
|
$stmt->execute([$name, $icon, $url, $next_order]);
|
||||||
|
$success = "Service added successfully!";
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$error = "Error while adding the service: " . $e->getMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Processing the service change form
|
||||||
|
if ($is_logged_in && isset($_POST['edit_service'])) {
|
||||||
|
$id = $_POST['id'];
|
||||||
|
$name = $_POST['name'];
|
||||||
|
$icon = $_POST['icon'];
|
||||||
|
$url = $_POST['url'];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$stmt = $pdo->prepare("UPDATE services SET name = ?, icon = ?, url = ? WHERE id = ?");
|
||||||
|
$stmt->execute([$name, $icon, $url, $id]);
|
||||||
|
$success = "Service successfully modified!";
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$error = "Error while modifying the service: " . $e->getMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Processing the service cancellation form
|
||||||
|
if ($is_logged_in && isset($_POST['delete_service'])) {
|
||||||
|
$id = $_POST['id'];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$stmt = $pdo->prepare("DELETE FROM services WHERE id = ?");
|
||||||
|
$stmt->execute([$id]);
|
||||||
|
$success = "Service successfully deleted!";
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$error = "Error while deleting the service: " . $e->getMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Processing of the service reorganization form
|
||||||
|
if ($is_logged_in && isset($_POST['reorder'])) {
|
||||||
|
$ids = $_POST['service_ids'];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$pdo->beginTransaction();
|
||||||
|
|
||||||
|
foreach ($ids as $order => $id) {
|
||||||
|
$stmt = $pdo->prepare("UPDATE services SET order_num = ? WHERE id = ?");
|
||||||
|
$stmt->execute([$order + 1, $id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdo->commit();
|
||||||
|
$success = "Services successfully reorganized!";
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$pdo->rollBack();
|
||||||
|
$error = "Error during service reorganization: " . $e->getMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieving services from the database
|
||||||
|
try {
|
||||||
|
$stmt = $pdo->query("SELECT * FROM services ORDER BY order_num ASC");
|
||||||
|
$services = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$services = [];
|
||||||
|
$error = "Error retrieving services: " . $e->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
$title = $config['site']['name'];
|
||||||
|
$description = "Internal system administration area of the ". $config['site']['name'] ." website.";
|
||||||
|
$url = "https://". $config['site']['main_domain'] ."/services?edit";
|
||||||
|
$meta_image = "https://". $config['site']['imgs_domain'] ."/-/WaWA7/FoRUmETa47.png/raw";
|
||||||
|
$robots = "noindex, nofollow";
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<!-- Primary Meta Tags -->
|
||||||
|
<title><?php echo $title; ?> - Admin</title>
|
||||||
|
<meta name="title" content="<?php echo $title; ?> - Admin" />
|
||||||
|
<meta name="description" content="<?php echo $description; ?>" />
|
||||||
|
<!-- Open Graph / Facebook -->
|
||||||
|
<meta property="og:type" content="website" />
|
||||||
|
<meta property="og:url" content="<?php echo $url; ?>" />
|
||||||
|
<meta property="og:title" content="<?php echo $title; ?> - Admin" />
|
||||||
|
<meta property="og:description" content="<?php echo $description; ?>" />
|
||||||
|
<meta property="og:image" content="<?php echo $meta_image; ?>" />
|
||||||
|
<!-- Twitter -->
|
||||||
|
<meta property="twitter:card" content="summary_large_image" />
|
||||||
|
<meta property="twitter:url" content="<?php echo $url; ?>" />
|
||||||
|
<meta property="twitter:title" content="<?php echo $title; ?> - Admin" />
|
||||||
|
<meta property="twitter:description" content="<?php echo $description; ?>" />
|
||||||
|
<meta property="twitter:image" content="<?php echo $meta_image; ?>" />
|
||||||
|
<meta name="robots" content="<?php echo $robots; ?>" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="assets/css/edit-services.css">
|
||||||
|
<!-- Font Awesome for icons -->
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||||
|
<!-- jQuery for drag and drop functionality -->
|
||||||
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||||
|
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.min.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="header">
|
||||||
|
<h1 class="title"><?php echo $title; ?> Admin</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php if ($error): ?>
|
||||||
|
<div class="alert alert-danger"><?php echo $error; ?></div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if ($success): ?>
|
||||||
|
<div class="alert alert-success"><?php echo $success; ?></div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if (!$is_logged_in): ?>
|
||||||
|
<!-- Login form -->
|
||||||
|
<div class="card">
|
||||||
|
<h2>Login</h2>
|
||||||
|
<form method="post">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="password">Password</label>
|
||||||
|
<input type="password" id="password" name="password" required>
|
||||||
|
</div>
|
||||||
|
<button type="submit" name="login">Log in</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<?php else: ?>
|
||||||
|
<!-- Logout form -->
|
||||||
|
<form method="post" style="text-align: right; margin-bottom: 1rem;">
|
||||||
|
<button type="submit" name="logout" class="btn-secondary">Log out</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<!-- Service Addition Form -->
|
||||||
|
<div class="card">
|
||||||
|
<h2>Add a service</h2>
|
||||||
|
<form method="post">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="name">Name</label>
|
||||||
|
<input type="text" id="name" name="name" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="icon">Icon</label>
|
||||||
|
<div class="icon-input-group">
|
||||||
|
<input type="text" id="icon" name="icon" class="icon-input" placeholder="fa-solid fa-envelope" required>
|
||||||
|
<i id="icon-preview" class="icon-preview fa-solid fa-envelope"></i>
|
||||||
|
<button type="button" class="icon-select-btn" onclick="openIconSelector('icon', 'icon-preview')">Choose</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="url">URL</label>
|
||||||
|
<input type="text" id="url" name="url" placeholder="https://example.com" required>
|
||||||
|
</div>
|
||||||
|
<button type="submit" name="add_service">Add</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- List of services -->
|
||||||
|
<div class="card">
|
||||||
|
<h2>Services</h2>
|
||||||
|
<form method="post" id="reorder-form">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th width="5%"></th>
|
||||||
|
<th width="10%">Icon</th>
|
||||||
|
<th width="25%">Name</th>
|
||||||
|
<th width="40%">URL</th>
|
||||||
|
<th width="20%">Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="sortable">
|
||||||
|
<?php foreach ($services as $service): ?>
|
||||||
|
<tr data-id="<?php echo $service['id']; ?>">
|
||||||
|
<td><i class="fas fa-grip-lines drag-handle"></i></td>
|
||||||
|
<td><i class="<?php echo htmlspecialchars($service['icon']); ?> service-icon"></i></td>
|
||||||
|
<td><?php echo htmlspecialchars($service['name']); ?></td>
|
||||||
|
<td><?php echo htmlspecialchars($service['url']); ?></td>
|
||||||
|
<td class="actions">
|
||||||
|
<button type="button" class="btn-secondary edit-btn"
|
||||||
|
data-id="<?php echo $service['id']; ?>"
|
||||||
|
data-name="<?php echo htmlspecialchars($service['name']); ?>"
|
||||||
|
data-icon="<?php echo htmlspecialchars($service['icon']); ?>"
|
||||||
|
data-url="<?php echo htmlspecialchars($service['url']); ?>">
|
||||||
|
<i class="fas fa-edit"></i>
|
||||||
|
</button>
|
||||||
|
<form method="post" style="display: inline;">
|
||||||
|
<input type="hidden" name="id" value="<?php echo $service['id']; ?>">
|
||||||
|
<button type="submit" name="delete_service" class="btn-danger" onclick="return confirm('Are you sure you want to delete this service?');">
|
||||||
|
<i class="fas fa-trash"></i>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<input type="hidden" name="reorder" value="1">
|
||||||
|
<div id="service-ids-container"></div>
|
||||||
|
<button type="submit" id="save-order" style="margin-top: 1rem;">Save order</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Edit modal -->
|
||||||
|
<div id="edit-modal" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); z-index: 1000;">
|
||||||
|
<div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: white; padding: 2rem; border-radius: 0.5rem; width: 90%; max-width: 500px;">
|
||||||
|
<h2>Edit the service</h2>
|
||||||
|
<form method="post" id="edit-form">
|
||||||
|
<input type="hidden" id="edit-id" name="id">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="edit-name">Name</label>
|
||||||
|
<input type="text" id="edit-name" name="name" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="edit-icon">Icon</label>
|
||||||
|
<div class="icon-input-group">
|
||||||
|
<input type="text" id="edit-icon" name="icon" class="icon-input" required>
|
||||||
|
<i id="edit-icon-preview" class="icon-preview"></i>
|
||||||
|
<button type="button" class="icon-select-btn" onclick="openIconSelector('edit-icon', 'edit-icon-preview')">Choose</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="edit-url">URL</label>
|
||||||
|
<input type="text" id="edit-url" name="url" required>
|
||||||
|
</div>
|
||||||
|
<div style="display: flex; justify-content: space-between;">
|
||||||
|
<button type="button" id="cancel-edit" class="btn-secondary">Cancel</button>
|
||||||
|
<button type="submit" name="edit_service">Save</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Icon selector -->
|
||||||
|
<div id="icon-selector-modal" class="icon-selector-modal">
|
||||||
|
<div class="icon-selector-content">
|
||||||
|
<div class="icon-selector-header">
|
||||||
|
<h2>Select an icon</h2>
|
||||||
|
<button type="button" class="icon-selector-close" onclick="closeIconSelector()">×</button>
|
||||||
|
</div>
|
||||||
|
<input type="text" id="icon-search" class="icon-search" placeholder="Search for an icon...">
|
||||||
|
<div class="icon-categories">
|
||||||
|
<button type="button" class="icon-category active" data-category="all">All</button>
|
||||||
|
<button type="button" class="icon-category" data-category="solid">Solid</button>
|
||||||
|
<button type="button" class="icon-category" data-category="regular">Regular</button>
|
||||||
|
<button type="button" class="icon-category" data-category="brands">Brands</button>
|
||||||
|
</div>
|
||||||
|
<div id="icon-grid" class="icon-grid">
|
||||||
|
<!-- The icons will be loaded here by JavaScript. -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<a href="/services" class="back-link">← Back to home page</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="assets/js/icon-selector.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
5
admin/index.php
Normal file
5
admin/index.php
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
header('Location: /');
|
||||||
|
|
||||||
|
?>
|
121
assets/css/my.css
Normal file
121
assets/css/my.css
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
/* Custom CSS */
|
||||||
|
:root {
|
||||||
|
--primary-color: #6366f1;
|
||||||
|
--secondary-color: #4f46e5;
|
||||||
|
--background-color: #f8fafc;
|
||||||
|
--card-bg: #ffffff;
|
||||||
|
--text-color: #1e293b;
|
||||||
|
--shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: var(--background-color);
|
||||||
|
color: var(--text-color);
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1200px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 5rem;
|
||||||
|
font-weight: 800;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
background-clip: text;
|
||||||
|
color: transparent;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
text-shadow: 3px 3px 6px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtitle {
|
||||||
|
font-size: 1rem;
|
||||||
|
color: #64748b;
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
max-width: 600px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.services-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
|
||||||
|
gap: 1.5rem;
|
||||||
|
margin-top: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.service-card {
|
||||||
|
background-color: var(--card-bg);
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 1.5rem 1rem;
|
||||||
|
box-shadow: var(--shadow);
|
||||||
|
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
text-decoration: none; /* Remove underline from links */
|
||||||
|
}
|
||||||
|
|
||||||
|
.service-card:hover {
|
||||||
|
transform: translateY(-5px);
|
||||||
|
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
.service-icon {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.service-name {
|
||||||
|
display: block;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
color: var(--text-color);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-link {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 20px;
|
||||||
|
right: 20px;
|
||||||
|
color: #64748b;
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
opacity: 0.5;
|
||||||
|
transition: opacity 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-link:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.title {
|
||||||
|
font-size: 3.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.services-grid {
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
}
|
BIN
favicon.ico
Normal file
BIN
favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
11
robots.txt
Normal file
11
robots.txt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# robots.txt
|
||||||
|
# Prevents all robots from accessing sensitive areas
|
||||||
|
|
||||||
|
User-agent: *
|
||||||
|
Disallow: /admin/ # Block access to the admin folder
|
||||||
|
Disallow: /_conf/ # Blocks access to the configuration folder
|
||||||
|
|
||||||
|
# Optional: you can add a link to your sitemap to help bots crawl the rest efficiently.
|
||||||
|
# Sitemap: https://kvs.fyi/sitemap.xml
|
||||||
|
|
||||||
|
# End of file
|
86
services.php
Normal file
86
services.php
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
<?php
|
||||||
|
include_once("./_conf/global.php");
|
||||||
|
include_once("./_conf/db.php");
|
||||||
|
|
||||||
|
// Connecting to the database
|
||||||
|
try {
|
||||||
|
$pdo = new PDO($db['dsn'], $db['user'], $db['pass']);
|
||||||
|
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
die("Database connection error: " . $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieving services from the database
|
||||||
|
try {
|
||||||
|
$stmt = $pdo->query("SELECT * FROM services ORDER BY order_num ASC");
|
||||||
|
$services = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
// If the table does not yet exist, a default table is used.
|
||||||
|
$services = [
|
||||||
|
['icon' => 'fa-solid fa-envelope', 'name' => 'Mail Server', 'url' => '#'],
|
||||||
|
['icon' => 'fa-solid fa-cloud', 'name' => 'Cloud Storage', 'url' => '#'],
|
||||||
|
['icon' => 'fa-solid fa-calendar', 'name' => 'Calendar', 'url' => '#'],
|
||||||
|
['icon' => 'fa-solid fa-comments', 'name' => 'Chat', 'url' => '#']
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if you are in edit mode
|
||||||
|
$edit_mode = isset($_GET['edit']);
|
||||||
|
|
||||||
|
// If you are in edit mode, redirect to edit-services
|
||||||
|
if ($edit_mode) {
|
||||||
|
header('Location: admin/edit-services');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$title = $config['site']['name'];
|
||||||
|
$description = "Grouping of services offered by ". $config['site']['name'] . ".";
|
||||||
|
$url = "https://". $config['site']['main_domain'] ."/services";
|
||||||
|
$meta_image = "https://". $config['site']['imgs_domain'] ."/-/WaWA7/FoRUmETa47.png/raw";
|
||||||
|
$robots = "index, follow";
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<!-- Primary Meta Tags -->
|
||||||
|
<title><?php echo $title; ?></title>
|
||||||
|
<meta name="title" content="<?php echo $title; ?>" />
|
||||||
|
<meta name="description" content="<?php echo $description; ?>" />
|
||||||
|
<!-- Open Graph / Facebook -->
|
||||||
|
<meta property="og:type" content="website" />
|
||||||
|
<meta property="og:url" content="<?php echo $url; ?>" />
|
||||||
|
<meta property="og:title" content="<?php echo $title; ?>" />
|
||||||
|
<meta property="og:description" content="<?php echo $description; ?>" />
|
||||||
|
<meta property="og:image" content="<?php echo $meta_image; ?>" />
|
||||||
|
<!-- Twitter -->
|
||||||
|
<meta property="twitter:card" content="summary_large_image" />
|
||||||
|
<meta property="twitter:url" content="<?php echo $url; ?>" />
|
||||||
|
<meta property="twitter:title" content="<?php echo $title; ?>" />
|
||||||
|
<meta property="twitter:description" content="<?php echo $description; ?>" />
|
||||||
|
<meta property="twitter:image" content="<?php echo $meta_image; ?>" />
|
||||||
|
<meta name="robots" content="<?php echo $robots; ?>" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="assets/css/my.css">
|
||||||
|
<!-- Font Awesome for icons -->
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1 class="title"><?php echo $title; ?></h1>
|
||||||
|
<p class="subtitle">Public services managed by <a href="<?php echo $config['author']['bio']; ?>" title="See my Bio" target="_blank"><?php echo $config['author']['name']; ?></a></p>
|
||||||
|
|
||||||
|
<div class="services-grid">
|
||||||
|
<?php foreach ($services as $service): ?>
|
||||||
|
<a href="<?php echo htmlspecialchars($service['url']); ?>" title="<?php echo htmlspecialchars($service['name']) ?>" target="_blank" class="service-card">
|
||||||
|
<i class="service-icon <?php echo htmlspecialchars($service['icon']); ?>"></i>
|
||||||
|
<div class="service-name"><?php echo htmlspecialchars($service['name']); ?></div>
|
||||||
|
</a>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a href="?edit" class="admin-link">Admin</a>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
x
Reference in New Issue
Block a user