<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Templates de Workflows n8n</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
padding-top: 20px;
padding-bottom: 20px;
}
.header {
padding-bottom: 20px;
border-bottom: 1px solid #e5e5e5;
margin-bottom: 30px;
}
.template-card {
margin-bottom: 20px;
border-radius: 10px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
height: 100%;
}
.template-card .card-body {
display: flex;
flex-direction: column;
}
.template-card .btn {
margin-top: auto;
}
.template-tag {
display: inline-block;
background-color: #e9ecef;
padding: 0.25rem 0.5rem;
border-radius: 0.25rem;
margin-right: 0.5rem;
margin-bottom: 0.5rem;
font-size: 0.875rem;
}
.nav-link {
color: #495057;
font-weight: 500;
}
.nav-link.active {
color: #007bff;
font-weight: 700;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<div class="d-flex justify-content-between align-items-center">
<h1>Templates de Workflows n8n</h1>
<nav>
<ul class="nav">
<li class="nav-item"><a href="/" class="nav-link">Accueil</a></li>
<li class="nav-item"><a href="/n8n-api.html" class="nav-link">API n8n</a></li>
<li class="nav-item"><a href="/workflow-manager.html" class="nav-link">Gestionnaire de Workflows</a></li>
<li class="nav-item"><a href="/validator.html" class="nav-link">Validateur</a></li>
<li class="nav-item"><a href="/templates.html" class="nav-link active">Templates</a></li>
<li class="nav-item"><a href="/docs.html" class="nav-link">Documentation</a></li>
</ul>
</nav>
</div>
</div>
<div class="row mb-4">
<div class="col-md-12">
<div class="card">
<div class="card-body">
<h5 class="card-title">Recherche de templates</h5>
<div class="row g-3">
<div class="col-md-6">
<input type="text" class="form-control" id="search-input" placeholder="Rechercher par nom ou description...">
</div>
<div class="col-md-4">
<select class="form-select" id="category-filter">
<option value="">Toutes les catégories</option>
<option value="api">API</option>
<option value="database">Base de données</option>
<option value="email">Email</option>
<option value="file">Fichier</option>
<option value="integration">Intégration</option>
<option value="notification">Notification</option>
</select>
</div>
<div class="col-md-2">
<button class="btn btn-primary w-100" id="search-button">Rechercher</button>
</div>
</div>
</div>
</div>
</div>
</div>
<h2 class="mb-4">Templates disponibles</h2>
<div class="row" id="templates-container">
<!-- Les templates seront chargés dynamiquement ici -->
<div class="col-12 text-center">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Chargement...</span>
</div>
<p>Chargement des templates...</p>
</div>
</div>
<!-- Modal pour afficher les détails du template -->
<div class="modal fade" id="template-modal" tabindex="-1" aria-labelledby="template-modal-label" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="template-modal-label">Détails du template</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
</div>
<div class="modal-body" id="template-modal-body">
<!-- Le contenu sera chargé dynamiquement -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Fermer</button>
<button type="button" class="btn btn-primary" id="import-template-btn">Importer ce template</button>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
<script>
// Données de démonstration pour les templates
const templateData = [
{
id: "template1",
name: "Notification Slack pour nouveaux emails",
description: "Envoie une notification Slack lorsqu'un nouvel email est reçu dans une boîte mail spécifique.",
category: "notification",
tags: ["slack", "email", "notification"],
complexity: "Facile",
nodes: 4,
author: "Équipe n8n",
created: "2023-01-15",
image: "https://n8n.io/images/workflows/slack-notification.png"
},
{
id: "template2",
name: "Sauvegarde automatique de fichiers Google Drive vers Dropbox",
description: "Sauvegarde périodiquement les fichiers d'un dossier Google Drive vers Dropbox.",
category: "file",
tags: ["google drive", "dropbox", "sauvegarde", "automatisation"],
complexity: "Moyenne",
nodes: 7,
author: "Équipe n8n",
created: "2023-02-20",
image: "https://n8n.io/images/workflows/gdrive-dropbox.png"
},
{
id: "template3",
name: "Synchronisation de contacts CRM vers Mailchimp",
description: "Synchronise automatiquement les contacts d'un CRM vers une liste Mailchimp.",
category: "integration",
tags: ["crm", "mailchimp", "contacts", "synchronisation"],
complexity: "Moyenne",
nodes: 6,
author: "Équipe n8n",
created: "2023-03-10",
image: "https://n8n.io/images/workflows/crm-mailchimp.png"
},
{
id: "template4",
name: "Extraction de données API vers base de données",
description: "Récupère des données d'une API REST et les stocke dans une base de données SQL.",
category: "api",
tags: ["api", "database", "extraction", "sql"],
complexity: "Avancée",
nodes: 8,
author: "Équipe n8n",
created: "2023-04-05",
image: "https://n8n.io/images/workflows/api-to-db.png"
},
{
id: "template5",
name: "Rapport quotidien par email",
description: "Génère et envoie un rapport quotidien par email avec des données agrégées.",
category: "email",
tags: ["rapport", "email", "planification", "données"],
complexity: "Moyenne",
nodes: 5,
author: "Équipe n8n",
created: "2023-05-12",
image: "https://n8n.io/images/workflows/daily-report.png"
},
{
id: "template6",
name: "Surveillance de site web et alerte",
description: "Surveille la disponibilité d'un site web et envoie des alertes en cas de panne.",
category: "notification",
tags: ["surveillance", "alerte", "site web", "disponibilité"],
complexity: "Facile",
nodes: 4,
author: "Équipe n8n",
created: "2023-06-18",
image: "https://n8n.io/images/workflows/website-monitoring.png"
}
];
document.addEventListener('DOMContentLoaded', function() {
// Afficher les templates
displayTemplates(templateData);
// Configurer la recherche
document.getElementById('search-button').addEventListener('click', function() {
filterTemplates();
});
// Configurer le modal
const templateModal = new bootstrap.Modal(document.getElementById('template-modal'));
// Configurer le bouton d'importation
document.getElementById('import-template-btn').addEventListener('click', function() {
const templateId = this.getAttribute('data-template-id');
importTemplate(templateId);
templateModal.hide();
});
});
function displayTemplates(templates) {
const container = document.getElementById('templates-container');
container.innerHTML = '';
if (templates.length === 0) {
container.innerHTML = '<div class="col-12"><div class="alert alert-info">Aucun template ne correspond à votre recherche.</div></div>';
return;
}
templates.forEach(template => {
const col = document.createElement('div');
col.className = 'col-md-4 mb-4';
const card = document.createElement('div');
card.className = 'card template-card';
const cardBody = document.createElement('div');
cardBody.className = 'card-body';
const title = document.createElement('h5');
title.className = 'card-title';
title.textContent = template.name;
const category = document.createElement('div');
category.className = 'mb-2';
category.innerHTML = `<span class="badge bg-primary">${getCategoryName(template.category)}</span>`;
const description = document.createElement('p');
description.className = 'card-text';
description.textContent = template.description;
const tagsDiv = document.createElement('div');
tagsDiv.className = 'mb-3';
template.tags.forEach(tag => {
const tagSpan = document.createElement('span');
tagSpan.className = 'template-tag';
tagSpan.textContent = tag;
tagsDiv.appendChild(tagSpan);
});
const details = document.createElement('div');
details.className = 'mb-3 text-muted small';
details.innerHTML = `
<div>Complexité: ${template.complexity}</div>
<div>Nombre de nœuds: ${template.nodes}</div>
<div>Auteur: ${template.author}</div>
<div>Créé le: ${formatDate(template.created)}</div>
`;
const button = document.createElement('button');
button.className = 'btn btn-outline-primary mt-auto';
button.textContent = 'Voir les détails';
button.setAttribute('data-bs-toggle', 'modal');
button.setAttribute('data-bs-target', '#template-modal');
button.addEventListener('click', function() {
showTemplateDetails(template);
});
cardBody.appendChild(title);
cardBody.appendChild(category);
cardBody.appendChild(description);
cardBody.appendChild(tagsDiv);
cardBody.appendChild(details);
cardBody.appendChild(button);
card.appendChild(cardBody);
col.appendChild(card);
container.appendChild(col);
});
}
function filterTemplates() {
const searchTerm = document.getElementById('search-input').value.toLowerCase();
const categoryFilter = document.getElementById('category-filter').value;
const filteredTemplates = templateData.filter(template => {
const matchesSearch = template.name.toLowerCase().includes(searchTerm) ||
template.description.toLowerCase().includes(searchTerm) ||
template.tags.some(tag => tag.toLowerCase().includes(searchTerm));
const matchesCategory = categoryFilter === '' || template.category === categoryFilter;
return matchesSearch && matchesCategory;
});
displayTemplates(filteredTemplates);
}
function showTemplateDetails(template) {
const modalBody = document.getElementById('template-modal-body');
const modalTitle = document.getElementById('template-modal-label');
const importButton = document.getElementById('import-template-btn');
modalTitle.textContent = template.name;
importButton.setAttribute('data-template-id', template.id);
modalBody.innerHTML = `
<div class="row">
<div class="col-md-6">
<img src="${template.image || 'https://via.placeholder.com/300x200?text=Pas+d%27image'}" class="img-fluid mb-3" alt="${template.name}">
<div class="mb-3">
<strong>Catégorie:</strong> ${getCategoryName(template.category)}
</div>
<div class="mb-3">
<strong>Tags:</strong>
${template.tags.map(tag => `<span class="template-tag">${tag}</span>`).join('')}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<strong>Description:</strong>
<p>${template.description}</p>
</div>
<div class="mb-3">
<strong>Complexité:</strong> ${template.complexity}
</div>
<div class="mb-3">
<strong>Nombre de nœuds:</strong> ${template.nodes}
</div>
<div class="mb-3">
<strong>Auteur:</strong> ${template.author}
</div>
<div class="mb-3">
<strong>Créé le:</strong> ${formatDate(template.created)}
</div>
</div>
</div>
<div class="row mt-3">
<div class="col-12">
<h5>Utilisation recommandée</h5>
<p>Ce template est idéal pour ${getTemplateUsage(template.category)}.</p>
<p>Après l'importation, vous devrez configurer les connexions aux services externes et personnaliser les paramètres selon vos besoins.</p>
</div>
</div>
`;
}
function importTemplate(templateId) {
// Simuler l'importation d'un template
alert(`Le template ${templateId} sera importé dans votre instance n8n.`);
// Dans une implémentation réelle, vous feriez un appel API ici
// pour importer le template dans l'instance n8n
}
function getCategoryName(category) {
const categories = {
'api': 'API',
'database': 'Base de données',
'email': 'Email',
'file': 'Fichier',
'integration': 'Intégration',
'notification': 'Notification'
};
return categories[category] || category;
}
function getTemplateUsage(category) {
const usages = {
'api': 'l\'intégration avec des services API externes',
'database': 'la gestion et la manipulation de données dans des bases de données',
'email': 'l\'automatisation des communications par email',
'file': 'la gestion et le traitement de fichiers',
'integration': 'la connexion entre différents services',
'notification': 'la mise en place de systèmes d\'alertes et de notifications'
};
return usages[category] || 'l\'automatisation de vos processus';
}
function formatDate(dateString) {
const date = new Date(dateString);
return date.toLocaleDateString('fr-FR', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
}
</script>
</body>
</html>