🐘
artifacts.php
Back
📝 Php ⚡ Executable Ctrl+S: Save • Ctrl+R: Run • Ctrl+F: Find
<?php // artifacts.php - Artifacts Management // Initialize artifacts session if (!isset($_SESSION['artifacts'])) $_SESSION['artifacts'] = []; // Handle artifact form submission if (isset($_POST['action']) && $_POST['action'] === 'save_artifacts') { $_SESSION['artifacts'] = []; // Process each artifact if (isset($_POST['artifacts']) && is_array($_POST['artifacts'])) { foreach ($_POST['artifacts'] as $artifact) { if (!empty(trim($artifact['title'])) && !empty(trim($artifact['content']))) { $_SESSION['artifacts'][] = [ 'title' => trim($artifact['title']), 'type' => $artifact['type'] ?? 'code', 'language' => $artifact['language'] ?? 'javascript', 'content' => trim($artifact['content']) ]; } } } header('Location: ' . $_SERVER['PHP_SELF']); exit; } // Handle artifact deletion if (isset($_POST['action']) && $_POST['action'] === 'clear_artifacts') { $_SESSION['artifacts'] = []; header('Location: ' . $_SERVER['PHP_SELF']); exit; } $artifacts = $_SESSION['artifacts']; ?> <style> /* Artifacts-specific styles */ .artifacts-tabs { display: flex; gap: 4px; margin-bottom: 16px; border-bottom: 1px solid var(--br); overflow-x: auto; } .artifact-tab { background: none; border: none; color: var(--muted); padding: 8px 12px; cursor: pointer; border-bottom: 2px solid transparent; white-space: nowrap; font-size: 0.85rem; transition: all 0.2s ease; } .artifact-tab.active { color: var(--accent); border-bottom-color: var(--accent); } .artifact-tab:hover { color: var(--ink); } .artifact-panel { display: none; height: 60vh; overflow-y: auto; } .artifact-panel.active { display: block; } .artifact-content-editor { display: grid; grid-template-rows: auto 1fr; height: 100%; gap: 12px; } .artifact-meta { display: grid; grid-template-columns: 1fr auto auto auto; gap: 8px; align-items: center; } .artifact-content { width: 100%; min-height: calc(60vh - 80px); font-family: 'Courier New', monospace; font-size: 0.9rem; line-height: 1.4; resize: none; border: 1px solid var(--br); border-radius: 8px; padding: 12px; background: var(--code); } .artifact-remove { background: #dc2626; color: white; border: none; border-radius: 4px; padding: 4px 8px; cursor: pointer; font-size: 0.75rem; min-width: 60px; } .artifact-remove:hover { background: #b91c1c; } .add-artifact { background: var(--accent); color: white; border: none; border-radius: 8px; padding: 10px 16px; cursor: pointer; margin-bottom: 16px; font-size: 0.9rem; } .add-artifact:hover { filter: brightness(1.1); } .artifacts-actions { display: flex; gap: 12px; margin-top: 16px; } .clear-artifacts { background: #dc2626; color: white; } .clear-artifacts:hover { background: #b91c1c; } .artifact-count { display: inline-flex; align-items: center; gap: 6px; font-size: 0.8rem; color: var(--accent); margin-left: 8px; } .artifact-count::before { content: '📄'; font-size: 12px; } @media (max-width: 640px) { .artifact-meta { grid-template-columns: 1fr; gap: 8px; } .artifact-meta > * { width: 100%; } } </style> <div class="overlay" id="artifacts"> <div class="dialog"> <div class="dialog-hd"> <strong>Initial Artifacts</strong> <button class="close-x" onclick="hideArtifacts()">&times;</button> </div> <div class="dialog-bd"> <p class="small-note">Add code, HTML, or other content that will be available at the start of conversations. These artifacts will be included in the initial context.</p> <form method="post" id="artifactsForm"> <input type="hidden" name="action" value="save_artifacts"> <button type="button" class="add-artifact" onclick="addArtifact()">+ Add Artifact</button> <div class="artifacts-tabs" id="artifactTabs"> <?php if (empty($artifacts)): ?> <button type="button" class="artifact-tab active" onclick="switchTab(0)">New Artifact</button> <?php else: ?> <?php foreach ($artifacts as $index => $artifact): ?> <button type="button" class="artifact-tab <?= $index === 0 ? 'active' : '' ?>" onclick="switchTab(<?= $index ?>)"> <?= h($artifact['title'] ?: 'Artifact ' . ($index + 1)) ?> </button> <?php endforeach; ?> <?php endif; ?> </div> <div id="artifacts-container"> <?php if (empty($artifacts)): ?> <!-- Default empty artifact --> <div class="artifact-panel active" id="artifact-0"> <div class="artifact-content-editor"> <div class="artifact-meta"> <input type="text" name="artifacts[0][title]" placeholder="Artifact title" value="" onchange="updateTabTitle(0, this.value)"> <select name="artifacts[0][type]"> <option value="code">Code</option> <option value="html">HTML</option> <option value="markdown">Markdown</option> <option value="text">Text</option> </select> <select name="artifacts[0][language]"> <option value="javascript">JavaScript</option> <option value="python">Python</option> <option value="php">PHP</option> <option value="html">HTML</option> <option value="css">CSS</option> <option value="sql">SQL</option> <option value="json">JSON</option> <option value="xml">XML</option> <option value="bash">Bash</option> <option value="other">Other</option> </select> <button type="button" class="artifact-remove" onclick="removeArtifact(0)">Remove</button> </div> <textarea name="artifacts[0][content]" class="artifact-content" placeholder="Enter your code or content here..."></textarea> </div> </div> <?php else: ?> <?php foreach ($artifacts as $index => $artifact): ?> <div class="artifact-panel <?= $index === 0 ? 'active' : '' ?>" id="artifact-<?= $index ?>"> <div class="artifact-content-editor"> <div class="artifact-meta"> <input type="text" name="artifacts[<?= $index ?>][title]" placeholder="Artifact title" value="<?= h($artifact['title']) ?>" onchange="updateTabTitle(<?= $index ?>, this.value)"> <select name="artifacts[<?= $index ?>][type]"> <option value="code" <?= $artifact['type'] === 'code' ? 'selected' : '' ?>>Code</option> <option value="html" <?= $artifact['type'] === 'html' ? 'selected' : '' ?>>HTML</option> <option value="markdown" <?= $artifact['type'] === 'markdown' ? 'selected' : '' ?>>Markdown</option> <option value="text" <?= $artifact['type'] === 'text' ? 'selected' : '' ?>>Text</option> </select> <select name="artifacts[<?= $index ?>][language]"> <option value="javascript" <?= $artifact['language'] === 'javascript' ? 'selected' : '' ?>>JavaScript</option> <option value="python" <?= $artifact['language'] === 'python' ? 'selected' : '' ?>>Python</option> <option value="php" <?= $artifact['language'] === 'php' ? 'selected' : '' ?>>PHP</option> <option value="html" <?= $artifact['language'] === 'html' ? 'selected' : '' ?>>HTML</option> <option value="css" <?= $artifact['language'] === 'css' ? 'selected' : '' ?>>CSS</option> <option value="sql" <?= $artifact['language'] === 'sql' ? 'selected' : '' ?>>SQL</option> <option value="json" <?= $artifact['language'] === 'json' ? 'selected' : '' ?>>JSON</option> <option value="xml" <?= $artifact['language'] === 'xml' ? 'selected' : '' ?>>XML</option> <option value="bash" <?= $artifact['language'] === 'bash' ? 'selected' : '' ?>>Bash</option> <option value="other" <?= $artifact['language'] === 'other' ? 'selected' : '' ?>>Other</option> </select> <button type="button" class="artifact-remove" onclick="removeArtifact(<?= $index ?>)">Remove</button> </div> <textarea name="artifacts[<?= $index ?>][content]" class="artifact-content" placeholder="Enter your code or content here..."><?= h($artifact['content']) ?></textarea> </div> </div> <?php endforeach; ?> <?php endif; ?> </div> <div class="artifacts-actions"> <button type="submit" class="btn">Save Artifacts</button> <?php if (!empty($artifacts)): ?> <button type="button" class="btn clear-artifacts" onclick="clearArtifacts()">Clear All</button> <?php endif; ?> </div> </form> </div> <div class="dialog-ft"> <button class="btn" onclick="hideArtifacts()">Close</button> </div> </div> </div> <script> // Artifacts management function hideArtifacts() { document.getElementById('artifacts').style.display = 'none'; } // Close modal when clicking outside document.getElementById('artifacts').addEventListener('click', function(e) { if (e.target === this) hideArtifacts(); }); let artifactCounter = <?= count($artifacts) ?: 1 ?>; let currentTab = 0; function switchTab(index) { // Hide all panels document.querySelectorAll('.artifact-panel').forEach(panel => { panel.classList.remove('active'); }); // Hide all tabs document.querySelectorAll('.artifact-tab').forEach(tab => { tab.classList.remove('active'); }); // Show selected panel and tab const panel = document.getElementById(`artifact-${index}`); const tab = document.querySelectorAll('.artifact-tab')[index]; if (panel) panel.classList.add('active'); if (tab) tab.classList.add('active'); currentTab = index; } function updateTabTitle(index, title) { const tab = document.querySelectorAll('.artifact-tab')[index]; if (tab) { tab.textContent = title || `Artifact ${index + 1}`; } } function addArtifact() { const container = document.getElementById('artifacts-container'); const tabsContainer = document.getElementById('artifactTabs'); const newIndex = artifactCounter++; // Add new tab const newTab = document.createElement('button'); newTab.type = 'button'; newTab.className = 'artifact-tab'; newTab.textContent = 'New Artifact'; newTab.onclick = () => switchTab(newIndex); tabsContainer.appendChild(newTab); // Add new panel const artifactHtml = ` <div class="artifact-panel" id="artifact-${newIndex}"> <div class="artifact-content-editor"> <div class="artifact-meta"> <input type="text" name="artifacts[${newIndex}][title]" placeholder="Artifact title" value="" onchange="updateTabTitle(${newIndex}, this.value)"> <select name="artifacts[${newIndex}][type]"> <option value="code">Code</option> <option value="html">HTML</option> <option value="markdown">Markdown</option> <option value="text">Text</option> </select> <select name="artifacts[${newIndex}][language]"> <option value="javascript">JavaScript</option> <option value="python">Python</option> <option value="php">PHP</option> <option value="html">HTML</option> <option value="css">CSS</option> <option value="sql">SQL</option> <option value="json">JSON</option> <option value="xml">XML</option> <option value="bash">Bash</option> <option value="other">Other</option> </select> <button type="button" class="artifact-remove" onclick="removeArtifact(${newIndex})">Remove</button> </div> <textarea name="artifacts[${newIndex}][content]" class="artifact-content" placeholder="Enter your code or content here..."></textarea> </div> </div> `; container.insertAdjacentHTML('beforeend', artifactHtml); // Switch to the new tab switchTab(newIndex); } function removeArtifact(index) { const panel = document.getElementById(`artifact-${index}`); const tabs = document.querySelectorAll('.artifact-tab'); const tab = tabs[index]; if (panel) panel.remove(); if (tab) tab.remove(); // Switch to first available tab const remainingTabs = document.querySelectorAll('.artifact-tab'); if (remainingTabs.length > 0) { // Find the index of the first remaining tab const firstPanel = document.querySelector('.artifact-panel'); if (firstPanel) { const firstIndex = parseInt(firstPanel.id.split('-')[1]); switchTab(firstIndex); } } } function clearArtifacts() { if (confirm('Clear all artifacts? This will remove all saved artifacts.')) { const form = document.createElement('form'); form.method = 'POST'; form.innerHTML = '<input type="hidden" name="action" value="clear_artifacts">'; document.body.appendChild(form); form.submit(); } } </script>