Untitled

mail@pastecode.io avatar
unknown
javascript
a year ago
16 kB
1
Indexable
Never
import React, { useCallback, useEffect, useState } from 'react'
import styles from "./styles.module.scss";
import { getCustomGroupFieldValue, updateCandidateCustomFieldsValues } from '@helpers/helpers';
import LocationSelect from '@components/Select/LocationSelect';
import 'react-datepicker/dist/react-datepicker.css';
import DatePicker from 'react-datepicker';
import moment from "moment";
import Select from "react-select";
import Switch from "react-switch";
import { customStyles } from '@components/Select/LocationSelect/customStyle';
import { useSettings } from 'contexts/SettingsContext';
import { debounce } from 'lodash';

export const CustomSingleSelect = ({ field, type, candidate, updateCandidate }) => {
    const [inputValue, setInputValue] = useState({})
    const [options, setOptions] = useState([]);
    const candidateFilter = candidate.custom_fields.values[field.key];

    useEffect(() => {
        setOptions(field.options.map((option) => {
            return {
                value: option.text,
                label: option.text
            }
        }))
    }, [])

    useEffect(() => {
        setInputValue({
            value: candidateFilter,
            label: candidateFilter
        })
    }, [candidate])

    const handleInputChange = (value) => {
        updateCandidateCustomFieldsValues(candidate, updateCandidate, field.key, type, value.value);
    };

    return (
        <div className={styles.selectFlex}>
            <label htmlFor="">{field.name}</label>
            <Select
                options={options}
                value={inputValue}
                onChange={handleInputChange}
                className="basic-single"
                classNamePrefix="select"
                styles={customStyles}
            />
        </div>
    )
}

export const CustomMultiSelect = ({ field, type, candidate, updateCandidate }) => {
    const [inputValue, setInputValue] = useState([])
    const [options, setOptions] = useState([]);
    const candidateFilter = candidate.custom_fields.values[field.key];

    useEffect(() => {
        setOptions(field.options.map((option) => {
            return {
                value: option.text,
                label: option.text
            }
        }))

    }, [])

    useEffect(() => {
        setInputValue(candidateFilter.map((v) => {
            return {
                value: v,
                label: v
            }
        }))
    }, [candidate])

    const handleInputChange = (value) => {
        updateCandidateCustomFieldsValues(candidate, updateCandidate, field.key, type, value);
    };

    return (
        <div className={styles.selectFlex}>
            <label htmlFor="">{field.name}</label>
            <Select
                isMulti
                name="multiSelect"
                options={options}
                value={inputValue}
                onChange={handleInputChange}
                className="basic-multi-select"
                classNamePrefix="select"
                styles={customStyles}
            />
        </div>
    )
}

export const CustomText = ({ field, type, candidate, updateCandidate }) => {
    const [inputValue, setInputValue] = useState('');

    //? Debounced is used to delay update for each letter, permormance boost!
    const debouncedUpdate = useCallback(debounce(updateCandidateCustomFieldsValues, 300), []);

    const handleInputChange = (value) => {
        setInputValue(value);
        debouncedUpdate(candidate, updateCandidate, field.key, type, value);
    }

    return (
        <div className={styles.selectFlex}>
            <label htmlFor="">{field.name}</label>
            <input
                type="text"
                className='input-primary'
                value={inputValue}
                onChange={(e) => handleInputChange(e.target.value)}
            />
        </div>
    )
}

export const CustomTextarea = ({ field, type, candidate, updateCandidate }) => {
    const [inputValue, setInputValue] = useState(candidate.custom_fields.values[field.key] || '');

    //? Debounced is used to delay update for each letter, permormance boost!
    const debouncedUpdate = useCallback(debounce(updateCandidateCustomFieldsValues, 300), []);

    const handleInputChange = (value) => {
        setInputValue(value);
        debouncedUpdate(candidate, updateCandidate, field.key, type, value);
    }

    return (
        <div className={styles.selectFlex}>
            <label htmlFor="">{field.name}</label>
            <textarea
                className='input-primary'
                name=""
                id={field.id}
                cols="30"
                rows="5"
                value={inputValue}
                onChange={(e) => handleInputChange(e.target.value)}
            />
        </div>
    )
}

export const CustomSinglePlace = ({ field, type, candidate, updateCandidate }) => {
    return (
        <div className={styles.selectFlex}>
            <label htmlFor="">{field.name}</label>
            <LocationSelect
                isMulti={false}
                onChange={(location) => updateCandidateCustomFieldsValues(candidate, updateCandidate, field.key, type, location)}
                value={{
                    value: candidate.custom_fields.values[field.key],
                    label: candidate.custom_fields.values[field.key]
                }}
            />
        </div>
    )
}

