From 8975b3bb9f68fd3ef1c70d143b197b99bcfe4992 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 30 Jun 2026 05:18:26 +0000 Subject: [PATCH] Replace native window.confirm with accessible state-based soft confirmation Replaced the blocking, unstyled native `window.confirm()` in SessionConsole.tsx with an inline, state-based soft confirmation to improve UX. Added 'Cancel' and 'Confirm End' buttons, along with a `role="status"` warning message to maintain Section 508 compliance and ensure screen readers announce the action's consequences. Co-authored-by: Sczitzo <46541128+Sczitzo@users.noreply.github.com> --- .Jules/palette.md | 4 ++ src/components/facilitator/SessionConsole.tsx | 45 ++++++++++++++++--- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/.Jules/palette.md b/.Jules/palette.md index 2802bd6..b34567b 100644 --- a/.Jules/palette.md +++ b/.Jules/palette.md @@ -15,3 +15,7 @@ ## 2026-10-24 - Form Success State Feedback **Learning:** Temporarily disabling the submit button and changing its state to a success message without wiping the form inputs asynchronously prevents data loss while maintaining clear feedback for the user on successful submissions. **Action:** For successful form submissions, temporarily (e.g., 2s) disable the submit button, change its text to a success message, and reset the form inputs immediately rather than inside the timeout. + +## 2026-10-24 - Accessible Soft Confirmations +**Learning:** Native `window.confirm()` dialogs are unstyled, blocking, and not always perfectly accessible. Replacing them with state-based soft confirmations provides a better UX, but requires explicit visual structure (a side-by-side 'Cancel' button) and semantic ARIA announcements to remain safe and accessible. +**Action:** Always include a 'Cancel' button and a dynamic `role="status"` warning text when replacing native confirmation dialogs to prevent users from being trapped and to ensure screen readers announce the consequences. diff --git a/src/components/facilitator/SessionConsole.tsx b/src/components/facilitator/SessionConsole.tsx index 252dde2..024c419 100644 --- a/src/components/facilitator/SessionConsole.tsx +++ b/src/components/facilitator/SessionConsole.tsx @@ -1,5 +1,6 @@ 'use client'; +import { useState } from 'react'; import { Socket } from 'socket.io-client'; import type { SessionStatePayload } from '@/types/websocket'; @@ -10,6 +11,8 @@ interface SessionConsoleProps { } export function SessionConsole({ sessionId, sessionState, socket }: SessionConsoleProps) { + const [showEndConfirm, setShowEndConfirm] = useState(false); + const handleStartSession = () => { socket.emit('facilitator', { type: 'startSession', @@ -25,14 +28,20 @@ export function SessionConsole({ sessionId, sessionState, socket }: SessionConso }; const handleEndSession = () => { - if (confirm('Are you sure you want to end this session? This will generate the session summary.')) { + if (showEndConfirm) { socket.emit('facilitator', { type: 'endSession', payload: { sessionId }, }); + } else { + setShowEndConfirm(true); } }; + const handleCancelEnd = () => { + setShowEndConfirm(false); + }; + if (!sessionState) { return (
@@ -84,12 +93,34 @@ export function SessionConsole({ sessionId, sessionState, socket }: SessionConso ) : null} {sessionState.status !== 'ENDED' && ( - + showEndConfirm ? ( +
+
+ + +
+
+ Are you sure you want to end this session? This will generate the session summary. +
+
+ ) : ( + + ) )}