Lachlan McMurtrie
The app is a collaborative component builder. it begin by starting a project, entering in a description. the next page will be an ai assisted project scope, where the user will type the component type, which will be a list of core components (all that are core across ui domains). The ai will then ask for a framework of native react or react for web. the behavioral hooks, interactions and utilites that align with the component will then be showed. for web, these must be all react-aria, for native, these will be react-native. assume react-shared types for cross platform as common, as well as react-stately for states which are also cross platform. provide the user with a the data attributes as per react-aria or native equivilant documentation, ask them how they want to recieve their code files - combined as typed primitives, or separated through the use of an adapter that exports the behaviors etc to the primitive.
499a14d verified | <html lang="en" class="dark"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>ComponentForge - AI Scope Generation</title> | |
| <link rel="icon" type="image/x-icon" href="/static/favicon.ico"> | |
| <link rel="stylesheet" href="style.css"> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> | |
| <script src="https://unpkg.com/feather-icons"></script> | |
| </head> | |
| <body class="bg-gray-900 text-white min-h-screen"> | |
| <custom-header></custom-header> | |
| <main class="container mx-auto px-4 py-8"> | |
| <div class="max-w-6xl mx-auto"> | |
| <!-- Progress Bar --> | |
| <div class="mb-8"> | |
| <div class="flex items-center justify-between mb-2"> | |
| <span class="text-sm text-gray-400">Step 2 of 3</span> | |
| <span class="text-sm text-purple-400">AI Scope Generation</span> | |
| </div> | |
| <div class="w-full bg-gray-700 rounded-full h-2"> | |
| <div class="bg-gradient-to-r from-purple-500 to-pink-500 h-2 rounded-full w-2/3"></div> | |
| </div> | |
| <!-- Project Info --> | |
| <div class="bg-gray-800 rounded-xl p-6 mb-6 border border-gray-700"> | |
| <div class="flex items-center justify-between"> | |
| <div> | |
| <h2 class="text-xl font-bold" id="projectTitle">Project: Loading...</h2> | |
| <p class="text-gray-400 mt-1" id="projectDesc"></p> | |
| </div> | |
| <button onclick="window.location.href = 'index.html'" class="text-gray-400 hover:text-white transition-colors"> | |
| <i data-feather="edit" class="w-5 h-5"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <!-- AI Scope Generator --> | |
| <div class="grid lg:grid-cols-2 gap-8"> | |
| <!-- Left Column - Input --> | |
| <div class="space-y-6"> | |
| <!-- Component Type Selection --> | |
| <div class="bg-gray-800 rounded-xl p-6 border border-gray-700"> | |
| <div class="flex items-center mb-4"> | |
| <i data-feather="grid" class="w-6 h-6 text-purple-500 mr-3"></i> | |
| <h3 class="text-lg font-semibold">Component Type</h3> | |
| </div> | |
| <div class="grid grid-cols-2 gap-3"> | |
| <button class="component-type-btn bg-gray-700 hover:bg-purple-600 p-4 rounded-lg border border-gray-600 hover:border-purple-500 transition-all duration-200" data-type="button"> | |
| <i data-feather="mouse-pointer" class="w-6 h-6 mb-2 mx-auto"></i> | |
| <span class="text-sm font-medium">Button</span> | |
| </button> | |
| <button class="component-type-btn bg-gray-700 hover:bg-pink-600 p-4 rounded-lg border border-gray-600 hover:border-pink-500 transition-all duration-200" data-type="input"> | |
| <i data-feather="edit" class="w-6 h-6 mb-2 mx-auto"></i> | |
| <span class="text-sm font-medium">Input</span> | |
| </button> | |
| <button class="component-type-btn bg-gray-700 hover:bg-blue-600 p-4 rounded-lg border border-gray-600 hover:border-blue-500 transition-all duration-200" data-type="select"> | |
| <i data-feather="chevron-down" class="w-6 h-6 mb-2 mx-auto"></i> | |
| <span class="text-sm font-medium">Select</span> | |
| </button> | |
| <button class="component-type-btn bg-gray-700 hover:bg-green-600 p-4 rounded-lg border border-gray-600 hover:border-green-500 transition-all duration-200" data-type="modal"> | |
| <i data-feather="square" class="w-6 h-6 mb-2 mx-auto"></i> | |
| <span class="text-sm font-medium">Modal</span> | |
| </button> | |
| <button class="component-type-btn bg-gray-700 hover:bg-yellow-600 p-4 rounded-lg border border-gray-600 hover:border-yellow-500 transition-all duration-200" data-type="menu"> | |
| <i data-feather="menu" class="w-6 h-6 mb-2 mx-auto"></i> | |
| <span class="text-sm font-medium">Menu</span> | |
| </button> | |
| <button class="component-type-btn bg-gray-700 hover:bg-indigo-600 p-4 rounded-lg border border-gray-600 hover:border-indigo-500 transition-all duration-200" data-type="tabs"> | |
| <i data-feather="folder" class="w-6 h-6 mb-2 mx-auto"></i> | |
| <span class="text-sm font-medium">Tabs</span> | |
| </button> | |
| </div> | |
| <!-- Additional Requirements --> | |
| <div class="bg-gray-800 rounded-xl p-6 border border-gray-700"> | |
| <div class="flex items-center mb-4"> | |
| <i data-feather="list" class="w-6 h-6 text-purple-500 mr-3"></i> | |
| <h3 class="text-lg font-semibold">Additional Requirements</h3> | |
| </div> | |
| <textarea | |
| id="additionalReqs" | |
| class="w-full px-4 py-3 bg-gray-700 border border-gray-600 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent text-white placeholder-gray-400 resize-none transition-all duration-200" | |
| rows="3" | |
| placeholder="Any specific behaviors, accessibility requirements, or custom features?" | |
| ></textarea> | |
| </div> | |
| <!-- Generate Button --> | |
| <button | |
| id="generateScopeBtn" | |
| class="w-full px-6 py-4 bg-gradient-to-r from-purple-600 to-pink-600 hover:from-purple-700 hover:to-pink-700 text-white font-semibold rounded-lg transition-all duration-200 transform hover:scale-105 focus:ring-4 focus:ring-purple-500 focus:ring-opacity-50 flex items-center justify-center" | |
| > | |
| <i data-feather="zap" class="w-5 h-5 mr-2"></i> | |
| Generate AI Scope | |
| </button> | |
| </div> | |
| <!-- Right Column - AI Output --> | |
| <div class="space-y-6"> | |
| <!-- Loading State --> | |
| <div id="loadingState" class="hidden bg-gray-800 rounded-xl p-8 border border-gray-700 text-center"> | |
| <div class="animate-spin rounded-full h-12 w-12 border-b-2 border-purple-500 mx-auto mb-4"></div> | |
| <p class="text-gray-300">AI is analyzing your requirements and generating optimal component scope...</p> | |
| </div> | |
| <!-- Framework Selection --> | |
| <div id="frameworkSection" class="hidden bg-gray-800 rounded-xl p-6 border border-gray-700"> | |
| <div class="flex items-center mb-4"> | |
| <i data-feather="smartphone" class="w-6 h-6 text-purple-500 mr-3"></i> | |
| <h3 class="text-lg font-semibold">Target Framework</h3> | |
| </div> | |
| <div class="grid grid-cols-2 gap-4"> | |
| <button class="framework-btn bg-gray-700 hover:bg-purple-600 p-4 rounded-lg border border-gray-600 transition-all duration-200" data-framework="react-web"> | |
| <i data-feather="globe" class="w-8 h-8 mb-3 mx-auto"></i> | |
| <span class="text-sm font-medium">React Web</span> | |
| <p class="text-xs text-gray-400 mt-1">With react-aria hooks</p> | |
| </button> | |
| <button class="framework-btn bg-gray-700 hover:bg-pink-600 p-4 rounded-lg border border-gray-600 transition-all duration-200" data-framework="react-native"> | |
| <i data-feather="smartphone" class="w-8 h-8 mb-3 mx-auto"></i> | |
| <span class="text-sm font-medium">React Native</span> | |
| <p class="text-xs text-gray-400 mt-1">With native APIs</p> | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Hooks & Behaviors --> | |
| <div id="hooksSection" class="hidden bg-gray-800 rounded-xl p-6 border border-gray-700"> | |
| <div class="flex items-center mb-4"> | |
| <i data-feather="anchor" class="w-6 h-6 text-purple-500 mr-3"></i> | |
| <h3 class="text-lg font-semibold">Suggested Hooks & Behaviors</h3> | |
| </div> | |
| <div id="hooksList" class="space-y-2"> | |
| <!-- Hooks will be populated here --> | |
| </div> | |
| </div> | |
| <!-- Data Attributes --> | |
| <div id="attributesSection" class="hidden bg-gray-800 rounded-xl p-6 border border-gray-700"> | |
| <div class="flex items-center mb-4"> | |
| <i data-feather="database" class="w-6 h-6 text-purple-500 mr-3"></i> | |
| <h3 class="text-lg font-semibold">Data Attributes</h3> | |
| </div> | |
| <div id="attributesList" class="space-y-2"> | |
| <!-- Attributes will be populated here --> | |
| </div> | |
| </div> | |
| <!-- Code Structure --> | |
| <div id="structureSection" class="hidden bg-gray-800 rounded-xl p-6 border border-gray-700"> | |
| <div class="flex items-center mb-4"> | |
| <i data-feather="code" class="w-6 h-6 text-purple-500 mr-3"></i> | |
| <h3 class="text-lg font-semibold">Code Structure</h3> | |
| </div> | |
| <div class="grid grid-cols-2 gap-4"> | |
| <button class="structure-btn bg-gray-700 hover:bg-purple-600 p-4 rounded-lg border border-gray-600 transition-all duration-200" data-structure="typed-primitives"> | |
| <i data-feather="type" class="w-8 h-8 mb-3 mx-auto"></i> | |
| <span class="text-sm font-medium">Typed Primitives</span> | |
| <p class="text-xs text-gray-400 mt-1">Combined approach</p> | |
| </button> | |
| <button class="structure-btn bg-gray-700 hover:bg-pink-600 p-4 rounded-lg border border-gray-600 transition-all duration-200" data-structure="adapter-pattern"> | |
| <i data-feather="layers" class="w-8 h-8 mb-3 mx-auto"></i> | |
| <span class="text-sm font-medium">Adapter Pattern</span> | |
| <p class="text-xs text-gray-400 mt-1">Separated behaviors</p> | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Continue Button --> | |
| <div id="continueSection" class="hidden"> | |
| <button | |
| id="continueBtn" | |
| class="w-full px-6 py-4 bg-gradient-to-r from-green-600 to-emerald-600 hover:from-green-700 hover:to-emerald-700 text-white font-semibold rounded-lg transition-all duration-200 transform hover:scale-105 focus:ring-4 focus:ring-green-500 focus:ring-opacity-50 flex items-center justify-center" | |
| > | |
| <i data-feather="arrow-right" class="w-5 h-5 mr-2"></i> | |
| Continue to Code Generation | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </main> | |
| <custom-footer></custom-footer> | |
| <script src="components/header.js"></script> | |
| <script src="components/footer.js"></script> | |
| <script src="script.js"></script> | |
| <script> | |
| feather.replace(); | |
| // Load project data | |
| document.addEventListener('DOMContentLoaded', function() { | |
| const projectData = StorageManager.getProjectData(); | |
| document.getElementById('projectTitle').textContent = `Project: ${projectData.name}`; | |
| document.getElementById('projectDesc').textContent = projectData.description; | |
| // Component type selection | |
| document.querySelectorAll('.component-type-btn').forEach(btn => { | |
| btn.addEventListener('click', function() { | |
| document.querySelectorAll('.component-type-btn').forEach(b => b.classList.remove('bg-purple-600', 'bg-pink-600', 'bg-blue-600', 'bg-green-600', 'bg-yellow-600', 'bg-indigo-600')); | |
| this.classList.add(this.classList.contains('hover:bg-purple-600') ? 'bg-purple-600' : | |
| this.classList.contains('hover:bg-pink-600') ? 'bg-pink-600' : | |
| this.classList.contains('hover:bg-blue-600') ? 'bg-blue-600' : | |
| this.classList.contains('hover:bg-green-600') ? 'bg-green-600' : | |
| this.classList.contains('hover:bg-yellow-600') ? 'bg-yellow-600' : 'bg-indigo-600'); | |
| }); | |
| }); | |
| // Generate scope | |
| document.getElementById('generateScopeBtn').addEventListener('click', async function() { | |
| const selectedType = document.querySelector('.component-type-btn.bg-purple-600, .component-type-btn.bg-pink-600, .component-type-btn.bg-blue-600, .component-type-btn.bg-green-600, .component-type-btn.bg-yellow-600, .component-type-btn.bg-indigo-600')?.dataset.type || 'button'; | |
| const additionalReqs = document.getElementById('additionalReqs').value; | |
| // Show loading | |
| document.getElementById('loadingState').classList.remove('hidden'); | |
| try { | |
| const scope = await AIService.generateComponentScope(projectData.description, selectedType); | |
| // Store scope | |
| localStorage.setItem('projectScope', JSON.stringify(scope)); | |
| // Hide loading, show results | |
| document.getElementById('loadingState').classList.add('hidden'); | |
| document.getElementById('frameworkSection').classList.remove('hidden'); | |
| document.getElementById('hooksSection').classList.remove('hidden'); | |
| document.getElementById('attributesSection').classList.remove('hidden'); | |
| document.getElementById('structureSection').classList.remove('hidden'); | |
| // Populate hooks | |
| const hooksList = document.getElementById('hooksList'); | |
| hooksList.innerHTML = scope.suggestedHooks.map(hook => ` | |
| <div class="flex items-center p-3 bg-gray-700 rounded-lg border border-gray-600"> | |
| <i data-feather="check-circle" class="w-4 h-4 text-green-500 mr-3"></i> | |
| <span class="text-sm font-mono">${hook}</span> | |
| `).join(''); | |
| // Populate attributes | |
| const attributesList = document.getElementById('attributesList'); | |
| attributesList.innerHTML = scope.dataAttributes.map(attr => ` | |
| <div class="flex items-center p-3 bg-gray-700 rounded-lg border border-gray-600"> | |
| <i data-feather="tag" class="w-4 h-4 text-blue-500 mr-3"></i> | |
| <span class="text-sm font-mono">${attr}</span> | |
| </div> | |
| `).join(''); | |
| } catch (error) { | |
| console.error('Error generating scope:', error); | |
| document.getElementById('loadingState').classList.add('hidden'); | |
| alert('Error generating scope. Please try again.'); | |
| } | |
| }); | |
| // Framework selection | |
| document.querySelectorAll('.framework-btn').forEach(btn => { | |
| btn.addEventListener('click', function() { | |
| document.querySelectorAll('.framework-btn').forEach(b => b.classList.remove('bg-purple-600', 'bg-pink-600')); | |
| this.classList.add(this.classList.contains('hover:bg-purple-600') ? 'bg-purple-600' : 'bg-pink-600'); | |
| localStorage.setItem('selectedFramework', this.dataset.framework); | |
| document.getElementById('continueSection').classList.remove('hidden'); | |
| }); | |
| // Structure selection | |
| document.querySelectorAll('.structure-btn').forEach(btn => { | |
| btn.addEventListener('click', function() { | |
| document.querySelectorAll('.structure-btn').forEach(b => b.classList.remove('bg-purple-600', 'bg-pink-600')); | |
| this.classList.add(this.classList.contains('hover:bg-purple-600') ? 'bg-purple-600' : 'bg-pink-600'); | |
| localStorage.setItem('selectedCodeStructure', this.dataset.structure); | |
| }); | |
| // Continue to next page | |
| document.getElementById('continueBtn').addEventListener('click', function() { | |
| window.location.href = 'code.html'; | |
| }); | |
| }); | |
| </script> | |
| </body> | |
| </html> |