Abmacode12's picture
import React, { useState } from 'react';
6feb262 verified
class ProjectsComponent extends HTMLElement {
constructor() {
super();
this.projects = [
{ id: 1, name: 'Portfolio Pro', status: 'active', timestamp: '2 jours', code: '' },
{ id: 2, name: 'E-shop Mode', status: 'active', timestamp: '5 jours', code: '' },
{ id: 3, name: 'App SaaS', status: 'archived', timestamp: '10 jours', code: '' }
];
}
connectedCallback() {
this.attachShadow({ mode: 'open' });
this.render();
}
render() {
this.shadowRoot.innerHTML = `
<style>
:host {
display: block;
}
.projects-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 1.5rem;
}
.projects-title {
font-size: 1.5rem;
font-weight: 600;
color: #111827;
}
.new-project-button {
display: flex;
align-items: center;
gap: 0.5rem;
background-color: #3b82f6;
color: white;
padding: 0.5rem 1rem;
border-radius: 0.5rem;
font-weight: 500;
transition: background-color 0.2s;
}
.new-project-button:hover {
background-color: #2563eb;
}
.projects-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 1.5rem;
}
.project-card {
background-color: white;
border: 1px solid #e5e7eb;
border-radius: 0.75rem;
padding: 1.5rem;
transition: all 0.2s;
cursor: pointer;
}
.project-card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}
.project-card.active {
border-left: 4px solid #10b981;
}
.project-name {
font-size: 1.125rem;
font-weight: 600;
color: #111827;
margin-bottom: 0.5rem;
}
.project-meta {
display: flex;
align-items: center;
gap: 0.5rem;
margin-bottom: 1rem;
}
.project-status {
font-size: 0.75rem;
padding: 0.25rem 0.5rem;
border-radius: 1rem;
}
.project-status.active {
background-color: #ecfdf5;
color: #065f46;
}
.project-status.archived {
background-color: #f3f4f6;
color: #4b5563;
}
.project-time {
font-size: 0.75rem;
color: #6b7280;
}
.project-actions {
display: flex;
gap: 0.5rem;
margin-top: 1rem;
}
.project-action {
padding: 0.5rem;
border-radius: 0.375rem;
background-color: #f3f4f6;
color: #4b5563;
transition: all 0.2s;
display: flex;
align-items: center;
justify-content: center;
}
.project-action:hover {
background-color: #e5e7eb;
}
.empty-state {
text-align: center;
padding: 3rem 0;
grid-column: 1 / -1;
}
.empty-icon {
width: 3rem;
height: 3rem;
background-color: #f3f4f6;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 1rem;
color: #9ca3af;
}
.empty-title {
font-size: 1.125rem;
font-weight: 600;
color: #111827;
margin-bottom: 0.5rem;
}
.empty-description {
color: #6b7280;
max-width: 400px;
margin: 0 auto 1.5rem;
}
.empty-button {
background-color: #3b82f6;
color: white;
padding: 0.5rem 1rem;
border-radius: 0.5rem;
font-weight: 500;
transition: background-color 0.2s;
}
.empty-button:hover {
background-color: #2563eb;
}
@media (max-width: 640px) {
.projects-grid {
grid-template-columns: 1fr;
}
}
</style>
<div class="projects-header">
<h2 class="projects-title">Mes Projets</h2>
<button class="new-project-button">
<i data-feather="plus"></i>
<span>Nouveau projet</span>
</button>
</div>
<div class="projects-grid">
${this.projects.length > 0 ?
this.projects.map(project => `
<div class="project-card" data-id="${project.id}">
<h3 class="project-name">${project.name}</h3>
<div class="project-meta">
<span class="project-status ${project.status}">${project.status === 'active' ? 'Actif' : 'Archivé'}</span>
<span class="project-time">${project.timestamp}</span>
</div>
<div class="project-actions">
<button class="project-action" title="Ouvrir">
<i data-feather="folder"></i>
</button>
<button class="project-action" title="Partager">
<i data-feather="share-2"></i>
</button>
<button class="project-action" title="Archiver">
<i data-feather="archive"></i>
</button>
</div>
</div>
`).join('') : `
<div class="empty-state">
<div class="empty-icon">
<i data-feather="folder"></i>
</div>
<h3 class="empty-title">Aucun projet trouvé</h3>
<p class="empty-description">Commencez par créer un nouveau projet ou demandez à Rosalinda de générer du code pour vous.</p>
<button class="empty-button">
<i data-feather="plus"></i>
<span>Créer un projet</span>
</button>
</div>
`}
</div>
`;
// Initialize feather icons
const featherScript = document.createElement('script');
featherScript.src = 'https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js';
this.shadowRoot.appendChild(featherScript);
featherScript.onload = () => {
feather.replace();
};
// Add event listeners
this.shadowRoot.querySelectorAll('.project-card').forEach(card => {
card.addEventListener('click', () => {
const projectId = parseInt(card.getAttribute('data-id'));
const project = this.projects.find(p => p.id === projectId);
if (project && project.code) {
document.dispatchEvent(new CustomEvent('show-code', {
detail: {
code: project.code,
description: project.name
}
}));
}
});
});
// New project button
this.shadowRoot.querySelector('.new-project-button').addEventListener('click', () => {
document.dispatchEvent(new CustomEvent('navigate', { detail: 'chat' }));
});
// Empty state button
const emptyButton = this.shadowRoot.querySelector('.empty-button');
if (emptyButton) {
emptyButton.addEventListener('click', () => {
document.dispatchEvent(new CustomEvent('navigate', { detail: 'chat' }));
});
}
}
}
customElements.define('projects-component', ProjectsComponent);