| class CodeComponent extends HTMLElement { |
| constructor() { |
| super(); |
| this.code = ''; |
| this.description = ''; |
| } |
|
|
| connectedCallback() { |
| this.attachShadow({ mode: 'open' }); |
| this.render(); |
| |
| |
| document.addEventListener('show-code', (e) => { |
| this.code = e.detail.code; |
| this.description = e.detail.description; |
| this.render(); |
| }); |
| } |
|
|
| render() { |
| this.shadowRoot.innerHTML = ` |
| <style> |
| :host { |
| display: block; |
| } |
| |
| .code-header { |
| display: flex; |
| align-items: center; |
| justify-content: space-between; |
| margin-bottom: 1.5rem; |
| } |
| |
| .code-title { |
| font-size: 1.5rem; |
| font-weight: 600; |
| color: #111827; |
| } |
| |
| .code-description { |
| color: #6b7280; |
| margin-bottom: 0.5rem; |
| } |
| |
| .code-actions { |
| display: flex; |
| gap: 0.5rem; |
| } |
| |
| .code-action { |
| display: flex; |
| align-items: center; |
| gap: 0.5rem; |
| padding: 0.5rem 1rem; |
| border-radius: 0.5rem; |
| font-weight: 500; |
| transition: all 0.2s; |
| } |
| |
| .code-action.primary { |
| background-color: #3b82f6; |
| color: white; |
| } |
| |
| .code-action.primary:hover { |
| background-color: #2563eb; |
| } |
| |
| .code-action.secondary { |
| background-color: #f3f4f6; |
| color: #4b5563; |
| } |
| |
| .code-action.secondary:hover { |
| background-color: #e5e7eb; |
| } |
| |
| .code-block { |
| position: relative; |
| background-color: #1e293b; |
| color: #f8fafc; |
| border-radius: 0.5rem; |
| overflow: hidden; |
| margin-bottom: 1.5rem; |
| } |
| |
| .code-block pre { |
| padding: 1.5rem; |
| overflow-x: auto; |
| font-family: 'Courier New', Courier, monospace; |
| font-size: 0.875rem; |
| margin: 0; |
| } |
| |
| .code-toolbar { |
| position: absolute; |
| top: 0.5rem; |
| right: 0.5rem; |
| display: flex; |
| gap: 0.5rem; |
| } |
| |
| .code-toolbar button { |
| background-color: #334155; |
| color: white; |
| border: none; |
| padding: 0.25rem 0.5rem; |
| border-radius: 0.25rem; |
| cursor: pointer; |
| font-size: 0.75rem; |
| display: flex; |
| align-items: center; |
| gap: 0.25rem; |
| } |
| |
| .code-toolbar button:hover { |
| background-color: #475569; |
| } |
| |
| .preview-container { |
| border: 1px solid #e5e7eb; |
| border-radius: 0.5rem; |
| overflow: hidden; |
| margin-top: 1.5rem; |
| } |
| |
| .preview-header { |
| background-color: #f3f4f6; |
| padding: 0.75rem 1rem; |
| border-bottom: 1px solid #e5e7eb; |
| display: flex; |
| align-items: center; |
| justify-content: space-between; |
| } |
| |
| .preview-title { |
| font-weight: 500; |
| color: #111827; |
| } |
| |
| .preview-actions { |
| display: flex; |
| gap: 0.5rem; |
| } |
| |
| .preview-action { |
| padding: 0.25rem; |
| border-radius: 0.25rem; |
| color: #6b7280; |
| transition: all 0.2s; |
| } |
| |
| .preview-action:hover { |
| background-color: #e5e7eb; |
| color: #111827; |
| } |
| |
| .preview-content { |
| background-color: white; |
| min-height: 200px; |
| padding: 1rem; |
| } |
| |
| .empty-state { |
| text-align: center; |
| padding: 3rem 0; |
| } |
| |
| .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; |
| } |
| </style> |
| |
| ${this.code ? ` |
| <div class="code-header"> |
| <div> |
| <h2 class="code-title">Code Généré</h2> |
| <p class="code-description">${this.description}</p> |
| </div> |
| <div class="code-actions"> |
| <button class="code-action primary" id="save-project"> |
| <i data-feather="save"></i> |
| <span>Sauvegarder</span> |
| </button> |
| <button class="code-action secondary" id="new-chat"> |
| <i data-feather="message-square"></i> |
| <span>Nouveau chat</span> |
| </button> |
| </div> |
| </div> |
| |
| <div class="code-block"> |
| <div class="code-toolbar"> |
| <button class="copy-code" data-code="${escapeHtml(this.code)}"> |
| <i data-feather="copy"></i> |
| <span>Copier</span> |
| </button> |
| <button class="download-code" data-code="${escapeHtml(this.code)}"> |
| <i data-feather="download"></i> |
| <span>Télécharger</span> |
| </button> |
| </div> |
| <pre><code>${escapeHtml(this.code)}</code></pre> |
| </div> |
| |
| <div class="preview-container"> |
| <div class="preview-header"> |
| <div class="preview-title">Aperçu</div> |
| <div class="preview-actions"> |
| <button class="preview-action" title="Actualiser"> |
| <i data-feather="refresh-cw"></i> |
| </button> |
| <button class="preview-action" title="Plein écran"> |
| <i data-feather="maximize"></i> |
| </button> |
| </div> |
| </div> |
| <div class="preview-content"> |
| <iframe srcdoc="${escapeHtml(this.code)}" frameborder="0" style="width: 100%; height: 400px;"></iframe> |
| </div> |
| </div> |
| ` : ` |
| <div class="empty-state"> |
| <div class="empty-icon"> |
| <i data-feather="code"></i> |
| </div> |
| <h3 class="empty-title">Aucun code généré</h3> |
| <p class="empty-description">Demandez à Rosalinda de générer du code pour voir le résultat ici.</p> |
| <button class="empty-button" id="go-to-chat"> |
| <i data-feather="message-square"></i> |
| <span>Discuter avec Rosalinda</span> |
| </button> |
| </div> |
| `} |
| `; |
|
|
| |
| 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(); |
| }; |
|
|
| |
| if (this.code) { |
| |
| this.shadowRoot.querySelector('.copy-code').addEventListener('click', () => { |
| const code = this.shadowRoot.querySelector('.copy-code').getAttribute('data-code'); |
| navigator.clipboard.writeText(code).then(() => { |
| const button = this.shadowRoot.querySelector('.copy-code'); |
| const originalText = button.innerHTML; |
| button.innerHTML = '<i data-feather="check"></i> Copié !'; |
| feather.replace(); |
| setTimeout(() => { |
| button.innerHTML = originalText; |
| feather.replace(); |
| }, 2000); |
| }); |
| }); |
|
|
| |
| this.shadowRoot.querySelector('.download-code').addEventListener('click', () => { |
| const code = this.shadowRoot.querySelector('.download-code').getAttribute('data-code'); |
| const element = document.createElement('a'); |
| element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(code)); |
| element.setAttribute('download', 'code.html'); |
| element.style.display = 'none'; |
| document.body.appendChild(element); |
| element.click(); |
| document.body.removeChild(element); |
| }); |
|
|
| |
| this.shadowRoot.getElementById('save-project').addEventListener('click', () => { |
| document.dispatchEvent(new CustomEvent('save-project', { |
| detail: { |
| code: this.code, |
| description: this.description |
| } |
| })); |
| alert('Projet sauvegardé avec succès !'); |
| }); |
|
|
| |
| this.shadowRoot.getElementById('new-chat').addEventListener('click', () => { |
| document.dispatchEvent(new CustomEvent('navigate', { detail: 'chat' })); |
| }); |
| } else { |
| |
| this.shadowRoot.getElementById('go-to-chat').addEventListener('click', () => { |
| document.dispatchEvent(new CustomEvent('navigate', { detail: 'chat' })); |
| }); |
| } |
| } |
| } |
|
|
| |
| function escapeHtml(unsafe) { |
| return unsafe |
| .replace(/&/g, "&") |
| .replace(/</g, "<") |
| .replace(/>/g, ">") |
| .replace(/"/g, """) |
| .replace(/'/g, "'"); |
| } |
|
|
| customElements.define('code-component', CodeComponent); |