fix(web): address CodeRabbit review feedback

Fixes issues identified in PR #3076:

1. mock-server.mjs: Fix HTTP line ending escape sequence
   - Changed `\\r\\n\\r\\n` to `\r\n\r\n` for proper HTTP CRLF terminators

2. App.tsx: Add accessibility attributes to pairing form
   - Added aria-label, aria-invalid, aria-describedby to input
   - Added id="pairing-error" and role="alert" to error message

3. Header.tsx: Add accessible name to logout button
   - Added aria-label for screen readers on mobile (icon-only) view

4. Layout.tsx: Guard localStorage access with try-catch
   - Prevents runtime errors when storage is blocked/unavailable

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
argenis de la rosa 2026-03-09 16:43:08 -04:00
parent 3f5c57634b
commit c280ae5045
4 changed files with 16 additions and 4 deletions

View File

@ -338,7 +338,7 @@ wsServer.on('connection', (socket) => {
server.on('upgrade', (req, socket, head) => {
const url = new URL(req.url, `http://${req.headers.host}`);
if (url.pathname !== '/ws/chat' || !isAuthorized(req)) {
socket.write('HTTP/1.1 401 Unauthorized\\r\\n\\r\\n');
socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n');
socket.destroy();
return;
}

View File

@ -87,6 +87,9 @@ function PairingDialog({
<form onSubmit={handleSubmit}>
<input
type="text"
aria-label={translate('auth.enter_code')}
aria-invalid={Boolean(error)}
aria-describedby={error ? 'pairing-error' : undefined}
value={code}
onChange={(e) => setCode(e.target.value)}
placeholder={translate('auth.code_placeholder')}
@ -95,7 +98,7 @@ function PairingDialog({
autoFocus
/>
{error && (
<p className="mb-4 text-center text-sm text-rose-300">{error}</p>
<p id="pairing-error" role="alert" className="mb-4 text-center text-sm text-rose-300">{error}</p>
)}
<button
type="submit"

View File

@ -67,6 +67,7 @@ export default function Header({ onToggleSidebar }: HeaderProps) {
<button
type="button"
onClick={logout}
aria-label={t('auth.logout')}
className="flex items-center gap-1 rounded-lg border border-[#2b4f97] bg-[#091937]/75 px-2.5 py-1.5 text-xs text-[#c4d8ff] transition hover:border-[#4f83ff] hover:text-white sm:gap-1.5 sm:px-3 sm:text-sm"
>
<LogOut className="h-4 w-4" />

View File

@ -11,14 +11,22 @@ export default function Layout() {
if (typeof window === 'undefined') {
return false;
}
return window.localStorage.getItem(SIDEBAR_COLLAPSED_KEY) === '1';
try {
return window.localStorage.getItem(SIDEBAR_COLLAPSED_KEY) === '1';
} catch {
return false;
}
});
const toggleSidebarCollapsed = () => {
setSidebarCollapsed((prev) => {
const next = !prev;
if (typeof window !== 'undefined') {
window.localStorage.setItem(SIDEBAR_COLLAPSED_KEY, next ? '1' : '0');
try {
window.localStorage.setItem(SIDEBAR_COLLAPSED_KEY, next ? '1' : '0');
} catch {
// Storage unavailable, ignore
}
}
return next;
});