taskflow / index.html
leroyfal's picture
Add 2 files
26ca223 verified
Raw History Blame Contribute Delete
28.8 kB
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TaskFlow - Mes Projets</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
.sidebar {
transition: all 0.3s ease;
}
.project-card:hover {
transform: translateY(-2px);
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
}
.dropdown-menu {
animation: fadeIn 0.2s ease-out;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
</style>
</head>
<body class="bg-gray-50 font-sans">
<!-- App Container -->
<div class="flex h-screen overflow-hidden">
<!-- Sidebar Navigation -->
<div class="sidebar bg-indigo-700 text-white w-64 flex-shrink-0 hidden md:block">
<div class="p-4 flex items-center space-x-2 border-b border-indigo-600">
<i class="fas fa-tasks text-2xl"></i>
<h1 class="text-xl font-bold">TaskFlow</h1>
</div>
<nav class="p-4">
<div class="mb-8">
<h2 class="text-xs uppercase tracking-wider text-indigo-300 mb-4">Menu Principal</h2>
<ul class="space-y-2">
<li>
<a href="#" class="flex items-center space-x-2 p-2 rounded hover:bg-indigo-800">
<i class="fas fa-home w-5"></i>
<span>Tableau de bord</span>
</a>
</li>
<li>
<a href="#" class="flex items-center space-x-2 p-2 rounded bg-indigo-800">
<i class="fas fa-project-diagram w-5"></i>
<span>Mes projets</span>
</a>
</li>
<li>
<a href="#" class="flex items-center space-x-2 p-2 rounded hover:bg-indigo-800">
<i class="fas fa-tasks w-5"></i>
<span>Mes tâches</span>
</a>
</li>
<li>
<a href="#" class="flex items-center space-x-2 p-2 rounded hover:bg-indigo-800">
<i class="fas fa-calendar-alt w-5"></i>
<span>Calendrier</span>
</a>
</li>
</ul>
</div>
<div>
<h2 class="text-xs uppercase tracking-wider text-indigo-300 mb-4">Équipes</h2>
<ul class="space-y-2">
<li>
<a href="#" class="flex items-center space-x-2 p-2 rounded hover:bg-indigo-800">
<div class="w-5 h-5 rounded-full bg-green-500 flex items-center justify-center text-xs">D</div>
<span>Développement</span>
</a>
</li>
<li>
<a href="#" class="flex items-center space-x-2 p-2 rounded hover:bg-indigo-800">
<div class="w-5 h-5 rounded-full bg-blue-500 flex items-center justify-center text-xs">M</div>
<span>Marketing</span>
</a>
</li>
<li>
<a href="#" class="flex items-center space-x-2 p-2 rounded hover:bg-indigo-800">
<div class="w-5 h-5 rounded-full bg-purple-500 flex items-center justify-center text-xs">V</div>
<span>Ventes</span>
</a>
</li>
</ul>
</div>
</nav>
</div>
<!-- Main Content Area -->
<div class="flex-1 flex flex-col overflow-hidden">
<!-- Top Navigation Bar -->
<header class="bg-white border-b border-gray-200 flex items-center justify-between p-4">
<div class="flex items-center space-x-4">
<button class="md:hidden text-gray-600">
<i class="fas fa-bars text-xl"></i>
</button>
<h2 class="text-xl font-semibold text-gray-800">Mes projets</h2>
</div>
<div class="flex items-center space-x-4">
<div class="relative">
<button class="p-2 rounded-full hover:bg-gray-100">
<i class="fas fa-bell text-gray-600"></i>
<span class="absolute top-0 right-0 w-2 h-2 bg-red-500 rounded-full"></span>
</button>
</div>
<div class="relative">
<button class="flex items-center space-x-2">
<div class="w-8 h-8 rounded-full bg-indigo-500 flex items-center justify-center text-white">JD</div>
<span class="hidden md:inline">John Doe</span>
<i class="fas fa-chevron-down text-xs hidden md:inline"></i>
</button>
</div>
</div>
</header>
<!-- Main Content -->
<main class="flex-1 overflow-auto p-6 bg-gray-50">
<!-- Projects Header -->
<div class="flex justify-between items-center mb-6">
<div>
<h1 class="text-2xl font-bold text-gray-800">Tous mes projets</h1>
<p class="text-gray-600">Gérez et suivez l'avancement de tous vos projets</p>
</div>
<button
class="bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700 flex items-center space-x-2"
onclick="openModal('newProjectModal')"
>
<i class="fas fa-plus"></i>
<span>Nouveau projet</span>
</button>
</div>
<!-- Projects Filters -->
<div class="bg-white p-4 rounded-lg shadow-sm border border-gray-100 mb-6">
<div class="flex flex-col md:flex-row md:items-center md:justify-between space-y-4 md:space-y-0">
<div class="relative md:w-64">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-search text-gray-400"></i>
</div>
<input
type="text"
class="block w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md leading-5 bg-white placeholder-gray-500 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
placeholder="Rechercher un projet..."
oninput="filterProjects(this.value)"
>
</div>
<div class="flex space-x-2">
<select class="block w-full pl-3 pr-10 py-2 text-base border border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md">
<option>Tous les statuts</option>
<option>En cours</option>
<option>Terminé</option>
<option>En attente</option>
</select>
<select class="block w-full pl-3 pr-10 py-2 text-base border border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md">
<option>Toutes les équipes</option>
<option>Développement</option>
<option>Marketing</option>
<option>Ventes</option>
</select>
<button class="px-3 py-2 border border-gray-300 rounded-md text-sm hover:bg-gray-50">
<i class="fas fa-filter"></i>
</button>
</div>
</div>
</div>
<!-- Projects Grid -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6" id="projects-container">
<!-- Project cards will be dynamically inserted here -->
</div>
<!-- Empty State -->
<div class="hidden flex-col items-center justify-center py-12 text-center" id="empty-state">
<div class="w-24 h-24 bg-indigo-50 rounded-full flex items-center justify-center mb-4">
<i class="fas fa-project-diagram text-indigo-500 text-3xl"></i>
</div>
<h3 class="text-lg font-medium text-gray-900 mb-2">Aucun projet trouvé</h3>
<p class="text-gray-500 max-w-md">Créez votre premier projet pour commencer à organiser votre travail et collaborer avec votre équipe.</p>
<button
class="mt-6 bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700 flex items-center space-x-2"
onclick="openModal('newProjectModal')"
>
<i class="fas fa-plus"></i>
<span>Créer un projet</span>
</button>
</div>
</main>
</div>
</div>
<!-- New Project Modal -->
<div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden" id="newProjectModal">
<div class="bg-white rounded-lg shadow-xl w-full max-w-md">
<div class="p-6">
<div class="flex justify-between items-center mb-4">
<h3 class="text-lg font-semibold">Nouveau projet</h3>
<button class="text-gray-400 hover:text-gray-500" onclick="closeModal('newProjectModal')">
<i class="fas fa-times"></i>
</button>
</div>
<form id="projectForm">
<div class="mb-4">
<label class="block text-gray-700 text-sm font-medium mb-2" for="project-name">Nom du projet*</label>
<input
class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500"
id="project-name"
type="text"
placeholder="Ex: Refonte du site web"
required
>
</div>
<div class="mb-4">
<label class="block text-gray-700 text-sm font-medium mb-2" for="project-team">Équipe*</label>
<select
class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500"
id="project-team"
required
>
<option value="">Sélectionner une équipe</option>
<option>Développement</option>
<option>Marketing</option>
<option>Ventes</option>
<option>Créer une nouvelle équipe...</option>
</select>
</div>
<div class="mb-4">
<label class="block text-gray-700 text-sm font-medium mb-2" for="project-description">Description</label>
<textarea
class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500"
id="project-description"
rows="3"
placeholder="Décrivez le projet..."
></textarea>
</div>
<div class="mb-4">
<label class="block text-gray-700 text-sm font-medium mb-2">Couleur du projet</label>
<div class="flex space-x-2">
<div class="w-8 h-8 rounded-full bg-indigo-500 border-2 border-indigo-700 cursor-pointer"></div>
<div class="w-8 h-8 rounded-full bg-blue-500 border-2 border-transparent cursor-pointer hover:border-blue-700"></div>
<div class="w-8 h-8 rounded-full bg-green-500 border-2 border-transparent cursor-pointer hover:border-green-700"></div>
<div class="w-8 h-8 rounded-full bg-yellow-500 border-2 border-transparent cursor-pointer hover:border-yellow-700"></div>
<div class="w-8 h-8 rounded-full bg-red-500 border-2 border-transparent cursor-pointer hover:border-red-700"></div>
</div>
</div>
<div class="flex justify-end space-x-3">
<button
type="button"
class="px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
onclick="closeModal('newProjectModal')"
>
Annuler
</button>
<button
type="submit"
class="px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
>
Créer
</button>
</div>
</form>
</div>
</div>
</div>
<!-- JavaScript -->
<script>
// Mock data for projects
const projects = [
{
id: 1,
name: "Refonte du site web",
team: "Développement",
description: "Refonte complète du site web avec nouvelle UI/UX et intégration CMS",
progress: 65,
status: "En cours",
members: ["JD", "AL", "SM", "+3"],
dueDate: "15/08/2023",
color: "indigo"
},
{
id: 2,
name: "Campagne marketing",
team: "Marketing",
description: "Lancement de la nouvelle campagne publicitaire pour le produit X",
progress: 30,
status: "En attente",
members: ["MP", "TM"],
dueDate: "30/09/2023",
color: "blue"
},
{
id: 3,
name: "Migration serveur",
team: "IT",
description: "Migration des serveurs vers le nouveau datacenter",
progress: 90,
status: "Presque terminé",
members: ["DL", "AL"],
dueDate: "25/06/2023",
color: "green"
},
{
id: 4,
name: "Stratégie SEO",
team: "Marketing",
description: "Mise en place de la nouvelle stratégie SEO pour améliorer le référencement",
progress: 45,
status: "En cours",
members: ["TM", "JD", "MP"],
dueDate: "10/09/2023",
color: "purple"
},
{
id: 5,
name: "Formation équipe",
team: "Ressources Humaines",
description: "Organisation des sessions de formation pour les nouvelles recrues",
progress: 20,
status: "En attente",
members: ["HR", "TM"],
dueDate: "05/09/2023",
color: "yellow"
},
{
id: 6,
name: "Analyse données",
team: "Analyse",
description: "Analyse des données clients pour le prochain trimestre",
progress: 10,
status: "À démarrer",
members: ["DA", "AL"],
dueDate: "20/09/2023",
color: "red"
}
];
// DOM Ready
document.addEventListener('DOMContentLoaded', function() {
// Load projects when page loads
loadProjects();
// Handle form submission
document.getElementById('projectForm').addEventListener('submit', function(e) {
e.preventDefault();
createNewProject();
});
// Initialize dropdown menus
initDropdowns();
});
// Load projects into the UI
function loadProjects() {
const projectsContainer = document.getElementById('projects-container');
const emptyState = document.getElementById('empty-state');
// Clear existing projects
projectsContainer.innerHTML = '';
if (projects.length === 0) {
emptyState.classList.remove('hidden');
projectsContainer.classList.add('hidden');
} else {
emptyState.classList.add('hidden');
projectsContainer.classList.remove('hidden');
projects.forEach(project => {
const projectCard = document.createElement('div');
projectCard.className = 'project-card bg-white rounded-lg shadow-sm border border-gray-100 overflow-hidden hover:shadow-md transition-shadow duration-200';
// Determine color classes based on project color
let progressColor = 'bg-indigo-600';
let statusColor = 'bg-indigo-50 text-indigo-600';
if (project.color === 'blue') {
progressColor = 'bg-blue-500';
statusColor = 'bg-blue-50 text-blue-600';
} else if (project.color === 'green') {
progressColor = 'bg-green-500';
statusColor = 'bg-green-50 text-green-600';
} else if (project.color === 'yellow') {
progressColor = 'bg-yellow-500';
statusColor = 'bg-yellow-50 text-yellow-600';
} else if (project.color === 'red') {
progressColor = 'bg-red-500';
statusColor = 'bg-red-50 text-red-600';
} else if (project.color === 'purple') {
progressColor = 'bg-purple-500';
statusColor = 'bg-purple-50 text-purple-600';
}
projectCard.innerHTML = `
<div class="p-6">
<div class="flex justify-between items-start">
<div>
<h3 class="font-bold text-lg mb-1">${project.name}</h3>
<p class="text-gray-500 text-sm">${project.team}</p>
</div>
<div class="dropdown relative">
<button class="text-gray-400 hover:text-gray-600">
<i class="fas fa-ellipsis-h"></i>
</button>
<div class="dropdown-menu hidden absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg z-10">
<div class="py-1">
<a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Modifier</a>
<a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Archiver</a>
<div class="border-t border-gray-100"></div>
<a href="#" class="block px-4 py-2 text-sm text-red-600 hover:bg-gray-100">Supprimer</a>
</div>
</div>
</div>
</div>
<p class="text-gray-600 mt-4 text-sm">${project.description}</p>
<div class="mt-6">
<div class="flex justify-between text-sm text-gray-500 mb-2">
<span>Progression</span>
<span>${project.progress}%</span>
</div>
<div class="w-full bg-gray-200 rounded-full h-2">
<div class="${progressColor} h-2 rounded-full" style="width: ${project.progress}%"></div>
</div>
</div>
<div class="mt-6 flex justify-between items-center">
<div class="flex -space-x-2">
${project.members.map(member =>
member.startsWith('+')
? `<div class="w-8 h-8 rounded-full border-2 border-white bg-gray-100 flex items-center justify-center text-xs font-medium">${member}</div>`
: `<div class="w-8 h-8 rounded-full border-2 border-white bg-${project.color}-500 flex items-center justify-center text-white text-xs">${member}</div>`
).join('')}
</div>
<span class="text-xs px-2 py-1 ${statusColor} rounded-full">${project.status}</span>
</div>
</div>
`;
projectsContainer.appendChild(projectCard);
});
}
}
// Filter projects based on search input
function filterProjects(searchTerm) {
const filteredProjects = projects.filter(project =>
project.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
project.team.toLowerCase().includes(searchTerm.toLowerCase()) ||
project.description.toLowerCase().includes(searchTerm.toLowerCase())
);
// For demo purposes, we'll just log the filtered projects
console.log("Filtrer les projets avec:", searchTerm);
console.log("Résultats:", filteredProjects);
// In a real app, you would update the UI with filtered projects
// For now, we'll just show/hide the empty state based on search
const emptyState = document.getElementById('empty-state');
const projectsContainer = document.getElementById('projects-container');
if (searchTerm && filteredProjects.length === 0) {
emptyState.classList.remove('hidden');
projectsContainer.classList.add('hidden');
// Update empty state message for search
emptyState.querySelector('h3').textContent = "Aucun projet trouvé";
emptyState.querySelector('p').textContent = `Aucun projet ne correspond à votre recherche "${searchTerm}". Essayez d'autres termes.`;
} else {
emptyState.classList.add('hidden');
projectsContainer.classList.remove('hidden');
}
}
// Create a new project
function createNewProject() {
const name = document.getElementById('project-name').value;
const team = document.getElementById('project-team').value;
const description = document.getElementById('project-description').value;
// Generate a random color for the new project
const colors = ['indigo', 'blue', 'green', 'yellow', 'red', 'purple'];
const randomColor = colors[Math.floor(Math.random() * colors.length)];
// Create a new project object
const newProject = {
id: projects.length + 1,
name: name,
team: team,
description: description,
progress: 0,
status: "À démarrer",
members: ["JD", "TM"],
dueDate: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toLocaleDateString('fr-FR'),
color: randomColor
};
// Add to our projects array (in a real app, this would be an API call)
projects.push(newProject);
// Reload projects
loadProjects();
// Close modal
closeModal('newProjectModal');
// Reset form
document.getElementById('projectForm').reset();
}
// Initialize dropdown menus
function initDropdowns() {
document.querySelectorAll('.dropdown button').forEach(button => {
button.addEventListener('click', function(e) {
e.stopPropagation();
const dropdown = this.parentElement;
const menu = dropdown.querySelector('.dropdown-menu');
// Close all other dropdowns first
document.querySelectorAll('.dropdown-menu').forEach(m => {
if (m !== menu) m.classList.add('hidden');
});
// Toggle current dropdown
menu.classList.toggle('hidden');
});
});
// Close dropdowns when clicking elsewhere
document.addEventListener('click', function() {
document.querySelectorAll('.dropdown-menu').forEach(menu => {
menu.classList.add('hidden');
});
});
}
// Modal functions
function openModal(modalId) {
document.getElementById(modalId).classList.remove('hidden');
}
function closeModal(modalId) {
document.getElementById(modalId).classList.add('hidden');
}
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=leroyfal/taskflow" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>