anycoder-85968a53 / index.html
XXXMARK's picture
Upload folder using huggingface_hub
fdac33d verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI Code Creator - Qwen & DeepSeek Edition</title>
<!-- Icons -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<!-- JSZip for Exporting -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
<!-- FileSaver for Saving -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script>
<style>
:root {
--bg-dark: #0f0f0f;
--bg-panel: #1a1a1a;
--bg-panel-hover: #252525;
--primary: #FFD700; /* Gold/Yellow */
--primary-dim: #b39700;
--text-main: #ffffff;
--text-muted: #a0a0a0;
--border: #333;
--code-bg: #111;
--accent-blue: #3b82f6;
--success: #10b981;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
scrollbar-width: thin;
scrollbar-color: var(--primary) var(--bg-dark);
}
body {
font-family: 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
background-color: var(--bg-dark);
color: var(--text-main);
height: 100vh;
display: flex;
flex-direction: column;
overflow: hidden;
}
/* --- Header --- */
header {
height: 60px;
background-color: var(--bg-panel);
border-bottom: 1px solid var(--border);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20px;
z-index: 10;
}
.logo {
font-size: 1.2rem;
font-weight: bold;
color: var(--primary);
display: flex;
align-items: center;
gap: 10px;
text-decoration: none;
}
.logo span { color: white; }
.header-controls {
display: flex;
gap: 15px;
}
button {
background-color: var(--bg-panel);
border: 1px solid var(--border);
color: var(--text-main);
padding: 8px 16px;
border-radius: 6px;
cursor: pointer;
transition: all 0.2s;
font-size: 0.9rem;
display: flex;
align-items: center;
gap: 8px;
}
button:hover {
background-color: var(--bg-panel-hover);
border-color: var(--primary);
}
button.primary {
background-color: var(--primary);
color: #000;
font-weight: bold;
border: none;
}
button.primary:hover {
background-color: var(--primary-dim);
}
/* --- Main Layout --- */
.app-container {
display: flex;
flex: 1;
height: calc(100vh - 60px);
}
/* --- Sidebar (Files, History) --- */
.sidebar {
width: 250px;
background-color: var(--bg-panel);
border-right: 1px solid var(--border);
display: flex;
flex-direction: column;
}
.sidebar-header {
padding: 15px;
border-bottom: 1px solid var(--border);
font-weight: bold;
color: var(--primary);
}
.file-list, .history-list {
flex: 1;
overflow-y: auto;
padding: 10px;
}
.file-item {
padding: 10px;
margin-bottom: 5px;
border-radius: 4px;
cursor: pointer;
display: flex;
align-items: center;
gap: 10px;
font-size: 0.9rem;
}
.file-item:hover, .file-item.active {
background-color: var(--bg-panel-hover);
color: var(--primary);
}
/* --- Editor Area --- */
.editor-section {
flex: 1;
display: flex;
flex-direction: column;
border-right: 1px solid var(--border);
}
.tabs {
display: flex;
background-color: var(--bg-dark);
border-bottom: 1px solid var(--border);
}
.tab {
padding: 12px 20px;
cursor: pointer;
border-right: 1px solid var(--border);
color: var(--text-muted);
font-size: 0.9rem;
}
.tab.active {
background-color: var(--bg-panel);
color: var(--primary);
border-top: 2px solid var(--primary);
}
.code-area {
flex: 1;
background-color: var(--code-bg);
display: flex;
flex-direction: column;
}
textarea#codeEditor {
flex: 1;
background-color: transparent;
color: #e0e0e0;
border: none;
resize: none;
padding: 20px;
font-family: 'Consolas', 'Monaco', monospace;
font-size: 14px;
line-height: 1.5;
outline: none;
}
/* --- AI Panel --- */
.ai-panel {
height: 40%;
border-top: 1px solid var(--border);
background-color: var(--bg-panel);
display: flex;
flex-direction: column;
}
.ai-input-container {
padding: 15px;
border-top: 1px solid var(--border);
background-color: var(--bg-dark);
}
.enhance-tools {
display: flex;
gap: 10px;
margin-bottom: 10px;
}
.enhance-btn {
font-size: 0.8rem;
padding: 4px 10px;
border-radius: 20px;
background: var(--bg-panel);
border: 1px solid var(--primary);
color: var(--primary);
}
.input-wrapper {
display: flex;
gap: 10px;
position: relative;
}
#aiInput {
flex: 1;
background-color: var(--bg-panel);
border: 1px solid var(--border);
color: white;
padding: 12px;
border-radius: 8px;
outline: none;
}
#aiInput:focus {
border-color: var(--primary);
}
.ai-output {
flex: 1;
padding: 15px;
overflow-y: auto;
font-family: 'Consolas', monospace;
font-size: 0.9rem;
color: var(--text-muted);
}
.ai-message {
margin-bottom: 15px;
padding: 10px;
border-radius: 6px;
background-color: rgba(255, 255, 255, 0.05);
border-left: 3px solid var(--primary);
}
/* --- Preview Pane --- */
.preview-section {
width: 40%;
display: flex;
flex-direction: column;
background-color: white;
}
.preview-header {
background-color: var(--bg-panel);
padding: 10px 15px;
border-bottom: 1px solid var(--border);
display: flex;
justify-content: space-between;
align-items: center;
}
iframe {
flex: 1;
border: none;
width: 100%;
height: 100%;
}
/* --- Modals --- */
.modal {
display: none;
position: fixed;
top: 0; left: 0; width: 100%; height: 100%;
background: rgba(0,0,0,0.8);
z-index: 100;
justify-content: center;
align-items: center;
}
.modal-content {
background: var(--bg-panel);
padding: 25px;
border-radius: 10px;
border: 1px solid var(--primary);
width: 500px;
max-width: 90%;
}
.modal h2 {
color: var(--primary);
margin-bottom: 20px;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
color: var(--text-muted);
}
.form-group input, .form-group select {
width: 100%;
padding: 10px;
background: var(--bg-dark);
border: 1px solid var(--border);
color: white;
border-radius: 4px;
}
.color-picker-row {
display: flex;
gap: 15px;
align-items: center;
margin-bottom: 10px;
}
input[type="color"] {
width: 40px;
height: 40px;
border: none;
padding: 0;
background: none;
}
/* Loader */
.loader {
border: 3px solid rgba(255,255,255,0.1);
border-top: 3px solid var(--primary);
border-radius: 50%;
width: 20px;
height: 20px;
animation: spin 1s linear infinite;
display: none;
}
@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
</style>
</head>
<body>
<!-- Header -->
<header>
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="logo">
<i class="fas fa-microchip"></i> <span>AI Code Creator</span> <small style="font-size: 0.6em; color: #666;">Built with Anycoder</small>
</a>
<div class="header-controls">
<button onclick="openSettings()"><i class="fas fa-robot"></i> AI Config</button>
<button onclick="openThemeTool()"><i class="fas fa-palette"></i> Theme</button>
<button onclick="exportProject()"><i class="fas fa-download"></i> Export ZIP</button>
<button class="primary" onclick="runAI()"><i class="fas fa-magic"></i> Generate</button>
</div>
</header>
<!-- Main App -->
<div class="app-container">
<!-- Left Sidebar -->
<aside class="sidebar">
<div class="sidebar-header">
<i class="fas fa-project-diagram"></i> Project Files
</div>
<div class="file-list" id="fileList">
<!-- Generated by JS -->
</div>
<div class="sidebar-header" style="border-top: 1px solid var(--border); margin-top: auto;">
<i class="fas fa-history"></i> History
</div>
<div class="history-list" id="historyList">
<!-- Generated by JS -->
</div>
</aside>
<!-- Center Editor -->
<section class="editor-section">
<div class="tabs">
<div class="tab active" onclick="switchTab('index.html')">index.html</div>
<div class="tab" onclick="switchTab('style.css')">style.css</div>
<div class="tab" onclick="switchTab('script.js')">script.js</div>
<div class="tab" style="margin-left: auto; border-left: 1px solid var(--border);" onclick="saveToHistory()">
<i class="fas fa-save"></i> Save Snapshot
</div>
</div>
<div class="code-area">
<textarea id="codeEditor" spellcheck="false" oninput="updateFileContent()"></textarea>
</div>
<!-- AI Chat / Enhancer -->
<div class="ai-panel">
<div style="padding: 10px; background: var(--bg-dark); border-bottom: 1px solid var(--border); display: flex; justify-content: space-between;">
<span style="color: var(--primary); font-weight: bold;">AI Assistant</span>
<span id="modelStatus" style="font-size: 0.8rem; color: var(--text-muted);">Model: Mock (Ready)</span>
</div>
<div class="ai-output" id="aiOutput">
<div class="ai-message">System: Ready. Describe your web app, or use the enhancer tools below.</div>
</div>
<div class="ai-input-container">
<div class="enhance-tools">
<button class="enhance-btn" onclick="enhancePrompt('Fix Code', 'Fix syntax errors in the following code:')">Fix Code</button>
<button class="enhance-btn" onclick="enhancePrompt('Optimize', 'Optimize the CSS for better performance:')">Optimize</button>
<button class="enhance-btn" onclick="enhancePrompt('Add Feature', 'Add a responsive navigation bar:')">Add Feature</button>
</div>
<div class="input-wrapper">
<input type="text" id="aiInput" placeholder="Ask AI to generate or edit code..." autocomplete="off">
<div class="loader" id="aiLoader"></div>
<button class="primary" style="padding: 8px 15px;" onclick="runAI()"><i class="fas fa-paper-plane"></i></button>
</div>
</div>
</div>
</section>
<!-- Right Preview -->
<section class="preview-section">
<div class="preview-header">
<span style="color: #333; font-weight: bold;">Live Preview</span>
<div style="display: flex; gap: 5px;">
<i class="fas fa-mobile-alt" style="color: #666; cursor: pointer;" onclick="setDevice('mobile')"></i>
<i class="fas fa-desktop" style="color: #000; cursor: pointer;" onclick="setDevice('desktop')"></i>
</div>
</div>
<iframe id="previewFrame" title="Live Preview"></iframe>
</section>
</div>
<!-- Settings Modal -->
<div id="settingsModal" class="modal">
<div class="modal-content">
<h2>AI Configuration</h2>
<div class="form-group">
<label>Select Model Provider</label>
<select id="aiProvider">
<option value="mock">Mock AI (Demo Mode)</option>
<option value="openai">OpenAI Compatible (Qwen/DeepSeek)</option>
<option value="huggingface">HuggingFace Inference</option>
</select>
</div>
<div class="form-group">
<label>API Endpoint / URL</label>
<input type="text" id="apiEndpoint" placeholder="https://api.openai.com/v1/...">
</div>
<div class="form-group">
<label>API Key</label>
<input type="password" id="apiKey" placeholder="sk-...">
</div>
<div style="display: flex; justify-content: flex-end; gap: 10px;">
<button onclick="closeModal('settingsModal')">Cancel</button>
<button class="primary" onclick="saveSettings()">Save Config</button>
</div>
</div>
</div>
<!-- Theme Modal -->
<div id="themeModal" class="modal">
<div class="modal-content">
<h2>Theme Customizer</h2>
<div class="color-picker-row">
<label>Primary (Yellow):</label>
<input type="color" id="themePrimary" value="#FFD700">
</div>
<div class="color-picker-row">
<label>Background:</label>
<input type="color" id="themeBg" value="#0f0f0f">
</div>
<div class="color-picker-row">
<label>Text Color:</label>
<input type="color" id="themeText" value="#ffffff">
</div>
<div style="display: flex; justify-content: flex-end; gap: 10px;">
<button onclick="resetTheme()">Reset Default</button>
<button class="primary" onclick="applyTheme()">Apply Theme</button>
</div>
</div>
</div>
<script>
// --- State Management ---
const state = {
files: {
'index.html': '<!DOCTYPE html>\n<html>\n<head>\n <title>My App</title>\n <link rel="stylesheet" href="style.css">\n</head>\n<body>\n <div class="container">\n <h1>Hello AI Creator!</h1>\n <p>Start coding or ask the AI to build something.</p>\n <button id="btn">Click Me</button>\n </div>\n <script src="script.js"><\/script>\n</body>\n</html>',
'style.css': 'body {\n background: #111;\n color: #fff;\n font-family: sans-serif;\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100vh;\n margin: 0;\n}\n\n.container {\n text-align: center;\n border: 2px solid #FFD700;\n padding: 40px;\n border-radius: 10px;\n}\n\nbutton {\n background: #FFD700;\n color: #000;\n border: none;\n padding: 10px 20px;\n font-size: 1.2rem;\n cursor: pointer;\n margin-top: 20px;\n border-radius: 5px;\n}',
'script.js': 'document.getElementById("btn").addEventListener("click", () => {\n alert("Button Clicked!");\n});'
},
activeFile: 'index.html',
history: [],
config: {
provider: 'mock',
endpoint: '',
key: ''
}
};
// --- Initialization ---
document.addEventListener('DOMContentLoaded', () => {
renderFileList();
loadEditor();
renderPreview();
loadHistory();
// Enter key for AI Input
document.getElementById('aiInput').addEventListener('keypress', function (e) {
if (e.key === 'Enter') {
runAI();
}
});
});
// --- Core Editor Functions ---
function switchTab(filename) {
state.activeFile = filename;
// Update UI
document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
// Find the tab element by text content (simple way) or index logic
// In a real app, assign IDs to tabs. Here we just reload editor content.
// Highlight active tab logic (simplified)
const tabs = document.querySelectorAll('.tab');
if(filename === 'index.html') tabs[0].classList.add('active');
if(filename === 'style.css') tabs[1].classList.add('active');
if(filename === 'script.js') tabs[2].classList.add('active');
loadEditor();
}
function loadEditor() {
const editor = document.getElementById('codeEditor');
editor.value = state.files[state.activeFile];
}
function updateFileContent() {
state.files[state.activeFile] = document.getElementById('codeEditor').value;
renderPreview();
}
function renderFileList() {
const list = document.getElementById('fileList');
list.innerHTML = '';
Object.keys(state.files).forEach(filename => {
const div = document.createElement('div');
div.className = `file-item ${filename === state.activeFile ? 'active' : ''}`;
div.innerHTML = `<i class="fas ${getFileIcon(filename)}"></i> ${filename}`;
div.onclick = () => switchTab(filename);
list.appendChild(div);
});
}
function getFileIcon(filename) {
if(filename.endsWith('.html')) return 'fa-html5 text-orange-500';
if(filename.endsWith('.css')) return 'fa-css3-alt text-blue-500';
if(filename.endsWith('.js')) return 'fa-js text-yellow-500';
return 'fa-file-code';
}
// --- Preview System ---
function renderPreview() {
const iframe = document.getElementById('previewFrame');
// Inject CSS into HTML for preview
const css = state.files['style.css'] || '';
const html = state.files['index.html'] || '';
// Basic injection logic to ensure style.css applies even in blob/data URI scenarios if needed
// For iframe srcdoc, we can just put them together
const combinedHTML = `
<!DOCTYPE html>
<html>
<head>
<style>${css}</style>
</head>
<body>
${html}
<script>${state.files['script.js'] || ''}<\/script>
</body>
</html>
`;
iframe.srcdoc = combinedHTML;
}
function setDevice(type) {
const iframe = document.getElementById('previewFrame');
if(type === 'mobile') {
iframe.style.width = '375px';
iframe.style.margin = '0 auto';
iframe.style.border = '1px solid #ccc';
} else {
iframe.style.width = '100%';
iframe.style.border = 'none';
iframe.style.margin = '0';
}
}
// --- AI Logic ---
function enhancePrompt(action, prefix) {
const input = document.getElementById('aiInput');
input.value = `${prefix} \n\nCurrent File (${state.activeFile}): \n${state.files[state.activeFile].substring(0, 100)}...`;
const output = document.getElementById('aiOutput');
output.innerHTML += `<div class="ai-message"><strong>System:</strong> Prompt enhanced for "${action}". Review input and press Generate.</div>`;
output.scrollTop = output.scrollHeight;
}
async function runAI() {
const input = document.getElementById('aiInput').value;
if(!input.trim()) return;
const loader = document.getElementById('aiLoader');
const output = document.getElementById('aiOutput');
loader.style.display = 'block';
output.innerHTML += `<div class="ai-message"><strong>User:</strong> ${input}</div>`;
try {
let aiResponse = "";
if (state.config.provider === 'mock') {
// Mock AI for Demo purposes
await new Promise(r => setTimeout(r, 1500)); // Fake delay
aiResponse = generateMockResponse(input);
} else {
// Real API Call (Conceptual Implementation)
aiResponse = await callRealAPI(input);
}
output.innerHTML += `<div class="ai-message"><strong>AI:</strong> ${aiResponse}</div>`;
processAIResult(aiResponse);
} catch (error) {
output.innerHTML += `<div class="ai-message" style="color:red"><strong>Error:</strong> ${error.message}</div>`;
} finally {
loader.style.display = 'none';
output.scrollTop = output.scrollHeight;
}
}
function generateMockResponse(prompt) {
// Heuristic responses for demo
if (prompt.toLowerCase().includes('html')) {
return "I've updated the HTML structure with a modern layout.";
}
if (prompt.toLowerCase().includes('css') || prompt.toLowerCase().includes('style')) {
return "I've refined the CSS. Added a gradient background and hover effects.";
}
if (prompt.toLowerCase().includes('fix') || prompt.toLowerCase().includes('error')) {
return "I detected a syntax error in the script tag. Fixed.";
}
return "Generated code structure based on your request. I've updated the 'index.html' file.";
}
async function callRealAPI(prompt) {
// Placeholder for fetch to Qwen/DeepSeek/HuggingFace
// In a real app, you'd construct the JSON body here based on state.config
const response = await fetch(state.config.endpoint || 'https://api.example.com/generate', {
method: 'POST',
headers: {
'Authorization': `Bearer ${state.config.key}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ prompt: prompt })
});
if(!response.ok) throw new Error('API Request Failed');
const data = await response.json();
return data.choices[0].message.content;
}
function processAIResult(responseText) {
// This is a very basic parser. In production, you'd want structured JSON from the AI.
// For this demo, we will detect keywords or just append to index.html for simple commands.
if (responseText.includes('```html')) {
const htmlMatch = responseText.match(/```html([\s\S]*?)```/);
if(htmlMatch) {
state.files['index.html'] = htmlMatch[1].trim();
switchTab('index.html');
}
} else if (responseText.includes('```css')) {
const cssMatch = responseText.match(/```css([\s\S]*?)```/);
if(cssMatch) {
state.files['style.css'] = cssMatch[1].trim();
switchTab('style.css');
}
} else {
// Default: append to current file for memory/chat context
const currentContent = state.files[state.activeFile];
state.files[state.activeFile] = currentContent + "\n<!-- AI Generated -->\n" + responseText;
}
loadEditor();
renderFileList();
renderPreview();
document.getElementById('aiInput').value = '';
}
// --- History & Saving ---
function saveToHistory() {
const snapshot = {
timestamp: new Date().toLocaleString(),
files: JSON.parse(JSON.stringify(state.files)),
prompt: document.getElementById('aiInput').value || "Manual Save"
};
state.history.unshift(snapshot);
if(state.history.length > 10) state.history.pop();
localStorage.setItem('ai_code_history', JSON.stringify(state.history));
renderHistory();
alert("Snapshot saved to History!");
}
function loadHistory() {
const stored = localStorage.getItem('ai_code_history');
if(stored) {
state.history = JSON.parse(stored);
renderHistory();
}
}
function renderHistory() {
const list = document.getElementById('historyList');
list.innerHTML = '';
state.history.forEach((item, index) => {
const div = document.createElement('div');
div.className = 'file-item';
div.innerHTML = `<i class="fas fa-history"></i> ${item.timestamp}`;
div.title = item.prompt;
div.onclick = () => restoreHistory(index);
list.appendChild(div);
});
}
function restoreHistory(index) {
if(confirm("Restore this snapshot? Current unsaved changes will be lost.")) {
state.files = JSON.parse(JSON.stringify(state.history[index].files));
loadEditor();
renderFileList();
renderPreview();
}
}
function exportProject() {
const zip = new JSZip();
for (const [filename, content] of Object.entries(state.files)) {
zip.file(filename, content);
}
zip.generateAsync({type:"blob"})
.then(function(content) {
saveAs(content, "ai-project.zip");
});
}
// --- Theme Tool ---
function openThemeTool() {
document.getElementById('themeModal').style.display = 'flex';
}
function applyTheme() {
const primary = document.getElementById('themePrimary').value;
const bg = document.getElementById('themeBg').value;
const text = document.getElementById('themeText').value;
const r = document.querySelector(':root');
r.style.setProperty('--primary', primary);
r.style.setProperty('--bg-dark', bg);
r.style.setProperty('--text-main', text);
closeModal('themeModal');
}
function resetTheme() {
document.getElementById('themePrimary').value = '#FFD700';
document.getElementById('themeBg').value = '#0f0f0f';
document.getElementById('themeText').value = '#ffffff';
applyTheme();
}
// --- Settings ---
function openSettings() {
document.getElementById('settingsModal').style.display = 'flex';
}
function saveSettings() {
state.config.provider = document.getElementById('aiProvider').value;
state.config.endpoint = document.getElementById('apiEndpoint').value;
state.config.key = document.getElementById('apiKey').value;
const status = document.getElementById('modelStatus');
status.innerText = `Model: ${state.config.provider.toUpperCase()} (Active)`;
closeModal('settingsModal');
}
function closeModal(id) {
document.getElementById(id).style.display = 'none';
}
// Close modals on outside click
window.onclick = function(event) {
if (event.target.classList.contains('modal')) {
event.target.style.display = "none";
}
}
</script>
</body>
</html>