Till now, I was using Google's reCaptcha challenge for spam protection.
But now I want to switch to Cloudflare's Turnstile.
Here is my old JavaScript code for reCaptcha handling:
/**
     * Contact form submission
     */
    let forms = document.querySelectorAll('.php-email-form');
    let status = document.querySelector('#status');

    forms.forEach( function(e) {
        e.addEventListener('submit', function(event) {
            event.preventDefault();

            let thisForm = this;

            let action = thisForm.getAttribute('action');
            let recaptcha = thisForm.getAttribute('data-recaptcha-site-key');
            
            if (!action) {
                displayError(thisForm, 'The form action property is not set!')
                return;
            }
            status.querySelector('.loading').classList.add('d-flex');
            status.querySelector('.error-message').classList.remove('d-block');
            status.querySelector('.sent-message').classList.remove('d-block');

            let formData = new FormData( thisForm );

            if (recaptcha) {
                if(typeof grecaptcha !== "undefined" ) {
                    grecaptcha.ready(function() {
                        try {
                            grecaptcha.execute(recaptcha, {action: 'php_email_form_submit'})
                            .then(token => {
                                formData.set('recaptcha-response', token);
                                php_email_form_submit(thisForm, action, formData);
                            })
                        } catch(error) {
                            displayError(thisForm, error)
                        }
                    });
                } else {
                    displayError(thisForm, 'The reCaptcha javascript API url is not loaded!')
                }
            } else {
                php_email_form_submit(thisForm, action, formData);
            }
        });
    });

    function php_email_form_submit(thisForm, action, formData) {
        fetch(action, {
            method: 'POST',
            body: formData,
            headers: {'X-Requested-With': 'XMLHttpRequest'}
        })
        .then(response => {
            if( response.ok ) {
                return response.text()
            } else {
                throw new Error(`${response.status} ${response.statusText} ${response.url}`); 
            }
        })
        .then(data => {
            status.querySelector('.loading').classList.remove('d-flex');
            if (data.trim() == 'OK') {
                status.querySelector('.sent-message').classList.add('d-block');
                thisForm.reset(); 
            } else {
                throw new Error(data ? data : 'Form submission failed and no error message returned from: ' + action); 
            }
        })
        .catch((error) => {
            displayError(thisForm, error);
        });
    }

    function displayError(thisForm, error) {
        status.querySelector('.loading').classList.remove('d-flex');
        status.querySelector('.error-message').innerHTML = error;
        status.querySelector('.error-message').classList.add('d-block');
    }

I want you to write similar JavaScript code for Cloudflare's Turnstile, replacing Google's reCaptcha.