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 CustomProblemCard extends HTMLElement { | |
| constructor() { | |
| super(); | |
| this.title = this.getAttribute('title') || 'Challenge'; | |
| this.language = this.getAttribute('language') || 'Python'; | |
| this.difficulty = this.getAttribute('difficulty') || 'Easy'; | |
| this.time = this.getAttribute('time') || '15 min'; | |
| this.description = this.getAttribute('description') || 'Description'; | |
| this.status = this.getAttribute('status') || 'free'; | |
| } | |
| connectedCallback() { | |
| this.attachShadow({ mode: 'open' }); | |
| this.shadowRoot.innerHTML = ` | |
| <style> | |
| :host { | |
| display: block; | |
| } | |
| .problem-card { | |
| background: rgba(31, 41, 55, 0.7); | |
| border: 1px solid rgba(55, 65, 81, 0.3); | |
| border-radius: 1rem; | |
| padding: 1.5rem; | |
| transition: all 0.3s ease; | |
| height: 100%; | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .problem-card::before { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| height: 3px; | |
| background: linear-gradient(90deg, #22c55e, #d946ef); | |
| opacity: 0; | |
| transition: opacity 0.3s ease; | |
| } | |
| .problem-card:hover::before { | |
| opacity: 1; | |
| } | |
| .language-badge { | |
| display: inline-block; | |
| padding: 0.25rem 0.75rem; | |
| border-radius: 9999px; | |
| font-size: 0.75rem; | |
| font-weight: 600; | |
| } | |
| .python-badge { | |
| background: rgba(34, 197, 94, 0.15); | |
| color: #22c55e; | |
| } | |
| .sql-badge { | |
| background: rgba(217, 70, 239, 0.15); | |
| color: #d946ef; | |
| } | |
| .difficulty-badge { | |
| display: inline-flex; | |
| align-items: center; | |
| padding: 0.25rem 0.75rem; | |
| border-radius: 9999px; | |
| font-size: 0.75rem; | |
| font-weight: 600; | |
| } | |
| .difficulty-easy { | |
| background: rgba(34, 197, 94, 0.1); | |
| border: 1px solid rgba(34, 197, 94, 0.3); | |
| color: #22c55e; | |
| } | |
| .difficulty-medium { | |
| background: rgba(245, 158, 11, 0.1); | |
| border: 1px solid rgba(245, 158, 11, 0.3); | |
| color: #f59e0b; | |
| } | |
| .status-ribbon { | |
| position: absolute; | |
| top: 0; | |
| right: 0; | |
| padding: 0.25rem 1rem; | |
| font-size: 0.75rem; | |
| font-weight: 600; | |
| border-radius: 0.375rem 1rem 0.375rem 0.375rem; | |
| font-size: 0.75rem; | |
| } | |
| .status-free { | |
| background: rgba(34, 197, 94, 0.2); | |
| color: #22c55e; | |
| } | |
| .status-premium { | |
| background: rgba(217, 70, 239, 0.2); | |
| color: #d946ef; | |
| } | |
| .hover-lift:hover { | |
| transform: translateY(-3px); | |
| box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.3); | |
| } | |
| </style> | |
| <div class="problem-card fade-in hover-lift"> | |
| ${this.status !== 'free' ? | |
| `<div class="status-ribbon ${this.status === 'premium' ? 'status-premium' : ''}"> | |
| ${this.status.toUpperCase()} | |
| </div>` : ''} | |
| <div class="flex justify-between items-start mb-4"> | |
| <div class="language-badge ${this.language === 'Python' ? 'python-badge' : 'sql-badge'}"> | |
| ${this.language} | |
| </div> | |
| </div> | |
| <h3 class="text-xl font-bold mb-3">${this.title}</h3> | |
| <p class="text-gray-300 mb-6">${this.description}</p> | |
| <div class="flex justify-between items-center"> | |
| <div class="flex items-center"> | |
| <div class="difficulty-badge ${this.difficulty.toLowerCase() === 'easy' ? 'difficulty-easy' : 'difficulty-medium'}"> | |
| ${this.difficulty} | |
| </div> | |
| <div class="text-gray-400 text-sm flex items-center"> | |
| <i data-feather="clock" class="w-4 h-4 mr-1"></i> | |
| ${this.time} | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| `; | |
| setTimeout(() => { | |
| if (typeof feather !== 'undefined') { | |
| feather.replace(); | |
| } | |
| }, 100); | |
| } | |
| } | |
| customElements.define('custom-problem-card', CustomProblemCard); |