modal-abuse.html

  1<!DOCTYPE html>
  2<html lang="en">
  3<head>
  4  <meta charset="UTF-8">
  5  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6  <title>Anti-Pattern: Modal Abuse</title>
  7  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
  8  <style>
  9    * {
 10      margin: 0;
 11      padding: 0;
 12      box-sizing: border-box;
 13    }
 14
 15    body {
 16      font-family: 'Inter', sans-serif;
 17      min-height: 100vh;
 18      background: #1e1e1e;
 19      padding: 40px;
 20    }
 21
 22    .container {
 23      max-width: 960px;
 24      width: 100%;
 25      margin: 0 auto;
 26      background: #f8fafc;
 27      border-radius: 24px;
 28      padding: 0;
 29      display: flex;
 30      flex-direction: column;
 31      position: relative;
 32      overflow: hidden;
 33    }
 34
 35    /* Base app UI (dimmed) */
 36    .app-ui {
 37      flex: 1;
 38      display: flex;
 39      flex-direction: column;
 40      filter: brightness(0.4);
 41    }
 42
 43    .app-header {
 44      background: white;
 45      padding: 16px 24px;
 46      border-bottom: 1px solid #e5e7eb;
 47      display: flex;
 48      justify-content: space-between;
 49      align-items: center;
 50    }
 51
 52    .app-logo {
 53      font-weight: 700;
 54      font-size: 18px;
 55      color: #111;
 56    }
 57
 58    .app-nav {
 59      display: flex;
 60      gap: 24px;
 61    }
 62
 63    .app-nav a {
 64      color: #6b7280;
 65      text-decoration: none;
 66      font-size: 14px;
 67    }
 68
 69    .app-content {
 70      flex: 1;
 71      display: flex;
 72    }
 73
 74    .app-sidebar {
 75      width: 200px;
 76      background: white;
 77      border-right: 1px solid #e5e7eb;
 78      padding: 16px;
 79    }
 80
 81    .sidebar-item {
 82      padding: 10px 12px;
 83      border-radius: 6px;
 84      font-size: 14px;
 85      color: #6b7280;
 86      margin-bottom: 4px;
 87    }
 88
 89    .sidebar-item.active {
 90      background: #f3f4f6;
 91      color: #111;
 92      font-weight: 500;
 93    }
 94
 95    .app-main {
 96      flex: 1;
 97      padding: 24px;
 98      background: #f9fafb;
 99    }
