const CC_FORM_CONTAINER_ID = 'captain_compliance_form_container'; const CC_FORM_ID = 'captain_compliance_form'; const CC_SERVER_URL = 'https://cc-platform-api-prod.fly.dev'; const CC_ACCESS_TOKEN = document.currentScript.getAttribute('access-token'); const CC_ELEMENT_TYPES = { TEXT: { element: ({ code }) => ` `, }, EMAIL: { element: ({ code }) => ` `, }, PHONE: { element: ({ code }) => ` `, }, NUMBER: { element: ({ code }) => ` `, }, TEXTAREA: { element: ({ code }) => ` `, }, FILE: { element: ({ code }) => ` `, }, DROPDOWN: { element: ({ code, metadata }) => ` `, }, }; function addStyles(styles) { const themeColor = styles.theme; const fontColor = styles.fontColor; const borderRadius = styles.borderRadius; const borderWidth = styles.borderWidth; const someStyle = ` `; document.head.insertAdjacentHTML('beforeend', someStyle); } async function loadFormData(accessToken) { const response = await fetch( `${CC_SERVER_URL}/requestForm/form-token?access-token=${accessToken}`, ); return await response.json(); } function handleSubmitButton() { const submitButton = document.getElementById('cc-form-submit-button'); submitButton.disabled = true; submitButton.value = 'Submitting...'; submitButton.classList.add('cc-default-btn-disabled'); return () => { submitButton.disabled = false; submitButton.value = 'Submit'; submitButton.classList.remove('cc-default-btn-disabled'); }; } function sendFormRequest(requestFormId, data, cb) { fetch(`${CC_SERVER_URL}/requestFormSubmit`, { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify({ data, requestFormId }), }) .then((response) => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then((data) => { console.log('API response:', data); cb(); }) .catch((error) => { console.error('There was a problem with the API request:', error.message); cb(); }); } function createForm({ fields, description, id }) { const formContainer = document.getElementById(CC_FORM_CONTAINER_ID); if (formContainer) { const fieldsToRender = fields.filter(({ disabled }) => !disabled); const inputs = fieldsToRender .map(({ label, code, type, metadata }) => { const component = CC_ELEMENT_TYPES[type]; return `
${component.element({ code, metadata })}
`; }) .join(' '); const form = document.createElement('form'); form.setAttribute('id', CC_FORM_ID); form.classList.add('cc-form-container'); form.innerHTML += `

Data Subject Access Request Form

${description ? `

${description}

` : ''}
${inputs} `; formContainer.appendChild(form); form.addEventListener('submit', (event) => { let isValid = true; const formData = {}; fieldsToRender.forEach(({ code, label, type }) => { const input = document.getElementById(code); const error = document.getElementById(`${code}Error`); if (type === 'EMAIL') { const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailPattern.test(input.value)) { error.style.display = 'block'; error.textContent = 'Please enter a valid email address'; isValid = false; } else { formData[code] = { type, code, label, value: input.value, }; error.style.display = 'none'; error.textContent = ''; } } else if (type === 'PHONE') { const phonePattern = /^\d{10}$/; // Assuming a 10-digit phone number if (!phonePattern.test(input.value)) { error.style.display = 'block'; error.textContent = 'Please enter a valid phone number'; isValid = false; } else { formData[code] = { type, code, label, value: input.value, }; error.style.display = 'none'; error.textContent = ''; } } else if (type === 'NUMBER') { const age = parseInt(input.value); if (isNaN(age) || age <= 0) { error.style.display = 'block'; error.textContent = `Please enter a valid ${label.toLowerCase()}`; isValid = false; } else { formData[code] = { type, code, label, value: input.value, }; error.style.display = 'none'; error.textContent = ''; } } else { if (input.value.trim() === '') { error.style.display = 'block'; error.textContent = `${ label.charAt(0).toUpperCase() + label.slice(1) } is required`; isValid = false; } else { formData[code] = { type, code, label, value: input.value, }; error.style.display = 'none'; error.textContent = ''; } } }); if (!isValid) { return event.preventDefault(); } if (isValid) { event.preventDefault(); const done = handleSubmitButton(); sendFormRequest(id, formData, () => { form.reset(); done(); }); console.log('SUCCESS'); } }); observer.disconnect(); } } const observer = new MutationObserver(handleMutations); async function handleMutations() { const formContainer = document.getElementById(CC_FORM_CONTAINER_ID); const formAdded = document.getElementById(CC_FORM_ID); if (!formAdded && formContainer) { const data = await loadFormData(CC_ACCESS_TOKEN); if (data) { createForm(data); addStyles(data.styles); observer.disconnect(); } } } observer.observe(document.documentElement, { childList: true, subtree: true });