| 1 |
import {createRoot} from '@wordpress/element'; |
| 2 |
import getDefaultValuesFromSections from './utilities/getDefaultValuesFromSections'; |
| 3 |
import Form from './form/Form'; |
| 4 |
import {DonationFormStateProvider} from './store'; |
| 5 |
import getWindowData from './utilities/getWindowData'; |
| 6 |
import prepareFormData from './utilities/PrepareFormData'; |
| 7 |
import getJoiRulesForForm from './utilities/ConvertFieldAPIRulesToJoi'; |
| 8 |
import Header from './form/Header'; |
| 9 |
import mountWindowData from '@givewp/forms/app/utilities/mountWindowData'; |
| 10 |
import {withTemplateWrapper} from '@givewp/forms/app/templates'; |
| 11 |
import DonationFormErrorBoundary from '@givewp/forms/app/errors/boundaries/DonationFormErrorBoundary'; |
| 12 |
import MultiStepForm from '@givewp/forms/app/form/MultiStepForm'; |
| 13 |
import getDonationFormNodeSettings from '@givewp/forms/app/utilities/getDonationFormNodeSettings'; |
| 14 |
import {DonationFormSettingsProvider} from '@givewp/forms/app/store/form-settings'; |
| 15 |
import useDonationFormPubSub from '@givewp/forms/app/utilities/useDonationFormPubSub'; |
| 16 |
import {useEffect, useState} from 'react'; |
| 17 |
import type {Form as DonationForm} from '@givewp/forms/types'; |
| 18 |
|
| 19 |
const formTemplates = window.givewp.form.templates; |
| 20 |
const GoalAchievedTemplate = withTemplateWrapper(formTemplates.layouts.goalAchieved); |
| 21 |
|
| 22 |
/** |
| 23 |
* Get data from the server |
| 24 |
*/ |
| 25 |
const {form, previewMode} = getWindowData(); |
| 26 |
const donationFormNodeSettings = getDonationFormNodeSettings(form); |
| 27 |
|
| 28 |
prepareFormData(form); |
| 29 |
|
| 30 |
mountWindowData(); |
| 31 |
|
| 32 |
/** |
| 33 |
* Prepare default values for form |
| 34 |
*/ |
| 35 |
const defaultValues = getDefaultValuesFromSections(form.nodes); |
| 36 |
|
| 37 |
const schema = getJoiRulesForForm(form); |
| 38 |
|
| 39 |
const initialState = { |
| 40 |
defaultValues, |
| 41 |
gateways: window.givewp.gateways.getAll(), |
| 42 |
validationSchema: schema, |
| 43 |
}; |
| 44 |
|
| 45 |
/** |
| 46 |
* @since 3.0.0 |
| 47 |
*/ |
| 48 |
function App({form}: { form: DonationForm }) { |
| 49 |
if (form.goal.isAchieved) { |
| 50 |
return ( |
| 51 |
<DonationFormErrorBoundary> |
| 52 |
<GoalAchievedTemplate goalAchievedMessage={form.settings.goalAchievedMessage} /> |
| 53 |
</DonationFormErrorBoundary> |
| 54 |
); |
| 55 |
} |
| 56 |
|
| 57 |
if (form.design?.isMultiStep) { |
| 58 |
return ( |
| 59 |
<DonationFormSettingsProvider value={{...form.settings, ...donationFormNodeSettings}}> |
| 60 |
<DonationFormStateProvider initialState={initialState}> |
| 61 |
{!form.design?.includeHeaderInMultiStep && form.settings.showHeader && <Header form={form} />} |
| 62 |
<MultiStepForm form={form} /> |
| 63 |
</DonationFormStateProvider> |
| 64 |
</DonationFormSettingsProvider> |
| 65 |
); |
| 66 |
} |
| 67 |
|
| 68 |
return ( |
| 69 |
<DonationFormSettingsProvider value={{...form.settings, ...donationFormNodeSettings}}> |
| 70 |
<DonationFormStateProvider initialState={initialState}> |
| 71 |
{form.settings?.showHeader && <Header form={form} />} |
| 72 |
<Form defaultValues={defaultValues} sections={form.nodes} validationSchema={schema} /> |
| 73 |
</DonationFormStateProvider> |
| 74 |
</DonationFormSettingsProvider> |
| 75 |
); |
| 76 |
} |
| 77 |
|
| 78 |
/** |
| 79 |
* @since 3.1.0 |
| 80 |
*/ |
| 81 |
function AppPreview() { |
| 82 |
const { |
| 83 |
subscribeToGoal, |
| 84 |
subscribeToGoalSource, |
| 85 |
subscribeToColors, |
| 86 |
subscribeToSettings, |
| 87 |
subscribeToCss, |
| 88 |
unsubscribeAll |
| 89 |
} = useDonationFormPubSub(); |
| 90 |
|
| 91 |
const [formState, setFormState] = useState<DonationForm>(form); |
| 92 |
|
| 93 |
useEffect(() => { |
| 94 |
subscribeToSettings((settings) => { |
| 95 |
setFormState((prevState) => { |
| 96 |
return { |
| 97 |
...prevState, |
| 98 |
settings: { |
| 99 |
...prevState.settings, |
| 100 |
...settings, |
| 101 |
}, |
| 102 |
}; |
| 103 |
}); |
| 104 |
}); |
| 105 |
|
| 106 |
subscribeToGoal((goal) => { |
| 107 |
setFormState((prevState) => { |
| 108 |
return { |
| 109 |
...prevState, |
| 110 |
goal: { |
| 111 |
...prevState.goal, |
| 112 |
...goal, |
| 113 |
}, |
| 114 |
}; |
| 115 |
}); |
| 116 |
}); |
| 117 |
|
| 118 |
subscribeToGoalSource((goalSource) => { |
| 119 |
setFormState((prevState) => { |
| 120 |
return { |
| 121 |
...prevState, |
| 122 |
goalSource, |
| 123 |
}; |
| 124 |
}); |
| 125 |
}); |
| 126 |
|
| 127 |
subscribeToColors((data) => { |
| 128 |
if (data['primaryColor']) { |
| 129 |
root.style.setProperty('--givewp-primary-color', data['primaryColor']); |
| 130 |
} |
| 131 |
|
| 132 |
if (data['secondaryColor']) { |
| 133 |
root.style.setProperty('--givewp-secondary-color', data['secondaryColor']); |
| 134 |
} |
| 135 |
}); |
| 136 |
|
| 137 |
subscribeToCss(({customCss}) => { |
| 138 |
let cssRules = ''; |
| 139 |
const stylesheet = new CSSStyleSheet(); |
| 140 |
|
| 141 |
stylesheet.replaceSync(customCss); |
| 142 |
|
| 143 |
for (let i = 0; i < stylesheet.cssRules.length; i++) { |
| 144 |
cssRules += stylesheet.cssRules[i].cssText + '\n'; |
| 145 |
} |
| 146 |
|
| 147 |
style.innerText = cssRules; |
| 148 |
}); |
| 149 |
|
| 150 |
return () => unsubscribeAll(); |
| 151 |
}, []); |
| 152 |
|
| 153 |
return <App form={formState} />; |
| 154 |
} |
| 155 |
|
| 156 |
const root = document.getElementById('root-givewp-donation-form'); |
| 157 |
const style = document.getElementById('root-givewp-donation-form-style'); |
| 158 |
|
| 159 |
createRoot(root).render(previewMode ? <AppPreview /> : <App form={form} />); |
| 160 |
|