100
101    .app-card {
102      background: white;
103      border-radius: 12px;
104      padding: 20px;
105      margin-bottom: 16px;
106    }
107
108    .app-card h3 {
109      font-size: 16px;
110      color: #111;
111      margin-bottom: 8px;
112    }
113
114    .app-card p {
115      font-size: 14px;
116      color: #6b7280;
117    }
118
119    /* Modal backdrop */
120    .modal-backdrop {
121      position: absolute;
122      inset: 0;
123      background: rgba(0, 0, 0, 0.5);
124    }
125
126    /* Large modal with advanced settings */
127    .modal {
128      position: absolute;
129      top: 50%;
130      left: 50%;
131      transform: translate(-50%, -50%);
132      width: 600px;
133      max-height: 800px;
134      background: white;
135      border-radius: 16px;
136      box-shadow: 0 25px 50px rgba(0,0,0,0.3);
137      overflow: hidden;
138      z-index: 100;
139    }
140
141    .modal-header {
142      display: flex;
143      justify-content: space-between;
144      align-items: center;
145      padding: 20px 24px;
146      border-bottom: 1px solid #e5e7eb;
147    }
148
149    .modal-title {
150      font-size: 18px;
151      font-weight: 700;
152      color: #111;
153    }
154
155    .modal-close {
156      width: 32px;
157      height: 32px;
158      border-radius: 8px;
159      border: none;
160      background: #f3f4f6;
161      color: #6b7280;
162      font-size: 18px;
163      cursor: pointer;
164      display: flex;
165      align-items: center;
166      justify-content: center;
167    }
168
169    .modal-body {
170      padding: 24px;
171      max-height: 600px;
172      overflow-y: auto;
173    }
174
175    /* Complex settings form that should be on a dedicated page */
176    .settings-section {
177      margin-bottom: 28px;
178    }
179
180    .settings-section h4 {
181      font-size: 14px;
182      font-weight: 600;
183      color: #374151;
184      margin-bottom: 16px;
185      padding-bottom: 8px;
186      border-bottom: 1px solid #e5e7eb;
187    }
188
189    .setting-row {
190      display: flex;
191      justify-content: space-between;
192      align-items: center;
193      padding: 12px 0;
194      border-bottom: 1px solid #f3f4f6;
195    }
196
197    .setting-row:last-child {
198      border-bottom: none;
199    }
200
201    .setting-label {
202      font-size: 14px;
203      color: #374151;
204    }
205
206    .setting-desc {
207      font-size: 12px;
208      color: #9ca3af;
209      margin-top: 2px;
210    }
211
212    .toggle {
213      width: 44px;
214      height: 24px;
215      background: #e5e7eb;
216      border-radius: 12px;
217      position: relative;
218    }
219
220    .toggle.on {
221      background: #3b82f6;
222    }
223
224    .toggle::after {
225      content: '';
226      position: absolute;
227      width: 20px;
228      height: 20px;
229      background: white;
230      border-radius: 50%;
231      top: 2px;
232      left: 2px;
233      transition: 0.2s;
234    }
235
236    .toggle.on::after {
237      left: 22px;
238    }
239
240    .select-input {
241      padding: 8px 12px;
242      border: 1px solid #d1d5db;
243      border-radius: 6px;
244      font-size: 13px;
245      color: #374151;
246      background: white;
247    }
248
249    .text-input {
250      padding: 8px 12px;
251      border: 1px solid #d1d5db;
252      border-radius: 6px;
253      font-size: 13px;
254      width: 180px;
255    }
256
257    .modal-footer {
258      display: flex;
259      gap: 12px;
260      justify-content: flex-end;
261      padding: 16px 24px;
262      border-top: 1px solid #e5e7eb;
263      background: #f9fafb;
264    }
265
266    .btn {
267      padding: 10px 20px;
268      border-radius: 8px;
269      font-size: 14px;
270      font-weight: 600;
271      cursor: pointer;
272      border: none;
273    }
274
275    .btn-secondary {
276      background: white;
277      border: 1px solid #d1d5db;
278      color: #374151;
279    }
280
281    .btn-primary {
282      background: #2563eb;
283      color: white;
284    }
285
286
287  </style>
288</head>
289<body>
290  <div class="container">
291    <!-- Base app -->
292    <div class="app-ui">
293      <div class="app-header">
294        <div class="app-logo">Dashboard</div>
295        <div class="app-nav">
296          <a href="#">Home</a>
297          <a href="#">Projects</a>
298          <a href="#">Team</a>
299        </div>
300      </div>
301      <div class="app-content">
302        <div class="app-sidebar">
303          <div class="sidebar-item active">Overview</div>
304          <div class="sidebar-item">Analytics</div>
305          <div class="sidebar-item">Reports</div>
306          <div class="sidebar-item">Settings</div>
307        </div>
308        <div class="app-main">
309          <div class="app-card">
310            <h3>Recent Activity</h3>
311            <p>Your recent actions will appear here...</p>
312          </div>
313          <div class="app-card">
314            <h3>Quick Stats</h3>
315            <p>Overview of your account metrics...</p>
316          </div>
317        </div>
318      </div>
319    </div>
320
321    <div class="modal-backdrop"></div>
322
323    <!-- Advanced settings crammed into a modal instead of a proper settings page -->
324    <div class="modal">
325      <div class="modal-header">
326        <span class="modal-title">Advanced Settings</span>
327        <button class="modal-close">×</button>
328      </div>
329      <div class="modal-body">
330        <div class="settings-section">
331          <h4>Notifications</h4>
332          <div class="setting-row">
333            <div>
334              <div class="setting-label">Email notifications</div>
335              <div class="setting-desc">Receive updates via email</div>
336            </div>
337            <div class="toggle on"></div>
338          </div>
339          <div class="setting-row">
340            <div>
341              <div class="setting-label">Push notifications</div>
342              <div class="setting-desc">Browser push alerts</div>
343            </div>
344            <div class="toggle"></div>
345          </div>
346          <div class="setting-row">
347            <div>
348              <div class="setting-label">Notification frequency</div>
349            </div>
350            <select class="select-input">
351              <option>Instant</option>
352              <option>Daily digest</option>
353              <option>Weekly</option>
354            </select>
355          </div>
356        </div>
357
358        <div class="settings-section">
359          <h4>Privacy & Security</h4>
360          <div class="setting-row">
361            <div>
362              <div class="setting-label">Two-factor authentication</div>
363              <div class="setting-desc">Add extra security</div>
364            </div>
365            <div class="toggle on"></div>
366          </div>
367          <div class="setting-row">
368            <div>
369              <div class="setting-label">Session timeout</div>
370            </div>
371            <select class="select-input">
372              <option>30 minutes</option>
373              <option>1 hour</option>
374              <option>4 hours</option>
375            </select>
376          </div>
377          <div class="setting-row">
378            <div>
379              <div class="setting-label">Activity logging</div>
380              <div class="setting-desc">Track account activity</div>
381            </div>
382            <div class="toggle on"></div>
383          </div>
384        </div>
385
386        <div class="settings-section">
387          <h4>Data & Export</h4>
388          <div class="setting-row">
389            <div>
390              <div class="setting-label">Auto-backup</div>
391              <div class="setting-desc">Automatic data backups</div>
392            </div>
393            <div class="toggle"></div>
394          </div>
395          <div class="setting-row">
396            <div>
397              <div class="setting-label">Export format</div>
398            </div>
399            <select class="select-input">
400              <option>CSV</option>
401              <option>JSON</option>
402              <option>Excel</option>
403            </select>
404          </div>
405        </div>
406
407        <div class="settings-section">
408          <h4>API Settings</h4>
409          <div class="setting-row">
410            <div>
411              <div class="setting-label">API Key</div>
412            </div>
413            <input type="text" class="text-input" value="sk-xxxxx-xxxxx" readonly>
414          </div>
415          <div class="setting-row">
416            <div>
417              <div class="setting-label">Rate limit</div>
418            </div>
419            <select class="select-input">
420              <option>100/min</option>
421              <option>500/min</option>
422              <option>1000/min</option>
423            </select>
424          </div>
425        </div>
426      </div>
427      <div class="modal-footer">
428        <button class="btn btn-secondary">Cancel</button>
429        <button class="btn btn-primary">Save Changes</button>
430      </div>
431    </div>
432
433  </div>
434<script src="/js/detect-antipatterns-browser.js"></script>
435</body>
436</html>