Generate a modern web app landing + dashboard UI for an app called "PySQL Labs" β a Python + SQL interactive learning platform with hands-on labs and interview-style drills. Create a polished, developer-focused, slightly playful but professional design.
509f3c2
verified
| class CustomDashboard extends HTMLElement { | |
| connectedCallback() { | |
| this.attachShadow({ mode: 'open' }); | |
| this.shadowRoot.innerHTML = ` | |
| <style> | |
| :host { | |
| display: block; | |
| } | |
| .dashboard-container { | |
| background: rgba(31, 41, 55, 0.7); | |
| border-radius: 1.5rem; | |
| padding: 2rem; | |
| border: 1px solid rgba(55, 65, 81, 0.3); | |
| } | |
| .progress-bar { | |
| height: 0.75rem; | |
| border-radius: 9999px; | |
| background: rgba(55, 65, 81, 0.5); | |
| overflow: hidden; | |
| } | |
| .progress-fill { | |
| height: 100%; | |
| border-radius: 9999px; | |
| background: linear-gradient(90deg, #22c55e, #d946ef); | |
| transition: width 1s ease-in-out; | |
| } | |
| .badge { | |
| display: inline-flex; | |
| align-items: center; | |
| padding: 0.25rem 0.75rem; | |
| border-radius: 9999px; | |
| font-size: 0.75rem; | |
| font-weight: 600; | |
| } | |
| .interview-timer { | |
| font-family: 'JetBrains Mono', monospace; | |
| font-size: 1.875rem; | |
| font-weight: bold; | |
| } | |
| </style> | |
| <div class="dashboard-container"> | |
| <div class="grid grid-cols-1 lg:grid-cols-3 gap-8"> | |
| <!-- Left: Progress Summary --> | |
| <div class="space-y-6"> | |
| <div> | |
| <h3 class="text-lg font-semibold mb-3">Your Progress</h3> | |
| <div class="bg-gray-800/50 rounded-xl p-4"> | |
| <div class="flex items-center justify-between mb-4"> | |
| <div> | |
| <div class="text-2xl font-bold">Level 12</div> | |
| <div class="text-gray-400">Python & SQL Expert</div> | |
| </div> | |
| <div class="space-y-4"> | |
| <div> | |
| <div class="flex justify-between text-sm mb-1"> | |
| <span>Python Mastery</span> | |
| <span>85%</span> | |
| </div> | |
| <div class="progress-bar"> | |
| <div class="progress-fill" style="width: 85%"></div> | |
| </div> | |
| <div> | |
| <div class="flex justify-between text-sm mb-1"> | |
| <span>SQL Skills</span> | |
| <span>78%</span> | |
| </div> | |
| <div class="progress-bar"> | |
| <div class="progress-fill" style="width: 78%"></div> | |
| </div> | |
| </div> | |
| <div class="mt-4"> | |
| <div class="flex space-x-3"> | |
| <div class="badge bg-primary/10 text-primary"> | |
| <i data-feather="star" class="w-3 h-3 mr-2"></i> | |
| 3 Badges | |
| </div> | |
| <div class="badge bg-secondary/10 text-secondary"> | |
| <i data-feather="flame" class="w-3 h-3 mr-2"></i> | |
| Streak: 14 days | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Middle: Continue Lab --> | |
| <div class="space-y-6"> | |
| <h3 class="text-lg font-semibold">Continue Learning</h3> | |
| <div class="bg-gray-800/70 rounded-xl p-4 border border-gray-700"> | |
| <div class="flex items-center justify-between mb-3"> | |
| <span class="text-sm text-gray-400">Last active lab</span> | |
| <div class="badge bg-green-500/10 text-green-500"> | |
| <i data-feather="play-circle" class="w-4 h-4 mr-2"></i> | |
| Continue Lab | |
| </div> | |
| </div> | |
| <div class="space-y-4"> | |
| <div class="bg-gray-900 rounded-lg p-3 font-mono text-sm"> | |
| def find_first_prime(nums): | |
| for num in nums: | |
| if is_prime(num): | |
| return num | |
| return None | |
| </div> | |
| <div class="flex items-center justify-between"> | |
| <div class="text-sm text-gray-300">Find First Prime</div> | |
| <div class="flex items-center"> | |
| <div class="w-2 h-2 rounded-full bg-green-500 mr-2"></div> | |
| <span class="text-sm">Tests: 4/5 passed</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Right: Interview Mode --> | |
| <div class="space-y-6"> | |
| <h3 class="text-lg font-semibold">Interview Mode</h3> | |
| <div class="bg-gray-800/70 rounded-xl p-4 border border-gray-700"> | |
| <div class="interview-timer text-center mb-4" id="interview-timer"> | |
| 30:00 | |
| </div> | |
| <div class="space-y-4"> | |
| <div> | |
| <div class="text-sm text-gray-400 mb-2">Next Question</div> | |
| <div class="bg-gray-900 rounded-lg p-4"> | |
| <div class="font-mono text-sm mb-3"> | |
| # SQL: Find duplicate emails | |
| # Time limit: 10 minutes | |
| </div> | |
| <button class="w-full py-3 bg-gradient-to-r from-secondary to-secondary/80 hover:from-secondary/90 hover:to-secondary text-white font-semibold rounded-lg transition-all"> | |
| <i data-feather="zap" class="w-4 h-4 mr-2"></i> | |
| Start Interview | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="mt-8 grid grid-cols-2 gap-4"> | |
| <div class="text-center p-4 bg-gray-800/50 rounded-xl"> | |
| <div class="text-3xl font-bold mb-2">142</div> | |
| <div class="text-sm text-gray-400">Problems Solved</div> | |
| </div> | |
| <div class="text-center p-4 bg-gray-800/50 rounded-xl"> | |
| <div class="text-3xl font-bold mb-2">87%</div> | |
| <div class="text-sm text-gray-400">Success Rate</div> | |
| </div> | |
| </div> | |
| </div> | |
| `; | |
| setTimeout(() => { | |
| if (typeof feather !== 'undefined') { | |
| feather.replace(); | |
| } | |
| }, 100); | |
| } | |
| } | |
| customElements.define('custom-dashboard', CustomDashboard); |