From c02776e5b9b9f5ae1c40083585104ceee865b897 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sat, 20 Jun 2026 05:34:36 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20Replace=20native=20co?= =?UTF-8?q?nfirm=20dialog=20with=20accessible=20soft=20confirmation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Removed blocking `window.confirm` from `handleEndSession`. * Implemented state-based soft confirmation with explicit "Confirm End" and "Cancel" buttons. * Preserved the warning text ("This will generate the session summary") and added `role="status"` for screen reader announcements. * Documented learning in `.Jules/palette.md`. Co-authored-by: Sczitzo <46541128+Sczitzo@users.noreply.github.com> --- .Jules/palette.md | 4 ++ src/components/facilitator/SessionConsole.tsx | 53 +++++++++++++++---- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/.Jules/palette.md b/.Jules/palette.md index 2802bd6..b47479d 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-25 - Soft Confirmation Pattern +**Learning:** Native `window.confirm()` dialogs create blocking, inaccessible experiences and lack styling options. State-based soft confirmations require explicit 'Cancel' options to prevent trapping users and need `role="status"` to ensure warning text is announced to screen readers. +**Action:** Replace `window.confirm()` with state-based UI containing confirm/cancel buttons and dynamic warning text with `role="status"`. diff --git a/src/components/facilitator/SessionConsole.tsx b/src/components/facilitator/SessionConsole.tsx index 252dde2..6f120c8 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,12 +28,16 @@ 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.')) { - socket.emit('facilitator', { - type: 'endSession', - payload: { sessionId }, - }); + if (!showEndConfirm) { + setShowEndConfirm(true); + return; } + + socket.emit('facilitator', { + type: 'endSession', + payload: { sessionId }, + }); + setShowEndConfirm(false); }; if (!sessionState) { @@ -84,12 +91,36 @@ 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. +
+
+ )} +
)}