import { useCallback, useEffect, useRef, useState } from "react";
import useResponsive from "src/hooks/useResponsive";
import {LocalizationProvider, DatePicker, TimePicker} from '@mui/x-date-pickers'
import {FormControlLabel, Checkbox, RadioGroup, Radio} from '@mui/material'
import { useSetRecoilState } from "recoil";
import { captchaAtom } from "src/atoms/captcha";
import { GoogleReCaptchaProvider, GoogleReCaptcha } from 'react-google-recaptcha-v3';
import { useClickAway } from "use-click-away";
import PhoneInput from 'react-phone-input-2'
import globalSettings from "src/constants/globalSettings_backup";
import PlacesAutocomplete, {geocodeByAddress} from 'react-places-autocomplete';
import { AddListItemButton, AddressContainer, AddressOption, AddressOptions, CheckBoxesContainer, CheckBoxesWrapper, ChipStyle, ChipText, ChipX, ConsetContainer, Container, FileInput, HTMLBlockStyle, InputStyle, ListContainer, ListInput, ListInputContainer, ListItem, ListItemText, ListItemsContainer, MultiSelectedOption, Option, PageNavigation, PageNavigationContainer, PhoneContainer, RemoveListItemButton, Required, RoundedInputContainer, RoundedInputStyle, RoundedOption, RoundedSelectOptionsStyle, RoundedSelectStyle, RoundedSelectStyleProps, RoundedSelectedOption, SectionLine, SelectArrow, SelectContainer, SelectStyle, SelectedOption, TextareaStyle, Title, UploadButton, UploadIcon, UploadText } from "./styles";
import { ReactComponent as SearchIcon } from "../../assets/icons/search.svg";
import { InputProps } from "../../types/input";
import 'react-phone-input-2/lib/style.css'
type TextFieldProps = {
title: string;
placeholder: string;
required?: boolean;
type?: 'text' | 'number' | 'hidden';
defaultValue?: string;
size?: string;
onChange?: (data : any) => void;
errorMessage?: string;
layoutGridColumnSpan?: string;
}
export function TextField({title, placeholder, required, type = 'text', defaultValue, size, onChange, errorMessage, layoutGridColumnSpan} : TextFieldProps){
return (
<Container sx={layoutGridColumnSpan ? {gridColumn: `span ${layoutGridColumnSpan}`} : {}}>
<InputStyle value={defaultValue} type={type} placeholder={errorMessage || placeholder} placeholderOpacity={errorMessage ? 1 : 0.5} placeholderColor={errorMessage ? 'red' : globalSettings.Colors.bodyBlack} required={required} onChange={onChange} />
</Container>
)
}
type RoundedTextFieldProps = {
placeholder: string;
icon?: React.ReactNode;
size?: string;
onChange: (e:any) => void;
width?: string;
};
export function RoundedTextField({placeholder, icon, size, onChange, width} : RoundedTextFieldProps){
return (
<RoundedInputContainer minWidth={width} width={width} >
{icon || <SearchIcon />}
<RoundedInputStyle placeholder={placeholder} onChange={(e)=>onChange(e)} />
</RoundedInputContainer>
)
}
type SelectProps = {
title: string;
options: {
text: string;
value: string;
}[];
required?: boolean;
size?: string;
onSelect?: (item:string) => void;
onChange?: (data : any) => void;
errorMessage?: string;
layoutGridColumnSpan?: string;
}
export function SelectDropDown ({title, options, required, size, onSelect, onChange, errorMessage, layoutGridColumnSpan} : SelectProps) {
const [selectedOption, setSelectedOption] = useState<string | null>(null)
const [showSelect, setShowSelect] = useState<boolean>(false)
const showSelectDropDown = () => {
setShowSelect(true)
}
const selectOption = (item : string) => {
setSelectedOption(item)
setShowSelect(false)
if(onSelect){
onSelect(item)
}
if(onChange){
onChange({target: {value: item}})
}
}
const dropDownRef = useRef(null)
useClickAway(dropDownRef, () => {
setShowSelect(false)
})
return (
<Container sx={layoutGridColumnSpan ? {gridColumn: `span ${layoutGridColumnSpan}`} : {}}>
<Title>{title}{required?<Required>*</Required>:null}</Title>
<SelectContainer onMouseDown={showSelectDropDown} ref={dropDownRef}>
<SelectArrow selected={showSelect} />
<SelectedOption>{selectedOption || <div style={errorMessage ? {opacity: 1, color: 'red'} : {opacity: 0.5}}>{errorMessage || 'Please Select'}</div>}</SelectedOption>
{showSelect?
<SelectStyle defaultValue="">
{options.map((item, key) => (
<Option key={key} onClick={()=>selectOption(item.text)} selected={item.text===selectedOption}>{item.text}</Option>
))}
</SelectStyle>
:null}
</SelectContainer>
</Container>
)
}
type RoundedSelectProps = RoundedSelectStyleProps & {
firstItem?: {
title: string;
onClick: () => void;
};
placeholder?: string;
options: {
title: string;
id: any;
}[];
optionBackgroundColor?: string;
optionTextColor?: string;
size?: string;
onSelect?: (item:any) => void;
selectwidth?: string;
width?: string;
}
export function RoundedSelect ({selectwidth, firstItem, options, placeholder, activetextcolor, bordercolor, arrowcolor, optionBackgroundColor, optionTextColor, size, onSelect, width} : RoundedSelectProps) {
const [selectedOption, setSelectedOption] = useState<{title: string, id: any} | null>(null)
const [showSelect, setShowSelect] = useState<boolean>(false)
const showSelectDropDown = () => {
setShowSelect(true)
}
const selectOption = (item : {title: string; id: any}) => {
setSelectedOption(item)
if(onSelect){
onSelect(item.id)
}
setShowSelect(false)
}
const dropDownRef = useRef(null)
useClickAway(dropDownRef, () => {
setShowSelect(false)
})
const firstItemClick = () => {
if(firstItem){
firstItem.onClick()
}
setSelectedOption(null)
setShowSelect(false)
}
return (
<RoundedSelectStyle selected={showSelect} width={width} minWidth={width} ref={dropDownRef} onMouseDown={showSelectDropDown} activetextcolor={activetextcolor} bordercolor={bordercolor} arrowcolor={arrowcolor}>
<SelectArrow selected={showSelect} />
<RoundedSelectedOption>{selectedOption?.title || placeholder}</RoundedSelectedOption>
{showSelect?
<RoundedSelectOptionsStyle defaultValue="">
{firstItem ? <RoundedOption backgroundColor={optionBackgroundColor} textcolor={optionTextColor} onClick={firstItemClick}>{firstItem.title}</RoundedOption> : null}
{options.map((item, key) => (
<RoundedOption backgroundColor={optionBackgroundColor} textcolor={optionTextColor} key={key} onClick={()=>selectOption(item)} selected={item.id===selectedOption?.id}>{item.title}</RoundedOption>
))}
</RoundedSelectOptionsStyle>
:null}
</RoundedSelectStyle>
)
}
type TextAreaProps = {
title: string;
placeholder: string;
required?: boolean;
size?: string;
onChange?: (data : any) => void;
layoutGridColumnSpan?: string;
}
export function Textarea ({title, placeholder, required, size, onChange, layoutGridColumnSpan} : TextAreaProps) {
return (
<Container sx={layoutGridColumnSpan ? {gridColumn: `span ${layoutGridColumnSpan}`} : {}}>
<TextareaStyle placeholder={placeholder} onChange={onChange} />
</Container>
)
}
type RadioProps = {
options: {
text: string;
value: string;
}[],
name: string;
size?: string;
onChange?: (data : any) => void;
layoutGridColumnSpan?: string;
}
export function RadioButtons ({options, name, size, onChange, layoutGridColumnSpan} : RadioProps) {
useEffect(() => {
if(onChange){
onChange({target: options[0]})
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
let radio_styles = {
gap: '3.3vw',
padding: '0.2vw',
margin: '0.1vw 0.6vw 0.1vw 1vw',
height: '1.5vw',
width: '1.5vw',
fontSize: '0.9vw !important',
margin2: '0 0 0 -1.5vw',
marginTop: '0'
}
const isMobile = useResponsive('down', 768)
if(isMobile){
radio_styles = {
gap: '7.5vw',
padding: '0',
margin: '0vw 3vw 0vw 0vw',
height: '7vw',
width: '7vw',
fontSize: '3.8vw !important',
margin2: '0 0 0 -1vw',
marginTop: '5.5vw'
}
}else{
radio_styles = {
gap: '3.3vw',
padding: '0.2vw',
margin: '0.1vw 0.6vw 0.1vw 1vw',
height: '1.5vw',
width: '1.5vw',
fontSize: '0.9vw !important',
margin2: '0 0 0 -1.5vw',
marginTop: '0'
}
}
return (
<RadioGroup
aria-labelledby={name}
defaultValue={options[0].value}
name={name}
row
sx={{marginTop: radio_styles.marginTop, gap: radio_styles.gap, columnSpan: layoutGridColumnSpan || null}}
>
{options.map((item, index) => <FormControlLabel sx={{'& > span:first-of-type': {'&:hover': {backgroundColor: globalSettings.Colors.primaryLight1}, padding: radio_styles.padding, margin: radio_styles.margin, '& > svg': {height: radio_styles.height, width: radio_styles.width}}, '& > span:last-of-type': { fontSize: radio_styles.fontSize }, margin: radio_styles.margin2}} onChange={onChange} key={index} value={item.value} control={<Radio sx={{'&.Mui-checked':{color:"#66A4F9"}}} />} label={item.text} />)}
</RadioGroup>
)
}
type CheckBoxesProps = {
label: string;
options: {
text: string;
value: string;
}[],
required?: boolean;
size?: string;
}
export function CheckBoxes ({label, options, required, size} : CheckBoxesProps) {
return (
<CheckBoxesContainer>
<Title>{label}{required && <Required>*</Required>}</Title>
<CheckBoxesWrapper>
{options.map((item, index)=><FormControlLabel control={<Checkbox />} label={item.text} key={index} />)}
</CheckBoxesWrapper>
</CheckBoxesContainer>
)
}
type HTMLBlockProps = {
content: string;
size?: string;
}
export function HTMLBlock ({content, size} : HTMLBlockProps) {
return (
<HTMLBlockStyle dangerouslySetInnerHTML={{__html: content}} />
)
}
export function Section ({size}:{size?: string}) {
return <SectionLine />
}
type DateProps = {
label: string;
size?: string;
};
export function MultiSelect ({title, options, required, size, onSelect, onChange, errorMessage, layoutGridColumnSpan} : SelectProps) {
const [showSelect, setShowSelect] = useState<boolean>(false)
const showSelectDropDown = (e : React.MouseEvent) => {
const target = e.target as HTMLElement;
if(target){
if(target.classList.contains('chip')){
return
}
}
setShowSelect(true)
}
const [selectedOptions, setSelectedOptions] = useState<string[]>([])
const selectOption = (item : string) => {
if(selectedOptions.includes(item)){
const newSelectedOptions = selectedOptions.filter(option=>option!==item)
setSelectedOptions(newSelectedOptions)
if(onChange){
onChange({target: {value: newSelectedOptions}})
}
}else{
setSelectedOptions([...selectedOptions, item])
if(onChange){
onChange({target: {value: [...selectedOptions, item]}})
}
}
setShowSelect(false)
}
const removeChip = (text : string) => {
if(onChange){
setSelectedOptions(selectedOptions.filter(item=>item!==text))
onChange({target: {value: selectedOptions.filter(item=>item!==text).length === 0 ? null : selectedOptions.filter(item=>item!==text)}})
}
}
const Chip = ({text} : {text: string}) => <ChipStyle className="chip" onClick={()=>removeChip(text)}><ChipText>{text}</ChipText><ChipX /></ChipStyle>
const dropDownRef = useRef(null)
useClickAway(dropDownRef, () => {
setShowSelect(false)
})
return (
<Container sx={layoutGridColumnSpan ? {gridColumn: `span ${layoutGridColumnSpan}`} : {}}>
<Title>{title}{required?<Required>*</Required>:null}</Title>
<SelectContainer onMouseDown={showSelectDropDown} ref={dropDownRef}>
<SelectArrow selected={showSelect} />
<MultiSelectedOption>{selectedOptions.length > 0 ? selectedOptions.map((item, index)=> (
<Chip text={item} key={index} />
)) : <div style={{opacity: 0.5}}>Please Select</div>}</MultiSelectedOption>
{showSelect?
<SelectStyle defaultValue="">
{options.map((item, key) => (
<Option key={key} onClick={()=>selectOption(item.text)} selected={selectedOptions.includes(item.text)}>{item.text}</Option>
))}
</SelectStyle>
:null}
</SelectContainer>
</Container>
)
}
export function Date({ label, size }: DateProps) {
return (
<div>
<LocalizationProvider>
<DatePicker label={label} />
</LocalizationProvider>
</div>
);
}
export function Time({label, size} : DateProps) {
return (
<div>
<LocalizationProvider>
<TimePicker label={label} />
<style>
{`
.MuiButtonBase-root {
line-height: 1.5;
}
`}
</style>
</LocalizationProvider>
</div>
)
}
type AddressProps = {
required?: boolean;
inputs: {
id: number;
label: string;
placeholder: string;
name: string;
autocompleteAttribute?: string;
}[];
onChange?: (data:any) => void;
}
type Suggestion = {
description: string;
place_id: string;
}
type PlacesAutocompleteProps = {
getInputProps: any;
suggestions: Suggestion[];
getSuggestionItemProps: any;
loading: boolean;
}
export function Address({required, inputs, onChange} : AddressProps) {
const [address, setAddress] = useState<string>('');
const handleChange = (newAddress: string) => {
setAddress(newAddress);
onGlobalChange();
};
const inputMap = {
address: 1,
city: 2,
state: 3,
postcode: 4,
country: 5
}
const handleSelect = (selectedAddress: string) => {
geocodeByAddress(selectedAddress)
.then((results: google.maps.GeocoderResult[]) => {
const addressComponents = results[0].address_components;
let addressLineOne = ''
for (let i = 0; i < addressComponents.length; i+=1) {
const component = addressComponents[i];
const componentType = component.types[0];
switch (componentType) {
case "street_number":
addressLineOne = `${addressLineOne} ${component.long_name}`
break;
case "route":
addressLineOne = `${addressLineOne} ${component.long_name}`
break;
case "establishment":
addressLineOne = `${addressLineOne} ${component.long_name}`
break;
case "locality":
addressLineOne = `${addressLineOne}, ${component.long_name}`
break;
case "administrative_area_level_1": {
const stateInputElem = document.getElementsByClassName('addressForm')[inputMap.state] as HTMLInputElement
if(stateInputElem){
stateInputElem.value = component.long_name
}
}
break;
case "country": {
const countryInputElem = document.getElementsByClassName('addressForm')[inputMap.country] as HTMLInputElement
if(countryInputElem){
countryInputElem.value = component.long_name
}
}
break;
case 'administrative_area_level_2': {
const cityInputElem = document.getElementsByClassName('addressForm')[inputMap.city] as HTMLInputElement;
if (cityInputElem) {
cityInputElem.value = component.short_name;
}
break;
}
case 'postal_code': {
const postalCodeInputElem = document.getElementsByClassName('addressForm')[inputMap.postcode] as HTMLInputElement;
if (postalCodeInputElem) {
postalCodeInputElem.value = component.long_name;
}
break;
}
default:
break;
}
const addressInputElem = document.getElementsByClassName('addressForm')[inputMap.address] as HTMLInputElement
if(addressInputElem){
setAddress(addressLineOne)
}
onGlobalChange();
}
})
.catch((error: any) => console.error('Error', error));
};
const onGlobalChange = () => {
const elem = document.getElementsByClassName('addressForm') as HTMLCollectionOf<HTMLInputElement>
if(onChange){
setTimeout(() => {
const addressMap = {
1: elem[inputMap.address].value,
3: elem[inputMap.city].value,
4: elem[inputMap.state].value,
5: elem[inputMap.postcode].value,
6: elem[inputMap.country].value
}
onChange({target: {value: addressMap}})
}, 300)
}
}
return (
<>
{inputs.map(({id, label, placeholder, name}, index) => {
if(index === 0){
return (
<PlacesAutocomplete
key={index}
value={address}
onChange={handleChange}
onSelect={handleSelect}
>
{({ getInputProps, suggestions, getSuggestionItemProps }:PlacesAutocompleteProps) => (
<AddressContainer sx={{gridColumn: 'span 6'}}>
<Container>
<Title>{label}{required && <Required>*</Required>}</Title>
<InputStyle className="addressForm" {...getInputProps()} type='text' placeholder={placeholder} required={required} />
</Container>
<AddressOptions>
{suggestions?.map((suggestion: Suggestion, key:number) => {
const style = { cursor: 'pointer' };
return (
<AddressOption
{...getSuggestionItemProps(suggestion, {
style,
})}
key={key}
>
{suggestion.description}
</AddressOption>
);
})}
</AddressOptions>
</AddressContainer>
)}
</PlacesAutocomplete>
)
}
return (
<Container key={index} sx={{gridColumn: 'span 6'}}>
<Title>{label}{required && <Required>*</Required>}</Title>
<InputStyle onChange={onGlobalChange} className="addressForm" type='text' placeholder={placeholder} required={required} />
</Container>
)
})}
</>
);
}
type PhoneProps = {
label: string;
required?: boolean;
placeholder?: string;
size?: string;
onChange?: (data : any) => void;
}
export function Phone({label, required, placeholder, size, onChange} : PhoneProps) {
const [value, setValue] = useState('')
const setPhone = (data : any) => {
setValue(data)
if(onChange){
onChange(data)
}
}
return (
<PhoneContainer>
{label!==''?<Title>{label}{required && <Required>*</Required>}</Title>:null}
<PhoneInput country='au' value={value} onChange={setPhone} placeholder={placeholder} />
</PhoneContainer>
)
}
type EmailProps = {
title: string;
placeholder: string;
required?: boolean;
size?: string;
onChange?: (data : any) => void;
errorMessage?: string;
layoutGridColumnSpan?: string;
}
export function Email({title, placeholder, required, size, onChange, errorMessage, layoutGridColumnSpan} : EmailProps) {
return (
<Container sx={layoutGridColumnSpan ? {gridColumn: `span ${layoutGridColumnSpan}`} : {}}>
<InputStyle id='email' onChange={onChange} type='email' placeholder={errorMessage || placeholder} placeholderOpacity={errorMessage ? 1 : 0.5} placeholderColor={errorMessage ? 'red' : globalSettings.Colors.bodyBlack} required={required} />
</Container>
)
}
export function FileUpload({size} : {size?: string}) {
const onFileUpload = (file: File | null) => {
console.log(`uploaded ${file?.name}`)
}
const [selectedFile, setSelectedFile] = useState<File | null>(null);
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target?.files ? event.target.files[0] : null;
setSelectedFile(file);
onFileUpload(file);
};
const fileInputRef = useRef<HTMLInputElement | null>(null);
const onUploadButtonClick = () => {
if(fileInputRef.current){
fileInputRef.current.click()
}
}
return (
<UploadButton onClick={onUploadButtonClick}>
<UploadIcon />
<UploadText>{selectedFile ? selectedFile.name : 'Upload File'}</UploadText>
<FileInput ref={fileInputRef} type="file" onChange={handleFileChange} />
</UploadButton>
);
}
export function CaptchaComponent () {
const setCaptcha = useSetRecoilState(captchaAtom)
const onCaptchaChange = useCallback(async (e : any) => {
const url = 'https://automation.orangedigital.au/api/v1.0/pilot-partners-development/recaptcha';
try {
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
response: e,
})
});
const data = await response.json();
const { success, score } = data;
if (success && score >= 0.5) {
setCaptcha(true)
} else {
setCaptcha(false)
}
} catch (error) {
setCaptcha(false)
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
return (
<>
<div id='captcha' style={{gridColumn: 'span 12'}} />
<GoogleReCaptchaProvider
reCaptchaKey="6LeJa1UnAAAAAI3kR1QWAcsaSV4ugwjvrZFMiuzP"
container={{
element: "captcha",
parameters: {
theme: 'light',
}
}}
>
<GoogleReCaptcha
onVerify={onCaptchaChange}
/>
</GoogleReCaptchaProvider>
</>
)
}
type WebsiteProps = {
title: string;
placeholder: string;
required?: boolean;
size?: string;
}
export function Website({title, placeholder, required, size} : WebsiteProps) {
return (
<Container>
<Title>{title}{required && <Required>*</Required>}</Title>
<InputStyle type='text' placeholder={placeholder} required={required} />
</Container>
)
}
type NameProps = {
required?: boolean;
inputs: {
id: number;
label: string;
placeholder: string;
name: string;
autocompleteAttribute?: string;
choices?: {text: string, value: string}[]
}[];
}
export function Name({required, inputs} : NameProps) {
return (
<>
{inputs.map(({id, label, placeholder, name, choices}, index) => (
<Container key={index}>
{!choices?<Title>{label}{required && <Required>*</Required>}</Title>:null}
{choices?<SelectDropDown title={label} options={choices} />:<InputStyle id={name} type='text' placeholder={placeholder} required={required} />}
</Container>
)
)}
</>
);
}
type ListProps = {
label: string;
placeholder?: string;
id: number;
formId: number;
size?: string;
}
export function List({label, placeholder, id, formId, size} : ListProps) {
const [listItems, setListItems] = useState<string[]>([])
const listInputRef = useRef<HTMLInputElement>(null)
const addListItem = () => {
if(listInputRef.current && listInputRef.current.value.length > 0){
setListItems([...listItems, listInputRef.current.value])
}
}
const onKeyDown = (e : React.KeyboardEvent) => {
if(e.key === 'Enter'){
addListItem()
}
}
const removeListItem = (item: string) => {
const newListItems = listItems.filter(e=>e!==item)
setListItems(newListItems)
}
return (
<ListContainer>
<Title>{label}</Title>
<ListInputContainer>
<ListInput onKeyDown={onKeyDown} placeholder={placeholder} ref={listInputRef} />
<AddListItemButton onMouseDown={addListItem} />
</ListInputContainer>
<ListItemsContainer>
{listItems.map((item, index) => (
<ListItem key={index}>
<ListItemText>{item}</ListItemText>
<RemoveListItemButton onClick={()=>removeListItem(item)} />
</ListItem>
))}
</ListItemsContainer>
</ListContainer>
)
}
type ConsetProps = {
id: number;
formId: number;
label: string;
inputs?: {
id: string;
label: string;
name?: string;
isHidden?: boolean;
}[];
checkboxLabel: string;
isRequired?: boolean;
size?: string;
}
export function Consent ({label, id, formId, inputs, checkboxLabel, isRequired = true, size} : ConsetProps) {
return (
<ConsetContainer>
<Title>{label}{isRequired && <Required>*</Required>}</Title>
<FormControlLabel control={<Checkbox />} label={checkboxLabel} />
</ConsetContainer>
)
}
type PageProps = {
nextButton: {
text: string;
};
previousButton: {
text: string;
};
goToNextPage?: () => void;
goToPreviousPage?: () => void;
isFirstPage?: boolean;
isLastPage?: boolean;
}
export function Page ({nextButton, previousButton, goToNextPage, goToPreviousPage, isFirstPage, isLastPage} : PageProps) {
return (
<PageNavigationContainer>
{!isFirstPage?<PageNavigation onClick={goToPreviousPage}>{previousButton.text}</PageNavigation>:null}
{!isLastPage?<PageNavigation onClick={goToNextPage}>{nextButton.text}</PageNavigation>:null}
</PageNavigationContainer>
)
}
export default function Input ({type, label, placeholder, isRequired, choices, defaultValue, content, inputs, id, formId, checkboxLabel, size, nextButton, previousButton, goToNextPage, goToPreviousPage, isFirstPage, isLastPage, onChange, errorMessage, layoutGridColumnSpan} : InputProps) {
switch (type) {
case 'text':
if(placeholder){
return <TextField title={label} placeholder={placeholder} required={isRequired} layoutGridColumnSpan={layoutGridColumnSpan} onChange={onChange} errorMessage={errorMessage} />
}
throw new Error('placeholder is invalid for text');
case 'textarea':
if(placeholder){
return <Textarea title={label} placeholder={placeholder} required={isRequired} layoutGridColumnSpan={layoutGridColumnSpan} onChange={onChange} />
}
throw new Error('placeholder is invalid for textarea');
case 'select':
if(choices){
return <SelectDropDown title={label} required={isRequired} options={choices} layoutGridColumnSpan={layoutGridColumnSpan} onChange={onChange} errorMessage={errorMessage} />
}
throw new Error('choices is invalid for select');
case 'multiselect':
if(choices){
return <MultiSelect title={label} required={isRequired} options={choices} layoutGridColumnSpan={layoutGridColumnSpan} onChange={onChange} errorMessage={errorMessage} />
}
throw new Error('choices is invalid for multiselect');
case 'number':
if(placeholder){
return <TextField title={label} placeholder={placeholder} required={isRequired} type="number" layoutGridColumnSpan={layoutGridColumnSpan} />
}
throw new Error('placeholder is invalid for number');
case 'checkbox':
if(choices){
return null
}
throw new Error('choices is invalid for checkbox');
case 'radio':
if(choices){
return <RadioButtons name={label} options={choices} onChange={onChange} />
}
throw new Error('choices is invalid for radio');
case 'hidden':
return <TextField title={label} placeholder='' type="hidden" defaultValue={defaultValue} />
case 'html':
if(content){
return <HTMLBlock content={content} />
}
throw new Error('content is invalid for html');
case 'section':
return <Section />
case 'date':
return <Date label={label} />
case 'time':
return <Time label={label} />
case 'address':
if(inputs){
return <Address inputs={inputs} onChange={onChange} />
}
throw new Error('inputs is invalid for address');
case 'phone':
return <Phone label={label} onChange={onChange} />
case 'email':
if(placeholder){
return <Email title={label} placeholder={placeholder} required={isRequired} onChange={onChange} errorMessage={errorMessage} layoutGridColumnSpan={layoutGridColumnSpan} />
}
throw new Error('placeholder is invalid for email');
case 'fileupload':
return <FileUpload />
case 'captcha':
return <CaptchaComponent />
case 'website':
if(placeholder){
return <Website title={label} placeholder={placeholder} required={isRequired} />
}
throw new Error('placeholder is invalid for website');
case 'name':
if(inputs){
return <Name inputs={inputs} />
}
throw new Error('inputs is invalid for name');
case 'list':
if(placeholder){
return <List label={label} placeholder={placeholder} id={id} formId={formId} />
}
throw new Error('placeholder is invalid for list');
case 'consent':
if(checkboxLabel){
return <Consent label={label} id={id} formId={formId} checkboxLabel={checkboxLabel} isRequired={isRequired} />
}
throw new Error('checkboxLabel is invalid for consent');
case 'page':
if(nextButton && previousButton && goToNextPage && goToPreviousPage && isFirstPage!==undefined && isLastPage!==undefined){
return <Page nextButton={nextButton} previousButton={previousButton} goToNextPage={goToNextPage} goToPreviousPage={goToPreviousPage} isFirstPage={isFirstPage} isLastPage={isLastPage} />
}
throw new Error('nextButton or previousButton or goToNextPage or goToPreviousPage or isFirstPage or isLastPage is invalid for page');
default:
throw new Error('type is invalid for input');
}
}