Files
Brenda Wallace ca7fd81439 Tidy/login signup (#4958)
* Add authentication dialogs for sign in and sign up

- Implemented AuthDialog component to manage sign in and sign up modals.
- Created SignInModal and SignUpModal components for handling respective authentication processes.
- Added AuthFields component for reusable form fields and error handling.
- Updated various views to utilize the new authentication dialogs instead of traditional links.
- Enhanced user experience by allowing sign in and sign up actions to occur without full page reloads.
- Added feature specs for testing the functionality of the new dialogs.

* Refactor modals and input fields for improved accessibility and styling; adjust button sizes and text formatting

* Refactor authentication forms and modals for improved usability and accessibility; integrate reCAPTCHA handling and enhance error messaging

* Refactor SignUpModal layout for improved responsiveness and accessibility; organize fields into rows and enhance styling

* Refactor session view spec to streamline field checks; remove redundant test and retain essential content expectations
2026-10-17 09:26:39 +10:30

43 lines
1.4 KiB
JavaScript

import {useEffect, useRef} from 'react';
const SRC = 'https://www.google.com/recaptcha/api.js?render=explicit';
// Loads Google's script once, then calls back when `grecaptcha.render` is there.
function whenReady(callback) {
if (window.grecaptcha && window.grecaptcha.render) {
callback();
return;
}
let script = document.querySelector(`script[src="${SRC}"]`);
if (!script) {
script = document.createElement('script');
script.src = SRC;
script.async = true;
document.head.appendChild(script);
}
script.addEventListener('load', () => window.grecaptcha.ready(callback));
}
// A reCAPTCHA checkbox drawn into the element `ref` is put on, when there is a
// site key. `response()` is what to send with the form (nothing without a key),
// and `reset()` clears it after a failed attempt.
export default function useRecaptcha(siteKey) {
const ref = useRef(null);
const widgetId = useRef(null);
useEffect(() => {
if (!siteKey || !ref.current) return;
whenReady(() => {
if (ref.current && widgetId.current === null) {
widgetId.current = window.grecaptcha.render(ref.current, {sitekey: siteKey});
}
});
}, [siteKey]);
return {
ref,
response: () => (widgetId.current === null ? undefined : window.grecaptcha.getResponse(widgetId.current)),
reset: () => { if (widgetId.current !== null) window.grecaptcha.reset(widgetId.current); },
};
}