export const CustomMultiLocation = ({ field, type, candidate, updateCandidate }) => {
    return (
        <div className={styles.selectFlex}>
            <label htmlFor="">{field.name}</label>
            <LocationSelect
                isMulti={type === 'single_location' ? false : true}
                onChange={(location) => updateCandidateCustomFieldsValues(candidate, updateCandidate, field.key, type, location)}
                value={candidate.custom_fields.values[field.key]}
            />
        </div>
    )
}

export const CustomDate = ({ field, type, candidate, updateCandidate }) => {
    const [startDate, setStartDate] = useState(() => {
        const fieldValue = candidate.custom_fields.values[field.key];
        return fieldValue ? moment(fieldValue, 'DD/MM/YYYY').toDate() : null;
    });

    useEffect(() => {
        const fieldValue = candidate.custom_fields.values[field.key];
        if (fieldValue !== null) {
            setStartDate(moment(fieldValue, 'DD/MM/YYYY').toDate());
        } else {
            setStartDate(null);
        }
    }, [candidate]);

    const handleInputChange = (date) => {
        setStartDate(date);
        const formattedDate = date ? moment(date).format('DD/MM/YYYY') : null;
        updateCandidateCustomFieldsValues(candidate, updateCandidate, field.key, type, formattedDate);
    };

    return (
        <div className={styles.selectFlex}>
            <label htmlFor="">{field.name}</label>
            <DatePicker
                dateFormat="dd/MM/yyyy"
                selected={startDate}
                onChange={(date) => handleInputChange(date)}
                className="calendar-input"
                isClearable
            />
        </div>
    )
}

export const CustomYesNo = ({ field, type, candidate, updateCandidate }) => {
    const [inputValue, setInputValue] = useState(candidate.custom_fields.values[field.key] ? true : false);

    const handleInputChange = (checked) => {
        setInputValue(checked);
        updateCandidateCustomFieldsValues(candidate, updateCandidate, field.key, type, checked ? 1 : 0)
    }

    return (
        <div className={styles.selectFlex}>
            <label htmlFor="">{field.name}</label>
            <Switch
                checked={inputValue}
                onChange={(checked) => handleInputChange(checked)}
                onColor='#be2bbb'
                height={20}
                width={46}
                activeBoxShadow='0 0 2px 3px #be2bbb25'
            />
        </div>
    )
}

export const CustomNumber = ({ field, type, candidate, updateCandidate }) => {
    const [input, setInput] = useState(candidate.custom_fields.values[field.key] || '');
    const debouncedUpdate = useCallback(debounce(updateCandidateCustomFieldsValues, 300), []);

    const handleInputChange = (value) => {
        setInput(value)
        debouncedUpdate(candidate, updateCandidate, field.key, type, value)
    }

    return (
        <div className={styles.selectFlex}>
            <label htmlFor="">{field.name}</label>
            <input
                className={`${styles.width50} input-primary`}
                type="number"
                value={input}
                onChange={(e) => handleInputChange(e.target.value)}
            />
        </div>
    )
}

export const CustomNumberRange = ({ field, type, candidate, updateCandidate }) => {
    const candidateFilter = candidate.custom_fields.values[field.key];
    const [inputFromValue, setInputFromValue] = useState(candidateFilter.from || '');
    const [inputToValue, setInputToValue] = useState(candidateFilter.to || '');

    const debouncedUpdate = useCallback(debounce(updateCandidateCustomFieldsValues, 300), []);

    const handleInputChange = (value, inputType) => {

        if (inputType === 'from') {
            setInputFromValue(value);
            debouncedUpdate(candidate, updateCandidate, field.key, type, {
                from: value,
                to: inputToValue
            });
        } else if (inputType === 'to') {
            setInputToValue(value);
            debouncedUpdate(candidate, updateCandidate, field.key, type, {
                from: inputFromValue,
                to: value
            });
        }
    }

    return (
        <div className={styles.selectFlex}>
            <label htmlFor="">{field.name}</label>
            <div className={`${styles.multipleItems} ${styles.width50}`}>
                <input
                    className={` input-primary`}
                    type="number"
                    value={inputFromValue}
                    onChange={(e) => handleInputChange(e.target.value, 'from')}
                />
                <span className={styles.to}> - </span>
                <input
                    className={` input-primary`}
                    type="number"
                    value={inputToValue}
                    onChange={(e) => handleInputChange(e.target.value, 'to')}
                />
            </div>
        </div>
    )
}

