Ravvi89/leetcode-pattern-trainer
0
1<!DOCTYPE html>2<html lang="en" class="h-full">3<head>4 <meta charset="UTF-8" />5 <meta name="viewport" content="width=device-width, initial-scale=1.0"/>6 <title>LeetCode Pattern Trainer</title>7 <meta name="description" content="Practice LeetCode by algorithm patterns with step-by-step guides."/>8 <link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='96' height='96' viewBox='0 0 24 24' fill='none' stroke='%23059669' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 3v18h18'/%3E%3Cpath d='M19 17V9l-5 5-4-4-6 6'/%3E%3C/svg%3E"/>9 <!-- Highlight.js -->10 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@11.9.0/styles/github.min.css">11 <script src="https://cdn.jsdelivr.net/npm/highlight.js@11.9.0/lib/highlight.min.js"></script>12 <!-- Feather Icons -->13 <script src="https://cdn.jsdelivr.net/npm/feather-icons@4.29.2/dist/feather.min.js"></script>14 <!-- TailwindCSS Play CDN (for easy dev usage) -->15 <script src="https://cdn.tailwindcss.com"></script>16 <script>17 tailwind.config = {18 darkMode: 'class',19 theme: {20 extend: {21 colors: {22 primary: {23 50: '#f0f9ff',24 100: '#e0f2fe',25 200: '#bae6fd',26 300: '#7dd3fc',27 400: '#38bdf8',28 500: '#0ea5e9', /* default sky-500 */29 600: '#0284c7',30 700: '#0369a1',31 800: '#075985',32 900: '#0c4a6e'33 },34 secondary: {35 50: '#f5f3ff',36 100: '#ede9fe',37 200: '#ddd6fe',38 300: '#c4b5fd',39 400: '#a78bfa',40 500: '#8b5cf6', /* default violet-500 */41 600: '#7c3aed',42 700: '#6d28d9',43 800: '#5b21b6',44 900: '#4c1d95'45 }46 },47 boxShadow: {48 'soft': '0 6px 20px rgba(0,0,0,0.08)'49 },50 borderRadius: {51 'xl': '0.9rem'52 }53 }54 }55 }56 </script>57 <link rel="stylesheet" href="style.css">58</head>59<body class="h-full bg-slate-50 dark:bg-slate-900 text-slate-800 dark:text-slate-100 transition-colors">60 <!-- Header -->61 <header class="sticky top-0 z-20 border-b border-slate-200/60 dark:border-slate-800/70 bg-white/70 dark:bg-slate-900/70 backdrop-blur">62 <div class="mx-auto max-w-7xl px-4 sm:px-6">63 <div class="h-16 flex items-center justify-between">64 <div class="flex items-center gap-3">65 <div class="h-9 w-9 grid place-items-center rounded-lg bg-primary-100 text-primary-600 dark:bg-primary-900/30 dark:text-primary-300">66 <i data-feather="target"></i>67 </div>68 <div>69 <div class="font-semibold text-lg">LeetCode Pattern Trainer</div>70 <div class="text-xs text-slate-500 dark:text-slate-400">Practice by patterns, not problems</div>71 </div>72 </div>73 <div class="hidden md:flex items-center gap-3">74 <div class="px-3 py-1.5 rounded-full bg-emerald-50 text-emerald-700 border border-emerald-200/70 text-xs font-medium">75 Track your progress locally76 </div>77 </div>78 </div>79 </div>80 </header>81 82 <!-- Main -->83 <main class="mx-auto max-w-7xl px-4 sm:px-6 py-6">84 <div class="flex flex-col lg:flex-row gap-6">85 <!-- Sidebar: Patterns -->86 <aside class="lg:w-64 shrink-0">87 <div class="sticky top-24 space-y-6">88 <div class="rounded-xl border border-slate-200/70 dark:border-slate-800 bg-white dark:bg-slate-950 shadow-soft">89 <div class="px-4 py-3 border-b border-slate-200/70 dark:border-slate-800 flex items-center justify-between">90 <div class="font-semibold text-sm">Patterns</div>91 <button id="clearPatternFilterBtn" class="text-xs text-primary-600 hover:text-primary-700 disabled:opacity-50" disabled>Clear</button>92 </div>93 <div id="patternList" class="max-h-[420px] overflow-auto p-2 space-y-1">94 <!-- Patterns injected -->95 </div>96 </div>97 98 <div class="rounded-xl border border-slate-200/70 dark:border-slate-800 bg-white dark:bg-slate-950 shadow-soft">99 <div class="px-4 py-3 border-b border-slate-200/70 dark:border-slate-800">100 <div class="font-semibold text-sm">Theme</div>101 </div>102 <div class="p-3">103 <div class="flex items-center justify-between">104 <div class="text-sm">Dark mode</div>105 <button id="themeToggle" class="relative inline-flex h-6 w-11 items-center rounded-full bg-slate-200 dark:bg-slate-700 transition">106 <span id="themeToggleKnob" class="inline-block h-5 w-5 transform rounded-full bg-white dark:translate-x-6 transition shadow"></span>107 </button>108 </div>109 <div class="mt-2">110 <button id="resetProgress" class="text-xs text-red-600 hover:text-red-700">Reset progress</button>111 </div>112 </div>113 </div>114 </div>115 </aside>116 117 <!-- Content -->118 <section class="flex-1 min-w-0">119 <!-- Toolbar -->120 <div class="rounded-xl border border-slate-200/70 dark:border-slate-800 bg-white dark:bg-slate-950 shadow-soft">121 <div class="p-4">122 <div class="flex flex-col sm:flex-row gap-3 sm:items-center">123 <div class="relative flex-1">124 <i data-feather="search" class="absolute left-3 top-2.5 h-5 w-5 text-slate-400"></i>125 <input id="searchInput" type="text" placeholder="Search by title or tag..." class="w-full pl-10 pr-4 py-2 rounded-lg border border-slate-200 dark:border-slate-800 bg-slate-50 dark:bg-slate-900 focus:outline-none focus:ring-2 focus:ring-primary-500/40">126 </div>127 <div class="flex items-center gap-2">128 <select id="difficultyFilter" class="px-3 py-2 rounded-lg border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-900 text-sm">129 <option value="all">All difficulties</option>130 <option value="easy">Easy</option>131 <option value="medium">Medium</option>132 <option value="hard">Hard</option>133 </select>134 <select id="statusFilter" class="px-3 py-2 rounded-lg border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-900 text-sm">135 <option value="all">All</option>136 <option value="unsolved">Unsolved</option>137 <option value="solved">Solved</option>138 </select>139 <button id="sortBtn" class="px-3 py-2 rounded-lg border border-slate-200 dark:border-slate-800 text-sm flex items-center gap-2">140 <span id="sortLabel">Sort: Default</span>141 <i data-feather="chevron-down" class="h-4 w-4"></i>142 </button>143 </div>144 </div>145 </div>146 </div>147 148 <!-- Stats -->149 <div class="mt-6 grid grid-cols-2 md:grid-cols-4 gap-3">150 <div class="rounded-xl p-4 border border-slate-200/70 dark:border-slate-800 bg-white dark:bg-slate-950">151 <div class="text-xs text-slate-500">Total Questions</div>152 <div id="statTotal" class="mt-2 text-2xl font-semibold">0</div>153 </div>154 <div class="rounded-xl p-4 border border-emerald-200/70 dark:border-emerald-900 bg-emerald-50/60 dark:bg-emerald-900/20">155 <div class="text-xs text-emerald-700 dark:text-emerald-300">Solved</div>156 <div id="statSolved" class="mt-2 text-2xl font-semibold text-emerald-700 dark:text-emerald-200">0</div>157 </div>158 <div class="rounded-xl p-4 border border-amber-200/70 dark:border-amber-900 bg-amber-50/60 dark:bg-amber-900/20">159 <div class="text-xs text-amber-700 dark:text-amber-300">Unsolved</div>160 <div id="statUnsolved" class="mt-2 text-2xl font-semibold text-amber-700 dark:text-amber-200">0</div>161 </div>162 <div class="rounded-xl p-4 border border-slate-200/70 dark:border-slate-800 bg-white dark:bg-slate-950">163 <div class="text-xs text-slate-500">Accuracy</div>164 <div id="statAccuracy" class="mt-2 text-2xl font-semibold">0%</div>165 </div>166 </div>167 168 <!-- Questions -->169 <div id="questionsGrid" class="mt-6 grid gap-4 md:grid-cols-2 xl:grid-cols-3">170 <!-- Cards injected -->171 </div>172 173 <div id="emptyState" class="hidden mt-10 text-center text-slate-500">174 <i data-feather="filter" class="mx-auto h-8 w-8 text-slate-400"></i>175 <div class="mt-2">No results match your filters.</div>176 </div>177 </section>178 </div>179 </main>180 181 <!-- Modal -->182 <div id="modal" class="hidden fixed inset-0 z-30">183 <div class="absolute inset-0 bg-black/50"></div>184 <div class="relative mx-auto mt-10 max-w-4xl w-[calc(100%-2rem)] rounded-2xl border border-slate-200/70 dark:border-slate-800 bg-white dark:bg-slate-950 shadow-soft">185 <div class="flex items-center justify-between p-4 border-b border-slate-200/70 dark:border-slate-800">186 <div class="flex items-center gap-2">187 <div id="modalDifficultyBadge" class="px-2 py-1 text-xs rounded-full border">Medium</div>188 <div id="modalTitle" class="font-semibold"></div>189 </div>190 <div class="flex items-center gap-2">191 <button id="toggleSolvedBtn" class="px-3 py-1.5 rounded-lg bg-emerald-600 text-white text-sm hover:bg-emerald-700">Mark as Solved</button>192 <button id="modalCloseBtn" class="p-2 hover:bg-slate-100 dark:hover:bg-slate-800 rounded-lg"><i data-feather="x"></i></button>193 </div>194 </div>195 <div class="p-5 grid gap-6 md:grid-cols-2">196 <div class="space-y-4">197 <div>198 <div class="text-xs text-slate-500">Description</div>199 <div id="modalDescription" class="mt-1 whitespace-pre-line"></div>200 </div>201 <div>202 <div class="text-xs text-slate-500">Constraints</div>203 <div id="modalConstraints" class="mt-1 whitespace-pre-line"></div>204 </div>205 </div>206 <div class="space-y-3">207 <div class="flex items-center justify-between">208 <div class="font-medium">Approach</div>209 <button id="copyApproachBtn" class="text-sm text-primary-600 hover:text-primary-700">Copy</button>210 </div>211 <pre class="p-3 rounded-lg overflow-auto text-sm bg-slate-50 dark:bg-slate-900 border border-slate-200/70 dark:border-slate-800"><code id="approachCode" class="language-javascript"></code></pre>212 <div class="flex items-center justify-between">213 <div class="font-medium">Solution</div>214 <button id="copySolutionBtn" class="text-sm text-primary-600 hover:text-primary-700">Copy</button>215 </div>216 <pre class="p-3 rounded-lg overflow-auto text-sm bg-slate-50 dark:bg-slate-900 border border-slate-200/70 dark:border-slate-800"><code id="solutionCode" class="language-javascript"></code></pre>217 </div>218 </div>219 </div>220 </div>221 222 <!-- Toast -->223 <div id="toast" class="hidden fixed bottom-4 left-1/2 -translate-x-1/2 z-40 px-4 py-2 rounded-lg bg-slate-900 text-white text-sm shadow-lg">Copied to clipboard</div>224 225 <script src="script.js"></script>226 <script>feather.replace();</script>227<script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>228</body>229</html>