|
|
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); |