export const CustomMoney = ({ field, type, candidate, updateCandidate }) => {
    const candidateFilter = candidate.custom_fields.values[field.key];
    const [currencyValue, setCurrencyValue] = useState({ value: candidateFilter?.currency, label: candidateFilter?.currency });
    const [inputValue, setInputValue] = useState(candidateFilter?.number || '');
    const [options, setOptions] = useState([]);
    const { currencies } = useSettings();

    const debouncedUpdate = useCallback(debounce(updateCandidateCustomFieldsValues, 300), []);

    useEffect(() => {
        setOptions(Object.keys(currencies).map((currency) => {
            return {
                value: currency,
                label: currency
            }
        }))
    }, [])

    //! This has quick fix for sending null if currency isn't selected - remove after implementing Validdation
    const handleInputChange = (value, inputType) => {
        if (inputType === 'currency') {
            setCurrencyValue(value)
            updateCandidateCustomFieldsValues(candidate, updateCandidate, field.key, type, {
                currency: value.value,
                number: inputValue
            })
        } else if (inputType === 'money') {
            setInputValue(value);
            debouncedUpdate(candidate, updateCandidate, field.key, type, currencyValue.value === null ? null : {
                currency: currencyValue.value,
                number: value
            })
        }
    }

    return (
        <div className={styles.selectFlex}>
            <label htmlFor="">{field.name}</label>
            <div className={styles.multipleItems}>
                <Select
                    options={options}
                    value={currencyValue}
                    onChange={(value) => handleInputChange(value, 'currency')}
                    className={`${styles.width50} basic-single`}
                    classNamePrefix="select"
                    styles={customStyles}
                />
                <input
                    className={`${styles.width50} input-primary`}
                    type="number"
                    value={inputValue}
                    onChange={(e) => handleInputChange(e.target.value, 'money')}
                />
            </div>
        </div>
    )
}

export const CustomMoneyRange = ({ field, type, candidate, updateCandidate }) => {
    const candidateFilter = candidate.custom_fields.values[field.key];
    const [currencyValue, setCurrencyValue] = useState({ value: candidateFilter?.currency, label: candidateFilter?.currency });
    const [inputFromValue, setInputFromValue] = useState(candidateFilter?.from || '');
    const [inputToValue, setInputToValue] = useState(candidateFilter?.to || '');

    const debouncedUpdate = useCallback(debounce(updateCandidateCustomFieldsValues, 300), []);

    const [options, setOptions] = useState([]);
    const { currencies } = useSettings();

    useEffect(() => {
        setOptions(Object.keys(currencies).map((currency) => {
            return {
                value: currency,
                label: currency
            }
        }))

    }, [])

    //! This has quick fix for sending null if currency isn't selected - remove after implementing Validdation
    const handleInputChange = (value, inputType) => {
        if (inputType === 'currency') {
            setCurrencyValue(value);
            updateCandidateCustomFieldsValues(candidate, updateCandidate, field.key, type, {
                currency: value.value,
                from: inputFromValue,
                to: inputToValue
            })
        } else if (inputType === 'from') {
            setInputFromValue(value);
            debouncedUpdate(candidate, updateCandidate, field.key, type, currencyValue.value === null ? null : {
                currency: currencyValue.value,
                from: value,
                to: inputToValue
            })
        } else if (inputType === 'to') {
            setInputToValue(value);
            debouncedUpdate(candidate, updateCandidate, field.key, type, currencyValue.value === null ? null : {
                currency: currencyValue.value,
                from: inputFromValue,
                to: value
            })
        }
    }
    return (
        <div className={styles.selectFlex}>
            <label htmlFor="">{field.name}</label>
            <div className={styles.multipleItems}>
                <Select
                    options={options}
                    value={currencyValue}
                    onChange={(value) => handleInputChange(value, 'currency')}
                    className={`${styles.width50} basic-single`}
                    classNamePrefix="select"
                    styles={customStyles}
                />
                <div className={`${styles.multipleItems} ${styles.width50}`}>
                    <input
                        className={` input-primary`}
                        type="number"
                        value={inputFromValue}
                        onChange={(e) => handleInputChange(e.target.value, 'from')}
                    />
                    <span className={styles.to}> - </span>
                    <input
                        className={` input-primary`}
                        type="number"
                        value={inputToValue}
                        onChange={(e) => handleInputChange(e.target.value, 'to')}
                    />
                </div>
            </div>
        </div>
    )
}