slack status without the slack status.zzstoatzz.io/
quickslice

feat: add HTML/JS linting and bug report button

- Add HTML syntax checking with xmllint to pre-commit hooks
- Add JavaScript syntax validation with node -c
- Add JSON validation to catch syntax errors before deployment
- Add floating bug report button on all pages
- Bug button collects context (page, theme, viewport) and opens GitHub issue
- Responsive design for mobile devices

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

Changed files
+151 -1
templates
+16 -1
.pre-commit-config.yaml
··· 18 18 entry: cargo clippy -- -D warnings 19 19 language: system 20 20 types: [rust] 21 - pass_filenames: false 21 + pass_filenames: false 22 + - id: check-html-syntax 23 + name: Check HTML syntax 24 + entry: bash -c 'for file in "$@"; do if ! xmllint --html --noout "$file" 2>/dev/null; then echo "HTML syntax error in $file"; exit 1; fi; done' -- 25 + language: system 26 + files: \.html$ 27 + - id: check-js-syntax 28 + name: Check JavaScript syntax 29 + entry: bash -c 'for file in "$@"; do if ! node -c "$file" 2>/dev/null; then echo "JavaScript syntax error in $file"; exit 1; fi; done' -- 30 + language: system 31 + files: \.js$ 32 + - id: check-json 33 + name: Check JSON 34 + entry: bash -c 'for file in "$@"; do if ! python3 -m json.tool "$file" > /dev/null 2>&1; then echo "JSON syntax error in $file"; exit 1; fi; done' -- 35 + language: system 36 + files: \.json$
+135
templates/base.html
··· 49 49 document.documentElement.style.setProperty('--accent', savedAccent); 50 50 })(); 51 51 </script> 52 + 53 + <style> 54 + /* Bug Report Button Styles */ 55 + .bug-report-button { 56 + position: fixed; 57 + bottom: 20px; 58 + right: 20px; 59 + width: 48px; 60 + height: 48px; 61 + background: var(--accent, #1DA1F2); 62 + border: none; 63 + border-radius: 50%; 64 + cursor: pointer; 65 + display: flex; 66 + align-items: center; 67 + justify-content: center; 68 + box-shadow: 0 2px 8px rgba(0,0,0,0.2); 69 + transition: all 0.3s ease; 70 + z-index: 9999; 71 + } 72 + 73 + .bug-report-button:hover { 74 + transform: scale(1.1); 75 + box-shadow: 0 4px 12px rgba(0,0,0,0.3); 76 + } 77 + 78 + .bug-report-button svg { 79 + width: 24px; 80 + height: 24px; 81 + fill: white; 82 + } 83 + 84 + .bug-report-tooltip { 85 + position: absolute; 86 + bottom: 60px; 87 + right: 0; 88 + background: var(--bg-secondary, #1a1a1a); 89 + color: var(--text-primary, #ffffff); 90 + border: 1px solid var(--border-color, #2a2a2a); 91 + border-radius: 8px; 92 + padding: 8px 12px; 93 + font-size: 14px; 94 + white-space: nowrap; 95 + opacity: 0; 96 + pointer-events: none; 97 + transition: opacity 0.3s ease; 98 + } 99 + 100 + .bug-report-button:hover .bug-report-tooltip { 101 + opacity: 1; 102 + } 103 + 104 + @media (max-width: 640px) { 105 + .bug-report-button { 106 + width: 40px; 107 + height: 40px; 108 + bottom: 15px; 109 + right: 15px; 110 + } 111 + 112 + .bug-report-button svg { 113 + width: 20px; 114 + height: 20px; 115 + } 116 + } 117 + </style> 52 118 </head> 53 119 <body> 54 120 {% block content %}{% endblock %} 121 + 122 + <!-- Bug Report Button --> 123 + <button class="bug-report-button" id="bug-report-button" aria-label="Report a bug"> 124 + <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> 125 + <path d="M20 8h-2.81a5.985 5.985 0 0 0-1.82-1.96L17 4.41 15.59 3l-2.17 2.17C12.96 5.06 12.49 5 12 5c-.49 0-.96.06-1.41.17L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8zm-6 8h-4v-2h4v2zm0-4h-4v-2h4v2z"/> 126 + </svg> 127 + <span class="bug-report-tooltip">report a bug</span> 128 + </button> 129 + 130 + <script> 131 + // Bug Report Button Handler 132 + document.addEventListener('DOMContentLoaded', function() { 133 + const bugButton = document.getElementById('bug-report-button'); 134 + if (bugButton) { 135 + bugButton.addEventListener('click', function() { 136 + // Gather context information 137 + const context = { 138 + page: window.location.pathname, 139 + url: window.location.href, 140 + userAgent: navigator.userAgent, 141 + screenResolution: `${window.screen.width}x${window.screen.height}`, 142 + viewportSize: `${window.innerWidth}x${window.innerHeight}`, 143 + theme: document.documentElement.getAttribute('data-theme') || 'light', 144 + timestamp: new Date().toISOString() 145 + }; 146 + 147 + // Build issue title and body 148 + const title = '[Bug Report] Issue on ' + context.page; 149 + const body = `## Bug Description 150 + <!-- Please describe the bug you encountered --> 151 + 152 + 153 + ## Steps to Reproduce 154 + <!-- Please list the steps to reproduce the bug --> 155 + 1. 156 + 2. 157 + 3. 158 + 159 + ## Expected Behavior 160 + <!-- What did you expect to happen? --> 161 + 162 + 163 + ## Actual Behavior 164 + <!-- What actually happened? --> 165 + 166 + 167 + ## Context Information 168 + - **Page**: ${context.page} 169 + - **URL**: ${context.url} 170 + - **Timestamp**: ${context.timestamp} 171 + - **Theme**: ${context.theme} 172 + - **Viewport**: ${context.viewportSize} 173 + - **Screen**: ${context.screenResolution} 174 + - **User Agent**: ${context.userAgent} 175 + 176 + ## Additional Information 177 + <!-- Any additional information, screenshots, etc. --> 178 + `; 179 + 180 + // Create GitHub issue URL 181 + const githubRepo = 'https://github.com/zzstoatzz/status.zzstoatzz.io'; 182 + const issueUrl = `${githubRepo}/issues/new?title=${encodeURIComponent(title)}&body=${encodeURIComponent(body)}`; 183 + 184 + // Open in new tab 185 + window.open(issueUrl, '_blank'); 186 + }); 187 + } 188 + }); 189 + </script> 55 190 </body> 56 191 </html>