;\n name: string;\n disableEdit?: boolean;\n index: any;\n};\n\nconst ConditionalInput = ({\n node,\n name,\n disableEdit,\n index,\n}: ConditionalInputType) => {\n const { setFieldValue, values } = useFormikContext() as any;\n const translate = useTranslate();\n const lookup =\n values.tierRequirement.length === 2\n ? values.tierRequirementOperator\n : values.tierRequirement[0];\n\n if (node.complete || disableEdit) {\n return (\n \n {node[name] || '-'}\n {name === 'percentage' && '%'}\n \n );\n }\n\n const additionalProps = {\n minimumActiveMembersCount: { min: 0, max: +node.maximumActiveMembers },\n maximumActiveMembers: { min: +node.minimumActiveMembersCount },\n minimumNetProfit: { min: 0, max: +node.maximumNetProfit },\n maximumNetProfit: { max: +node.minimumNetProfit },\n percentage: { min: 0, max: 100 },\n };\n\n const validate = (value: number | string) => {\n switch (name) {\n case 'minimumActiveMembersCount':\n return value <= +node.maximumActiveMembers && value >= 0\n ? value\n : node.maximumActiveMembers;\n case 'maximumActiveMembers':\n return value >= +node.minimumActiveMembersCount && value >= 0\n ? value\n : node.minimumActiveMembersCount;\n case 'minimumNetProfit':\n return value <= +node.maximumNetProfit && value >= 0\n ? value\n : node.maximumNetProfit;\n case 'maximumNetProfit':\n return value >= +node.minimumNetProfit && value >= 0\n ? value\n : node.minimumNetProfit;\n case 'percentage':\n return value <= 100 && value >= 0 ? value : 50;\n default:\n return value;\n }\n };\n\n return (\n \n {\n const { value } = e.target;\n\n const { forActiveMembers, forNetProfit } = getTierRequirement(lookup);\n\n const newLevels = values.levels.map(\n (level: Record, idx: number) => {\n if (idx === index) {\n return {\n ...level,\n [name]: value,\n };\n }\n return level;\n }\n );\n\n if (newLevels.length > 1) {\n if (name.includes('minimumActiveMembersCount')) {\n newLevels[index - 1] = {\n ...newLevels[index - 1],\n ...(forActiveMembers && { maximumActiveMembers: +value }),\n };\n }\n if (name.includes('minimumNetProfit')) {\n newLevels[index - 1] = {\n ...newLevels[index - 1],\n ...(forNetProfit && { maximumNetProfit: +value }),\n };\n }\n }\n\n setFieldValue('levels', newLevels);\n }}\n onBlur={(e) => {\n const { value } = e.target;\n const newValue = validate(value);\n\n setFieldValue(\n 'levels',\n values.levels.map((level: Record) => {\n if (level.key === node.key) {\n return {\n ...level,\n [name]: newValue || value,\n complete: isNotEmpty(node, lookup),\n completedAt: isNotEmpty(node, lookup) ? lookup : '',\n };\n }\n return level;\n })\n );\n }}\n style={{ border: '0px' }}\n size=\"small\"\n placeholder={\n name === 'name' ? translate(messages['common.edit.text']) : '-'\n }\n />\n {name === 'percentage' && %}\n
\n );\n};\n\nexport default ConditionalInput;\n","import styled from 'styled-components';\n\nexport const StyledTableContainer = styled.div`\n /* overflow: auto;\n margin: 0 auto;\n width: 80%; */\n\n tr.drop-over-downward td {\n border-bottom: 2px inset #1890ff;\n }\n\n tr.drop-over-upward td {\n border-top: 2px inset #1890ff;\n }\n\n .button-group {\n display: flex;\n flex-direction: row-reverse;\n }\n`;\n\nexport const StyledCenter = styled.div`\n /* height: 138px; */\n display: flex;\n align-items: center;\n justify-content: center;\n`;\n\nexport default {};\n","import React, { useState } from 'react';\nimport { QuestionCircleOutlined } from '@ant-design/icons';\nimport { Modal } from 'antd';\n\nimport { FormattedMessage } from 'react-intl';\nimport { useFormikContext } from 'formik';\n\nimport { AffiliateProgrammeLevel } from 'types/graphqlTypes';\nimport { getTierRequirement } from '../../../../../../../../constants';\n\nconst DeleteTier = ({ index }: { index: any }) => {\n const { values, setFieldValue } = useFormikContext() as any;\n const [isShow, setShow] = useState(false);\n const handleShow = (e?: any) => {\n if (e) e.preventDefault();\n setShow(!isShow);\n };\n\n const { levels } = values;\n\n return (\n <>\n \n \n \n {isShow && (\n \n }\n cancelText={\n \n }\n onCancel={handleShow}\n onOk={() => {\n const lookup =\n values.tierRequirement.length === 2\n ? values.tierRequirementOperator\n : values.tierRequirement[0];\n\n const { forActiveMembers, forNetProfit } = getTierRequirement(\n lookup\n );\n\n let providedLevels = [];\n\n const newFilteredLevels = levels.filter(\n (_: AffiliateProgrammeLevel, idx: number | string) =>\n idx !== index\n );\n\n providedLevels = newFilteredLevels;\n if (newFilteredLevels.length) {\n const newMappedLevels = newFilteredLevels.map(\n (l: Record, indx: number) => {\n if (indx !== newFilteredLevels.length - 1) {\n return {\n ...l,\n ...(forActiveMembers && {\n maximumActiveMembers:\n newFilteredLevels[indx + 1].minimumActiveMembersCount,\n }),\n ...(forNetProfit && {\n maximumNetProfit:\n newFilteredLevels[indx + 1].minimumNetProfit,\n }),\n };\n }\n return l;\n }\n );\n providedLevels = newMappedLevels;\n }\n\n setFieldValue('levels', providedLevels);\n handleShow();\n }}\n >\n \n \n )}\n >\n );\n};\n\nexport default DeleteTier;\n","import styled from 'styled-components';\n\nexport const Root = styled.div`\n .footer-actions {\n display: flex;\n }\n .form-content {\n max-width: 620px;\n margin: 0 auto;\n }\n`;\n\nexport default {};\n","import React, { useRef, useImperativeHandle, useEffect } from 'react';\nimport { Form } from '@ant-design/compatible';\nimport '@ant-design/compatible/assets/index.css';\nimport { Input } from 'antd';\nimport { Formik, useFormikContext } from 'formik';\nimport { FormattedMessage } from 'react-intl';\nimport FormItem from 'components/FormItem';\nimport { formItemHorizontalLayout } from 'constants/form';\nimport { AffiliateProgrammeLevel } from 'types/graphqlTypes';\nimport { Root } from './styles';\nimport { TIER_REQUIREMENT } from '../../../../../../../../constants';\n\ntype TierFormType = {\n index: string;\n submitEdit: boolean;\n submit: (val: any, idx: any) => void;\n isLatest: boolean;\n setSubmitEdit: any;\n};\n\nconst TierForm = ({ index, submitEdit, submit, isLatest }: TierFormType) => {\n const parentForm = useFormikContext() as any;\n const formRef = useRef(null);\n const parentFormValues = parentForm.values;\n\n const initialValues = {\n ...parentFormValues.levels.find(\n (_: AffiliateProgrammeLevel, idx: any) => idx === index\n ),\n };\n\n useImperativeHandle(formRef, () => ({\n ...formRef.current,\n handleSubmit: () => submit,\n }));\n\n useEffect(() => {\n if (submitEdit) {\n const { tierRequirement, tierRequirementOperator } = parentFormValues;\n const lookup =\n tierRequirement.length === 2\n ? tierRequirementOperator\n : tierRequirement[0];\n const {\n current: { values },\n } = formRef;\n submit(lookup, values);\n }\n }, [submitEdit, submit, parentFormValues]);\n\n return (\n {}}\n >\n {({ values, errors, handleChange }) => (\n \n \n \n \n }\n {...formItemHorizontalLayout}\n colon={false}\n />\n \n }\n validateStatus={errors && errors.name && 'error'}\n help={errors && errors.name}\n >\n \n \n {parentFormValues.tierRequirement.includes(\n TIER_REQUIREMENT.ACTIVE_MEMBERS\n ) && (\n <>\n \n }\n validateStatus={\n errors && errors.minimumActiveMembersCount && 'error'\n }\n help={errors && errors.minimumActiveMembersCount}\n >\n \n \n \n }\n validateStatus={\n errors && errors.maximumActiveMembers && 'error'\n }\n help={errors && errors.maximumActiveMembers}\n >\n \n \n >\n )}\n {parentFormValues.tierRequirement.includes(\n TIER_REQUIREMENT.NET_PROFIT\n ) && (\n <>\n \n }\n validateStatus={errors && errors.minimumNetProfit && 'error'}\n help={errors && errors.minimumNetProfit}\n >\n \n \n \n }\n validateStatus={errors && errors.maximumNetProfit && 'error'}\n help={errors && errors.maximumNetProfit}\n >\n \n \n >\n )}\n \n }\n validateStatus={errors && errors.percentage && 'error'}\n help={errors && errors.percentage}\n >\n \n \n \n )}\n \n );\n};\n\nexport default TierForm;\n","import React, { useState } from 'react';\nimport { Modal } from 'antd';\nimport { FormattedMessage } from 'react-intl';\nimport { useFormikContext } from 'formik';\nimport { isNotEmpty } from '../ConditionalInput/ConditionalInput';\nimport TierForm from '../TierForm';\n\nconst EditTier = ({ index }: { index: any }) => {\n const [isShow, setShow] = useState(false);\n const [submitEdit, setSubmitEdit] = useState(false);\n const { setFieldValue, values } = useFormikContext() as any;\n\n const handleShow = (e: any) => {\n if (e) e.preventDefault();\n setShow(!isShow);\n };\n\n const handleOk = (e: any) => {\n if (e) e.preventDefault();\n setSubmitEdit(true);\n };\n\n const submit = (lookup: any, newValues: Record) => {\n setSubmitEdit(false);\n setFieldValue(\n 'levels',\n values.levels.map((level: Record, idx: string) => {\n if (idx === index) {\n return {\n ...newValues,\n complete: isNotEmpty(newValues, lookup),\n completedAt: isNotEmpty(newValues, lookup) ? lookup : '',\n };\n }\n return level;\n })\n );\n setShow(!isShow);\n };\n\n return (\n <>\n \n \n \n {isShow && (\n \n }\n okText={\n \n }\n cancelText={\n \n }\n onCancel={handleShow}\n onOk={handleOk}\n >\n \n \n )}\n >\n );\n};\n\nexport default EditTier;\n","import React, { useState } from 'react';\nimport { QuestionCircleOutlined } from '@ant-design/icons';\nimport { Modal } from 'antd';\nimport generateId from 'utils/generateId';\nimport { FormattedMessage } from 'react-intl';\nimport { useFormikContext } from 'formik';\nimport { AffiliateProgrammeLevel } from 'types/graphqlTypes';\nimport { getTierRequirement } from '../../../../../../../../constants';\n\nconst DuplicateTier = ({ index }: { index: number }) => {\n const { values, setFieldValue } = useFormikContext() as any;\n const [isShow, setShow] = useState(false);\n const handleShow = (e?: any) => {\n if (e) e.preventDefault();\n setShow(!isShow);\n };\n\n const { levels } = values;\n\n return (\n <>\n {\n if (index === levels.length - 1) {\n handleShow();\n }\n }}\n >\n \n \n {isShow && (\n \n }\n cancelText={\n \n }\n onCancel={handleShow}\n onOk={() => {\n const selectedLevel = levels.find(\n (_: AffiliateProgrammeLevel, idx: string | number) =>\n idx === index\n );\n\n const lookup =\n values.tierRequirement.length === 2\n ? values.tierRequirementOperator\n : values.tierRequirement[0];\n\n const { forActiveMembers, forNetProfit } = getTierRequirement(\n lookup\n );\n\n const newLevels = levels.map(\n (level: Record, idx: string | number) => {\n if (idx === levels.length - 1) {\n return {\n ...level,\n ...(forActiveMembers && {\n maximumActiveMembers:\n +level.minimumActiveMembersCount + 1,\n }),\n ...(forNetProfit && {\n maximumNetProfit: +level.minimumNetProfit + 1,\n }),\n };\n }\n return level;\n }\n );\n\n setFieldValue('levels', []);\n\n setFieldValue('levels', [\n ...newLevels,\n {\n ...selectedLevel,\n key: generateId('aap'),\n name: `Copy of ${selectedLevel.name}`,\n ...(!!newLevels.length &&\n forActiveMembers && {\n minimumActiveMembersCount:\n newLevels[newLevels.length - 1].maximumActiveMembers,\n }),\n ...(!!newLevels.length &&\n forNetProfit && {\n minimumNetProfit:\n newLevels[newLevels.length - 1].maximumNetProfit,\n }),\n },\n ]);\n handleShow();\n }}\n >\n \n \n )}\n >\n );\n};\n\nexport default DuplicateTier;\n","import React from 'react';\nimport { EllipsisOutlined } from '@ant-design/icons';\nimport { Dropdown, Button, Menu } from 'antd';\nimport { useFormikContext } from 'formik';\nimport DeleteTier from '../DeleteTier';\nimport EditTier from '../EditTier';\nimport DuplicateTier from '../DuplicateTier';\n\nconst ActionsColumn = ({ index }: { index: number }) => {\n const { values } = useFormikContext() as any;\n\n return (\n \n \n \n \n \n \n \n \n \n \n \n }\n >\n } />\n \n );\n};\n\nexport default ActionsColumn;\n","import { defineMessages } from 'react-intl';\n\nconst messages = defineMessages({\n 'tier.text': {\n id: 'tier.text',\n defaultMessage: 'Tier',\n },\n 'tier-name.text': {\n id: 'tier-name.text',\n defaultMessage: 'Tier Name',\n },\n 'min-active-members.text': {\n id: 'min-active-members.text',\n defaultMessage: 'Min Active Members',\n },\n 'max-active-members.text': {\n id: 'max-active-members.text',\n defaultMessage: 'Max Active Members',\n },\n 'min-net-profit.text': {\n id: 'min-net-profit.text',\n defaultMessage: 'Min Net Profit',\n },\n 'max-net-profit.text': {\n id: 'max-net-profit.text',\n defaultMessage: 'Max Net Profit',\n },\n 'commission.text': {\n id: 'commission.text',\n defaultMessage: 'Commission',\n },\n});\n\nexport default messages;\n","import React from 'react';\nimport { FormattedMessage } from 'react-intl';\nimport { CheckCircleFilled, ExclamationCircleFilled } from '@ant-design/icons';\nimport { customFormatMessage } from 'utils/customFormatMessage';\nimport { TIER_REQUIREMENT } from 'pages/components/AffiliateProgramme/constants';\nimport ConditionalInput from './components/ConditionalInput';\nimport { StyledCenter } from './styles';\nimport ActionColumns from './components/ActionColumns';\nimport messages from './messages';\n\nexport const getColumns = (values: Record, intl: any) => {\n const translate = (messageVal: any, opts = null) =>\n customFormatMessage(intl.formatMessage, messageVal, opts);\n\n return [\n {\n title: <>>,\n width: 50,\n render: (_: unknown, record: Record) =>\n record.complete ? (\n \n ) : (\n \n ),\n },\n {\n title: translate(messages['tier.text']),\n key: 'number',\n dataIndex: 'number',\n render: (_: unknown, _1: unknown, index: number) => (\n \n \n
\n \n
\n
{index + 1}\n
\n \n ),\n },\n {\n title: translate(messages['tier-name.text']),\n key: 'name',\n dataIndex: 'name',\n render: (_: unknown, record: Record, index: any) => (\n \n \n \n ),\n },\n {\n title: translate(messages['min-active-members.text']),\n key: 'minimumActiveMembersCount',\n dataIndex: 'minimumActiveMembersCount',\n render: (_: unknown, record: Record, index: any) =>\n values.tierRequirement.includes(TIER_REQUIREMENT.ACTIVE_MEMBERS) ? (\n \n ) : (\n <>>\n ),\n },\n {\n title: translate(messages['max-active-members.text']),\n key: 'maximumActiveMembers',\n dataIndex: 'maximumActiveMembers',\n render: (_: unknown, record: Record, index: any) =>\n values.tierRequirement.includes(TIER_REQUIREMENT.ACTIVE_MEMBERS) ? (\n \n ) : (\n <>>\n ),\n },\n {\n title: translate(messages['min-net-profit.text']),\n key: 'minimumNetProfit',\n dataIndex: 'minimumNetProfit',\n render: (_: unknown, record: Record, index: any) =>\n values.tierRequirement.includes(TIER_REQUIREMENT.NET_PROFIT) ? (\n \n ) : (\n <>>\n ),\n },\n {\n title: translate(messages['max-net-profit.text']),\n key: 'maximumNetProfit',\n dataIndex: 'maximumNetProfit',\n render: (_: unknown, record: Record, index: any) =>\n values.tierRequirement.includes(TIER_REQUIREMENT.NET_PROFIT) ? (\n \n ) : (\n <>>\n ),\n },\n {\n title: translate(messages['commission.text']),\n key: 'percentage',\n dataIndex: 'percentage',\n render: (_: unknown, record: Record, index: number) => (\n \n ),\n },\n {\n title: 'Actions',\n key: 'actions',\n render: (_: unknown, _1: Record, index: number) => (\n \n ),\n },\n ];\n};\n","import React from 'react';\nimport { PlusOutlined } from '@ant-design/icons';\nimport { Table, Button } from 'antd';\nimport { FormattedMessage, useIntl } from 'react-intl';\nimport { getTierRequirement } from 'pages/components/AffiliateProgramme/constants';\nimport { StyledTableContainer } from '../../styles';\nimport { getColumns } from '../../columns';\n\ntype TierTableType = {\n tierRequirementLookup: string;\n defaultLevelValue: Record;\n formProps: Record;\n};\n\nconst TierTable = ({\n formProps,\n defaultLevelValue,\n tierRequirementLookup,\n}: TierTableType) => {\n const { values, setFieldValue } = formProps;\n const intl = useIntl();\n\n return (\n \n \n
\n
\n r.key}\n />\n \n );\n};\n\nexport default TierTable;\n","import React, { useEffect } from 'react';\nimport generateId from 'utils/generateId';\nimport { TIER_REQUIREMENT } from '../../../../../../constants';\nimport { isNotEmpty } from './components/ConditionalInput/ConditionalInput';\nimport TierTable from './components/TierTable';\n\ntype TierSettingsType = {\n formProps: Record;\n};\n\nconst TierSettings = ({ formProps }: TierSettingsType) => {\n const { values, setFieldValue } = formProps;\n\n const tierRequirementLookup =\n values.tierRequirement.length === 2\n ? values.tierRequirementOperator\n : values.tierRequirement[0];\n\n useEffect(() => {\n const newLevels = values.levels.map((level: Record) => {\n if (\n (level.completedAt === TIER_REQUIREMENT.ACTIVE_MEMBERS ||\n level.completedAt === TIER_REQUIREMENT.NET_PROFIT) &&\n level.completedAt !== tierRequirementLookup\n ) {\n if (\n level.completedAt === TIER_REQUIREMENT.ACTIVE_MEMBERS &&\n (tierRequirementLookup === TIER_REQUIREMENT.BOTH ||\n tierRequirementLookup === TIER_REQUIREMENT.EITHER)\n ) {\n return {\n ...level,\n complete: false,\n minimumNetProfit: '',\n maximumNetProfit: '',\n };\n }\n if (\n level.completedAt === TIER_REQUIREMENT.NET_PROFIT &&\n (tierRequirementLookup === TIER_REQUIREMENT.BOTH ||\n tierRequirementLookup === TIER_REQUIREMENT.EITHER)\n ) {\n return {\n ...level,\n complete: false,\n minimumActiveMembersCount: '',\n maximumActiveMembers: '',\n };\n }\n return {\n ...level,\n complete: false,\n minimumNetProfit: '',\n maximumNetProfit: '',\n minimumActiveMembersCount: '',\n maximumActiveMembers: '',\n };\n }\n if (\n (level.completedAt === TIER_REQUIREMENT.BOTH ||\n level.completedAt === TIER_REQUIREMENT.EITHER) &&\n level.completedAt !== tierRequirementLookup\n ) {\n if (\n tierRequirementLookup === TIER_REQUIREMENT.ACTIVE_MEMBERS &&\n (level.completedAt === TIER_REQUIREMENT.BOTH ||\n level.completedAt === TIER_REQUIREMENT.EITHER)\n ) {\n return {\n ...level,\n minimumNetProfit: '',\n maximumNetProfit: '',\n complete: isNotEmpty(level, tierRequirementLookup),\n };\n }\n if (\n tierRequirementLookup === TIER_REQUIREMENT.NET_PROFIT &&\n (level.completedAt === TIER_REQUIREMENT.BOTH ||\n level.completedAt === TIER_REQUIREMENT.EITHER)\n ) {\n return {\n ...level,\n minimumActiveMembersCount: '',\n maximumActiveMembers: '',\n complete: isNotEmpty(level, tierRequirementLookup),\n };\n }\n }\n return {\n ...level,\n complete: isNotEmpty(level, tierRequirementLookup),\n };\n });\n setFieldValue('levels', newLevels);\n // eslint-disable-next-line\n }, [setFieldValue, tierRequirementLookup]);\n\n const defaultLevelValue = {\n key: generateId('aap'),\n complete: false,\n completedAt: '',\n name: '',\n minimumActiveMembersCount: 1,\n maximumActiveMembers: '',\n minimumNetProfit: 1,\n maximumNetProfit: '',\n percentage: '',\n };\n\n return (\n \n );\n};\n\nexport default TierSettings;\n","import React from 'react';\nimport { Form } from '@ant-design/compatible';\nimport '@ant-design/compatible/assets/index.css';\nimport { Switch as AntdSwitch } from 'antd';\nimport { formItemHorizontalLayout } from 'constants/form';\n\nconst Temp: any = AntdSwitch;\nconst Switch = ({\n checkedChildren,\n unCheckedChildren,\n label,\n value,\n onChange,\n}: {\n checkedChildren: string;\n unCheckedChildren: string;\n value: string;\n label: string;\n onChange: (e: any) => void;\n}) => (\n \n \n \n);\n\nexport default Switch;\n","import React from 'react';\nimport { Form } from '@ant-design/compatible';\nimport '@ant-design/compatible/assets/index.css';\nimport { Select as Temp } from 'antd';\nimport { formItemHorizontalLayout } from 'constants/form';\n\nconst { Option } = Temp;\n\nfunction Select({\n options,\n label,\n value,\n onChange,\n}: {\n options: Array<{\n id: any;\n text: any;\n }>;\n label: string;\n value: string;\n onChange: (e: any) => void;\n}) {\n return (\n \n onChange(e)}\n size=\"large\"\n >\n {options.map((q, i) => (\n \n ))}\n \n \n );\n}\n\nexport default Select;\n","import React, { ReactElement } from 'react';\nimport { Radio } from 'antd';\nimport { useFormikContext } from 'formik';\nimport { RadioChangeEvent } from 'antd/lib/radio';\n\nconst RadioGroup = (props: { children: ReactElement; name: string }) => {\n const { children, name } = props;\n const { setFieldValue, values } = useFormikContext() as any;\n function handleChange(e: RadioChangeEvent) {\n setFieldValue(name, e.target.value);\n }\n return (\n \n {children}\n \n );\n};\n\nexport default RadioGroup;\n","export default Array.from(Array(28), (_, i) => i + 1); // returns [1, ..., 28]\n","import styled from 'styled-components';\n\nexport const Root = styled.div`\n .footer-actions {\n display: flex;\n }\n .form-content {\n max-width: 620px;\n margin: 0 auto;\n }\n`;\n\nexport default {};\n","import React from 'react';\nimport { Form } from '@ant-design/compatible';\nimport '@ant-design/compatible/assets/index.css';\nimport { Input, Select, Checkbox } from 'antd';\nimport { formItemHorizontalLayout } from 'constants/form';\nimport useTranslate from 'utils/useTranslate';\nimport messages from 'messages';\n\nconst { Option } = Select;\n\ntype ClaimsType = {\n setFieldValue: (str: string, val: any) => void;\n values: Record;\n label: string;\n id: string;\n onChange: (val: any) => void;\n};\n\nfunction Claims({ setFieldValue, values, label, id, onChange }: ClaimsType) {\n const translate = useTranslate();\n return (\n \n \n \n setFieldValue(`payoutClaim${id}Duration`, e.target.value)\n }\n />\n \n \n {\n onChange(e);\n if (e.target.checked) {\n setFieldValue(`payoutClaim${id}Selected`, '-');\n } else {\n setFieldValue(`payoutClaim${id}Selected`, 'd');\n }\n }}\n >\n {translate(\n id.toLowerCase() === 'expiry'\n ? messages.NO_CLAIM_EXPIRY_TIME\n : messages.NO_CLAIM_OFFSET_TIME\n )}\n \n
\n \n \n );\n}\n\nexport default Claims;\n","export const HEX_COLOR_PATTERN = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;\n\nexport const PERIOD_TIME_PATTERN = /(h|d|m|y)/;\n\nexport default {};\n","import coercedGet from 'utils/coercedGet';\nimport { omit } from 'lodash';\nimport { PERIOD_TIME_PATTERN } from 'constants/regex';\nimport moment from 'moment';\nimport { CreateAffiliateProgrammeScreens } from './context';\nimport { getTierRequirement } from '../../constants';\n\nexport const AffiliateProgrammeSettlementPeriod = {\n WEEKLY: 'WEEKLY',\n MONTHLY: 'MONTHLY',\n BIWEEKLY: 'BIWEEKLY',\n};\n\nexport const getPrevScreen = (currScreen: string) => {\n const screens = Object.values(CreateAffiliateProgrammeScreens);\n const currScreenIdx = screens.findIndex((screen) => screen === currScreen);\n return screens[currScreenIdx > 0 ? currScreenIdx - 1 : currScreenIdx];\n};\n\nexport const getNextScreen = (currScreen: string) => {\n const screens = Object.values(CreateAffiliateProgrammeScreens);\n const currScreenIdx = screens.findIndex((screen) => screen === currScreen);\n return screens[\n currScreenIdx < screens.length - 1 ? currScreenIdx + 1 : currScreenIdx\n ];\n};\n\nconst transformPlatformFeesToHandlers = (\n vendorPlatformFees: Record\n) =>\n vendorPlatformFees.length\n ? vendorPlatformFees.reduce(\n (acc: Record, curr: Record) => ({\n ...acc,\n [`${curr.gameType}_${curr.vendor.id}`]: {\n gameType: curr.gameType,\n vendor: curr.vendor.id,\n minimumCharge: curr.minimumCharge,\n maximumCharge: curr.maximumCharge,\n chargeLevels: curr.chargeLevels.map((l: Record) =>\n omit(\n {\n ...l,\n },\n ['__typename']\n )\n ),\n ggrChargeCostSharing:\n !!(\n coercedGet(curr, 'minimumCharge', 0) ||\n coercedGet(curr, 'maximumCharge', 0) ||\n coercedGet(curr, 'chargeLevels', []).length\n ) || false,\n noMinimumCharge: curr.minimumCharge === 0,\n noMaximumCharge: curr.maximumCharge === 0,\n },\n }),\n {}\n )\n : {};\n\nexport const transformAffiliateData = (data: Record) => {\n if (data.id) {\n const lookup = coercedGet(data, 'levelsRequirement', '');\n const { forActiveMembers, forNetProfit } = getTierRequirement(lookup);\n\n return omit(\n {\n ...data,\n positiveCarryOverEnabled: !!coercedGet(\n data,\n 'positiveCarryOverEnabled',\n false\n ),\n depositTransactionCost:\n coercedGet(data, 'depositTransactionCost', 0) * 100,\n thirdPartyDepositTransactionCost:\n coercedGet(data, 'thirdPartyDepositTransactionCost', 0) * 100,\n withdrawalTransactionCost:\n coercedGet(data, 'withdrawalTransactionCost', 0) * 100,\n thirdPartyWithdrawalTransactionCost:\n coercedGet(data, 'thirdPartyWithdrawalTransactionCost', 0) * 100,\n promoCost: coercedGet(data, 'promoCost', 0) * 100,\n rebateCost: coercedGet(data, 'rebateCost', 0) * 100,\n interestAccountCost: coercedGet(data, 'interestAccountCost', 0) * 100,\n minimumPayoutAccumulationAmount: coercedGet(\n data,\n 'minimumPayoutAccumulationAmount',\n 0\n ),\n payoutClaimOffsetDuration: coercedGet(\n data,\n 'payoutClaimOffsetDuration',\n '0'\n ).replace(/\\D/g, ''),\n payoutClaimExpiryDuration: coercedGet(\n data,\n 'payoutClaimExpiryDuration',\n '0'\n ).replace(/\\D/g, ''),\n payoutExpiryDuration: coercedGet(\n data,\n 'payoutExpiryDuration',\n '0'\n ).replace(/\\D/g, ''),\n payoutClaimOffsetSelected:\n data.payoutClaimOffsetDuration === '0ms'\n ? '-'\n : coercedGet(data, 'payoutExpiryDuration', 'm').match(\n PERIOD_TIME_PATTERN\n )[0],\n payoutClaimExpirySelected:\n data.payoutClaimExpiryDuration === '0ms'\n ? '-'\n : coercedGet(data, 'payoutExpiryDuration', 'm').match(\n PERIOD_TIME_PATTERN\n )[0],\n payoutExpirySelected: coercedGet(\n data,\n 'payoutExpiryDuration',\n 'm'\n ).match(PERIOD_TIME_PATTERN)[0],\n noPayoutClaimOffsetDuration: data.payoutClaimOffsetDuration === '0ms',\n noPayoutClaimExpiryDuration: data.payoutClaimExpiryDuration === '0ms',\n noPayoutExpiryDuration: data.payoutExpiryDuration === '0ms',\n tierRequirement:\n data.levelsRequirement !== 'EITHER' &&\n data.levelsRequirement !== 'BOTH'\n ? [`${data.levelsRequirement}`]\n : ['ACTIVE_MEMBERS_COUNT', 'NET_PROFIT'],\n tierRequirementOperator:\n data.levelsRequirement !== 'EITHER' &&\n data.levelsRequirement !== 'BOTH'\n ? 'BOTH'\n : coercedGet(data, 'levelsRequirement', 'BOTH'),\n vendorHandlers: transformPlatformFeesToHandlers(\n data.vendorPlatformFees\n ),\n settlementTime: moment(\n `${new Date()\n .toISOString()\n .split('T')\n .shift()} ${data.settlementTime}`\n ),\n levels: coercedGet(data, 'levels', []).length\n ? data.levels.map((l: Record, idx: number) => ({\n ...l,\n maximumActiveMembers:\n forActiveMembers && idx !== data.levels.length - 1\n ? data.levels[idx + 1].minimumActiveMembersCount\n : '-',\n maximumNetProfit:\n forNetProfit && idx !== data.levels.length - 1\n ? data.levels[idx + 1].minimumNetProfit\n : '-',\n complete: true,\n completedAt: lookup,\n percentage: coercedGet(l, 'percentage', 0) * 100,\n }))\n : [],\n id: data.id,\n },\n ['key', '__typename']\n );\n }\n return {};\n};\n","import React from 'react';\nimport { Form } from '@ant-design/compatible';\nimport '@ant-design/compatible/assets/index.css';\nimport { Radio, Input, Select as AntdSelect, Checkbox, TimePicker } from 'antd';\nimport { FormattedMessage } from 'react-intl';\nimport Switch from 'pages/components/common/Switch';\nimport Select from 'pages/components/common/Select';\nimport FormItem from 'components/FormItem';\nimport RadioGroup from 'components/RadioGroup';\nimport { formItemHorizontalLayout } from 'constants/form';\n\nimport moment from 'moment';\n\nimport daysOfWeek from 'constants/daysOfWeek';\nimport daysOfMonth from 'constants/daysOfMonth';\nimport messages from 'messages';\nimport useTranslate from 'utils/useTranslate';\nimport { Root } from './styles';\nimport Claims from './components/Claims';\n\nimport { AffiliateProgrammeSettlementPeriod } from '../../../../utils';\n\nconst AffiliateProgrammePayoutMethod = {\n AUTOMATIC_PAYOUT: true,\n MANUAL_PAYOUT: false,\n};\n\nconst { Option } = AntdSelect;\n\nfunction SettlementPeriod({ formProps }: { formProps: Record }) {\n const { setFieldValue, values, handleChange, errors } = formProps;\n const translate = useTranslate();\n\n return (\n \n \n \n \n }\n {...formItemHorizontalLayout}\n colon={false}\n />\n \n \n <>\n \n \n \n \n \n \n >\n \n \n \n ) as any\n }\n value={values.minimumPayoutAccumulationEnabled}\n onChange={(checked) => {\n setFieldValue('minimumPayoutAccumulationEnabled', checked);\n if (!checked) {\n setFieldValue('minimumPayoutAccumulationAmount', 0);\n }\n }}\n checkedChildren={translate(messages['on.text'])}\n unCheckedChildren={translate(messages['off.text'])}\n />\n {values.minimumPayoutAccumulationEnabled && (\n \n }\n validateStatus={\n values.minimumPayoutAccumulationEnabled &&\n errors &&\n errors.minimumPayoutAccumulationAmount &&\n 'error'\n }\n help={\n values.minimumPayoutAccumulationEnabled &&\n errors &&\n errors.minimumPayoutAccumulationAmount\n }\n >\n \n \n )}\n \n }\n validateStatus={\n errors && errors.turnoverRequirementMultiplier && 'error'\n }\n help={errors && errors.turnoverRequirementMultiplier}\n >\n \n \n ) as any\n }\n value={values.settlementPeriod}\n options={[\n {\n id: 'WEEKLY',\n text: translate(messages.WEEKLY),\n },\n {\n id: 'BIWEEKLY',\n text: translate(messages.BIWEEKLY),\n },\n {\n id: 'MONTHLY',\n text: translate(messages.MONTHLY),\n },\n ]}\n onChange={(e) => setFieldValue('settlementPeriod', e)}\n />\n \n {values.period === AffiliateProgrammeSettlementPeriod.WEEKLY && (\n <>{translate(messages.WEEKLY)}>\n )}{' '}\n {values.period === AffiliateProgrammeSettlementPeriod.MONTHLY && (\n <>{translate(messages.MONTHLY)}>\n )}\n {values.period === AffiliateProgrammeSettlementPeriod.BIWEEKLY && (\n <>{translate(messages.BIWEEKLY)}>\n )}\n \n }\n {...formItemHorizontalLayout}\n colon={false}\n />\n {values.settlementPeriod ===\n AffiliateProgrammeSettlementPeriod.BIWEEKLY && (\n \n ) as any\n }\n options={[\n {\n id: '1',\n text: 'First week',\n },\n {\n id: '2',\n text: 'Second week',\n },\n ]}\n value={values.whichWeek || 'First week'}\n onChange={(e) => setFieldValue('whichWeek', e)}\n />\n )}\n {(values.settlementPeriod === AffiliateProgrammeSettlementPeriod.WEEKLY ||\n values.settlementPeriod ===\n AffiliateProgrammeSettlementPeriod.BIWEEKLY) && (\n \n ) as any\n }\n options={\n daysOfWeek.map((q) => ({\n id: q.value,\n text: translate(\n messages[`Every ${q.label}`.replace(' ', '_').toUpperCase()]\n ),\n })) as any\n }\n value={values.settlementDayOfWeek}\n onChange={(e) => setFieldValue('settlementDayOfWeek', e)}\n />\n )}\n {values.settlementPeriod ===\n AffiliateProgrammeSettlementPeriod.MONTHLY && (\n \n ) as any\n }\n options={\n [...daysOfMonth, 29, 30, 31].map((q) => ({\n id: q,\n text: translate(messages.EVERY_DYNAMIC_DAY, {\n day: `${moment.localeData().ordinal(q)}`,\n }),\n })) as any\n }\n value={values.settlementDayOfMonth || 1}\n onChange={(e) => setFieldValue('settlementDayOfMonth', e)}\n />\n )}\n\n \n }\n >\n setFieldValue('settlementTime', value)}\n style={{ width: '50%' }}\n />\n \n \n ) as any\n }\n id=\"Offset\"\n setFieldValue={setFieldValue}\n values={values}\n onChange={handleChange}\n />\n \n ) as any\n }\n id=\"Expiry\"\n setFieldValue={setFieldValue}\n values={values}\n onChange={handleChange}\n />\n \n }\n {...formItemHorizontalLayout}\n >\n \n \n setFieldValue('payoutExpiryDuration', e.target.value)\n }\n />\n setFieldValue('payoutExpirySelected', e)}\n style={{ width: 110 }}\n >\n \n \n \n \n \n {translate(messages.NO_AWARD_EXPIRY_TIME)}\n \n
\n \n \n \n );\n}\n\nexport default SettlementPeriod;\n","import React from 'react';\nimport { useFormikContext } from 'formik';\nimport { Form } from '@ant-design/compatible';\nimport '@ant-design/compatible/assets/index.css';\nimport styled from 'styled-components';\nimport AgentAffiliateProgramme from './components/AgentAffiliateProgramme';\nimport CostSettings from './components/CostSettings';\nimport TierSettings from './components/TierSettings';\nimport SettlementPeriod from './components/SettlementPeriod';\n\nimport {\n useCreateAffiliateProgrammeState,\n CreateAffiliateProgrammeTypes,\n} from '../../context';\n\nfunction InnerForm() {\n const formProps = useFormikContext();\n const [\n createAffiliateProgrammeState,\n ] = useCreateAffiliateProgrammeState() as any;\n return (\n \n \n \n );\n}\n\nconst Root = styled.div`\n .ant-col {\n padding-left: 12px;\n padding-right: 12px;\n }\n`;\n\nexport default InnerForm;\n","import * as Yup from 'yup';\n\nexport const agentAffiliateProgramSchema = {\n name: Yup.string().required('Required'),\n tierRequirement: Yup.array().required('Required'),\n minimumEffectiveBetRequirement: Yup.number()\n .nullable()\n .min(0, 'Invalid amount'),\n minimumDepositRequirement: Yup.number()\n .nullable()\n .min(0, 'Invalid amount'),\n};\n\nexport const costSettingsSchema = {\n vendorHandlers: Yup.array()\n .of(\n Yup.object({\n gameType: Yup.string().required('Required'),\n vendor: Yup.string().required('Required'),\n minimumCharge: Yup.number(),\n noMinimumCharge: Yup.bool(),\n maximumCharge: Yup.number(),\n noMaximumCharge: Yup.bool(),\n ggrChargeCostSharing: Yup.bool().required(),\n chargeLevels: Yup.array()\n .of(\n Yup.object({\n minimumTotalWinloss: Yup.number(),\n percentage: Yup.number(),\n })\n )\n .nullable(),\n })\n )\n .nullable(),\n};\n\nexport const settlementPeriodSchema = {\n minimumPayoutAccumulationAmount: Yup.number()\n .required('Required')\n .min(0, 'Invalid amount'),\n turnoverRequirementMultiplier: Yup.number()\n .nullable()\n .min(0, 'Invalid amount'),\n};\nexport const tierSettingsSchema = {};\n\nexport const formSchemas = [\n agentAffiliateProgramSchema,\n costSettingsSchema,\n settlementPeriodSchema,\n tierSettingsSchema,\n];\n","import { defineMessages } from 'react-intl';\n\nconst messages = defineMessages({\n 'agent-affiliate-programme.text': {\n id: 'agent-affiliate-programme.text',\n defaultMessage: 'Agent Affiliate Programme',\n },\n 'agent-affiliate.create-affiliate-programme-saved.text': {\n id: 'agent-affiliate.create-affiliate-programme-saved.text',\n defaultMessage: 'The affiliate programme has been saved successfully.',\n },\n 'agent-affiliate.create-affiliate-programme-updated.text': {\n id: 'agent-affiliate.create-affiliate-programme-updated.text',\n defaultMessage: 'The affiliate programme has been updated successfully.',\n },\n 'agent-affiliate.create-affiliate-programme-published.text': {\n id: 'agent-affiliate.create-affiliate-programme-published.text',\n defaultMessage: 'The affiliate programme has been published successfully.',\n },\n 'agent-affiliate.create-affiliate-programme-error.text': {\n id: 'agent-affiliate.create-affiliate-programme-error.text',\n defaultMessage: 'There were errors processing your request.',\n },\n 'agent-affiliate.existing-default-affiliate-programme-error.text': {\n id: 'agent-affiliate.existing-default-affiliate-programme-error.text',\n defaultMessage: 'A default programme already exists.',\n },\n 'agent-affiliate.no-tiers-affiliate-programme-error.text': {\n id: 'agent-affiliate.no-tiers-affiliate-programme-error.text',\n defaultMessage: 'Please provide at least one completed tier.',\n },\n 'agent-affiliate.no-complete-tier-details-affiliate-programme-error.text': {\n id:\n 'agent-affiliate.no-complete-tier-details-affiliate-programme-error.text',\n defaultMessage: 'Please complete tier details.',\n },\n 'cost-settings.text': {\n id: 'cost-settings.text',\n defaultMessage: 'Cost Settings',\n },\n 'settlement-period.text': {\n id: 'settlement-period.text',\n defaultMessage: 'Settlement Period',\n },\n 'tier-settings.text': {\n id: 'tier-settings.text',\n defaultMessage: 'Tier Settings',\n },\n});\n\nexport default messages;\n","import { useMutation } from '@apollo/react-hooks';\nimport { Button, message, Steps } from 'antd';\nimport { Formik } from 'formik';\nimport {\n CREATE_AFFILIATE_PROGRAMME,\n SUBMIT_AFFILIATE_PROGRAMME,\n UPDATE_AFFILIATE_PROGRAMME,\n} from 'graphql/mutations/affiliateProgramme.mutation';\nimport { AFFILIATE_PROGRAMMES } from 'graphql/queries/affiliateProgramme.query';\nimport { omit } from 'lodash';\nimport {\n AffiliateTypes,\n useAffiliateState,\n} from 'pages/components/AffiliateProgramme/context';\nimport Drawer from 'pages/components/common/Drawer/Drawer';\nimport messages from 'messages';\nimport moment from 'moment';\nimport ms from 'ms';\nimport React from 'react';\nimport { FormattedMessage } from 'react-intl';\nimport coercedGet from 'utils/coercedGet';\nimport useTranslate from 'utils/useTranslate';\nimport * as Yup from 'yup';\nimport { getTierRequirement } from '../../constants';\nimport InnerForm from './components/InnerForm/InnerForm';\nimport { formSchemas } from './constants';\nimport {\n CreateAffiliateProgrammeScreens,\n CreateAffiliateProgrammeTypes,\n useCreateAffiliateProgrammeState,\n} from './context';\nimport localMessages from './messages';\nimport {\n AffiliateProgrammeSettlementPeriod,\n getNextScreen,\n getPrevScreen,\n transformAffiliateData,\n} from './utils';\n\nfunction CreateAffiliateProgramme() {\n const [isSubmitting, setIsSubmitting] = React.useState(false);\n const [isLoading, setIsLoading] = React.useState(false);\n\n const [\n createAffiliateProgrammeState,\n createAffiliateProgrammeDispatch,\n ] = useCreateAffiliateProgrammeState();\n\n const SubmissionModes = {\n CREATE: 'CREATE',\n UPDATE: 'UPDATE',\n SUBMIT: 'SUBMIT',\n };\n\n const FormEvents = {\n EXITS: true,\n STAYS: false,\n HIDE_ALERTS: false,\n };\n\n const ErrorTypes = {\n DEFAULT: 'DEFAULT',\n NO_TIERS: 'NO_TIERS',\n INCOMPLETE_TIERS: 'INCOMPLETE_TIERS',\n };\n const translate = useTranslate();\n\n const successMessage = (text: string) => {\n message.success(translate(localMessages[`${text}`]));\n };\n\n const success = (mode: any) => {\n switch (mode) {\n case SubmissionModes.CREATE: {\n successMessage('agent-affiliate.create-affiliate-programme-saved.text');\n break;\n }\n case SubmissionModes.UPDATE: {\n successMessage(\n 'agent-affiliate.create-affiliate-programme-updated.text'\n );\n break;\n }\n case SubmissionModes.SUBMIT: {\n successMessage(\n 'agent-affiliate.create-affiliate-programme-published.text'\n );\n break;\n }\n default:\n break;\n }\n };\n\n const errorMessage = (text: string) => {\n message.error(translate(localMessages[`${text}`]));\n };\n\n const error = (errorType: any) => {\n switch (errorType) {\n case ErrorTypes.DEFAULT: {\n errorMessage(\n 'agent-affiliate.existing-default-affiliate-programme-error.text'\n );\n break;\n }\n case ErrorTypes.NO_TIERS: {\n errorMessage('agent-affiliate.no-tiers-affiliate-programme-error.text');\n break;\n }\n case ErrorTypes.INCOMPLETE_TIERS: {\n errorMessage(\n 'agent-affiliate.no-complete-tier-details-affiliate-programme-error.text'\n );\n break;\n }\n default:\n errorMessage('agent-affiliate.create-affiliate-programme-error.text');\n break;\n }\n };\n\n const steps = {\n [CreateAffiliateProgrammeScreens.AGENT_AFFILIATE_PROGRAMME_SCREEN]: translate(\n messages.AGENT_AFFILIATE_PROGRAMME\n ),\n [CreateAffiliateProgrammeScreens.COST_SETTINGS_SCREEN]: translate(\n messages.COST_SETTINGS\n ),\n [CreateAffiliateProgrammeScreens.SETTLEMENT_PERIOD_SCREEN]: translate(\n messages.SETTLEMENT_PERIOD\n ),\n [CreateAffiliateProgrammeScreens.TIER_SETTINGS_SCREEN]: translate(\n messages.TIER_SETTINGS\n ),\n };\n\n const formRef = React.useRef(null);\n const [affiliateState, affiliateDispatch] = useAffiliateState() as any;\n\n const [createAffiliateMutation] = useMutation(CREATE_AFFILIATE_PROGRAMME);\n const [updateAffiliateMutation] = useMutation(UPDATE_AFFILIATE_PROGRAMME);\n const [submitAffiliateMutation] = useMutation(SUBMIT_AFFILIATE_PROGRAMME);\n\n const formAction = {\n [SubmissionModes.CREATE]: createAffiliateMutation,\n [SubmissionModes.UPDATE]: updateAffiliateMutation,\n [SubmissionModes.SUBMIT]: submitAffiliateMutation,\n };\n\n const submit = async (mode = '', enableExit = false, enableAlert = true) => {\n setIsLoading(true);\n if (mode === SubmissionModes.SUBMIT || enableExit) {\n setIsSubmitting(true);\n }\n\n const formik = formRef.current;\n const { values } = formik;\n\n const levelsRequirement =\n values.tierRequirement.length === 2\n ? values.tierRequirementOperator\n : values.tierRequirement[0];\n\n const { forActiveMembers, forNetProfit } = getTierRequirement(\n levelsRequirement\n );\n\n const levels = values.levels\n .map((level: Record) => {\n if (level.complete) {\n return omit(\n {\n ...level,\n minimumActiveMembersCount: forActiveMembers\n ? +level.minimumActiveMembersCount\n : 0,\n maximumActiveMembers: forActiveMembers\n ? +level.maximumActiveMembers\n : 0,\n minimumNetProfit: forNetProfit ? +level.minimumNetProfit : 0,\n maximumNetProfit: forNetProfit ? +level.maximumNetProfit : 0,\n percentage: level.percentage\n ? +(level.percentage / 100).toFixed(2)\n : 0,\n },\n [\n 'key',\n 'complete',\n 'completedAt',\n 'number',\n 'maximumActiveMembers',\n 'maximumNetProfit',\n '__typename',\n ]\n );\n }\n return undefined;\n })\n .filter((item: any) => item !== undefined);\n\n const payoutClaimOffsetDuration =\n ms(\n `${\n values.noPayoutClaimOffsetDuration\n ? 0\n : values.payoutClaimOffsetDuration\n }${\n values.payoutClaimOffsetSelected === '-'\n ? 'ms'\n : values.payoutClaimOffsetSelected\n }`\n ) || 0;\n\n const payoutClaimExpiryDuration =\n ms(\n `${\n values.noPayoutClaimExpiryDuration\n ? 0\n : values.payoutClaimExpiryDuration\n }${\n values.payoutClaimExpirySelected === '-'\n ? 'ms'\n : values.payoutClaimExpirySelected\n }`\n ) || 0;\n\n const payoutExpiryDuration =\n ms(\n `${values.noPayoutExpiryDuration ? 0 : values.payoutExpiryDuration}${\n values.payoutExpirySelected\n }`\n ) || 0;\n\n const settlementTime = values.settlementTime\n ?.toISOString()\n ?.split('T')\n ?.pop();\n\n const vendorPlatformFees = Object.entries(values.vendorHandlers)\n .map((e: any) => {\n if (e[1].ggrChargeCostSharing) {\n const minimumCharge =\n !e[1].minimumCharge || e[1].noMinimumCharge\n ? 0\n : +e[1].minimumCharge;\n const maximumCharge =\n !e[1].maximumCharge || e[1].noMaximumCharge\n ? 0\n : +e[1].maximumCharge;\n const chargeLevels = e[1].chargeLevels ? e[1].chargeLevels : [];\n return omit({ ...e[1], minimumCharge, maximumCharge, chargeLevels }, [\n 'ggrChargeCostSharing',\n 'noMinimumCharge',\n 'noMaximumCharge',\n ]);\n }\n return undefined;\n })\n .filter((item) => item !== undefined && item.vendor);\n\n const costs = {\n depositTransactionCost: values.depositTransactionCost\n ? +(values.depositTransactionCost / 100).toFixed(2)\n : 0,\n thirdPartyDepositTransactionCost: values.thirdPartyDepositTransactionCost\n ? +(values.thirdPartyDepositTransactionCost / 100).toFixed(2)\n : 0,\n withdrawalTransactionCost: values.withdrawalTransactionCost\n ? +(values.withdrawalTransactionCost / 100).toFixed(2)\n : 0,\n thirdPartyWithdrawalTransactionCost: values.thirdPartyWithdrawalTransactionCost\n ? +(values.thirdPartyWithdrawalTransactionCost / 100).toFixed(2)\n : 0,\n promoCost: values.promoCost ? +(values.promoCost / 100).toFixed(2) : 0,\n rebateCost: values.rebateCost ? +(values.rebateCost / 100).toFixed(2) : 0,\n interestAccountCost: values.interestAccountCost\n ? +(values.interestAccountCost / 100).toFixed(2)\n : 0,\n };\n\n const newValues = {\n levelsRequirement,\n payoutClaimOffsetDuration: `${payoutClaimOffsetDuration}`,\n payoutClaimExpiryDuration: `${payoutClaimExpiryDuration}`,\n payoutExpiryDuration: `${payoutExpiryDuration}`,\n settlementTime,\n levels,\n vendorPlatformFees,\n settlementDayOfMonth: values.settlementDayOfMonth\n ? values.settlementDayOfMonth\n : 1,\n description: values.description !== null ? values.description : '',\n minimumDepositRequirement:\n values.minimumDepositRequirement !== null\n ? +values.minimumDepositRequirement\n : 0,\n minimumEffectiveBetRequirement:\n values.minimumEffectiveBetRequirement !== null\n ? +values.minimumEffectiveBetRequirement\n : 0,\n turnoverRequirementMultiplier:\n values.turnoverRequirementMultiplier !== null\n ? +values.turnoverRequirementMultiplier\n : 0,\n ...costs,\n };\n\n const omittedFields = [\n 'tierRequirement',\n 'tierRequirementOperator',\n 'noPayoutClaimOffsetDuration',\n 'noPayoutClaimExpiryDuration',\n 'noPayoutExpiryDuration',\n 'payoutClaimOffsetSelected',\n 'payoutClaimExpirySelected',\n 'payoutExpirySelected',\n 'vendorHandlers',\n 'whichWeek',\n 'membersCount',\n 'positiveCarryOverEnabled',\n 'id',\n 'status',\n 'vendorHandler',\n ];\n\n let input = { ...values, ...newValues };\n\n input = omit(input, omittedFields);\n\n // VALIDATION CHECKING FOR TIERS\n\n let types = [] as any;\n\n const noLevels = formRef.current.values.levels.length === 0;\n\n const incompletedLevels =\n !noLevels &&\n (\n coercedGet(formRef.current.values, 'levels', []).filter(\n (l: Record) => l.complete\n ) || []\n ).length !== formRef.current.values.levels.length;\n\n if (noLevels && mode === SubmissionModes.SUBMIT) {\n types = [...types, ErrorTypes.NO_TIERS];\n }\n\n if (incompletedLevels && mode === SubmissionModes.SUBMIT) {\n types = [...types, ErrorTypes.INCOMPLETE_TIERS];\n }\n if (types.length) {\n types.map((t: any) => error(t));\n setIsLoading(false);\n setIsSubmitting(false);\n return false;\n }\n\n // VALIDATION CHECKING FOR TIERS END\n\n try {\n const formAffiliateMutation = formAction[mode];\n\n if (mode === SubmissionModes.SUBMIT) {\n await updateAffiliateMutation({\n variables: { id: values.id, input },\n });\n }\n\n const res = await formAffiliateMutation({\n variables: {\n ...(mode !== SubmissionModes.SUBMIT && { input }),\n ...(mode !== SubmissionModes.CREATE && { id: values.id }),\n },\n ...(mode !== SubmissionModes.SUBMIT && {\n refetchQueries: [\n {\n query: AFFILIATE_PROGRAMMES,\n variables: affiliateState.refetchVariables,\n },\n ],\n }),\n });\n\n if (\n mode === SubmissionModes.SUBMIT &&\n res?.data?.submitAffiliateProgramme\n ) {\n await updateAffiliateMutation({\n variables: {\n id: values.id,\n input: {\n enabled: true,\n },\n },\n refetchQueries: [\n {\n query: AFFILIATE_PROGRAMMES,\n variables: affiliateState.refetchVariables,\n },\n ],\n });\n }\n\n if (mode === SubmissionModes.CREATE) {\n formik.setFieldValue(\n 'id',\n coercedGet(res, 'data.createAffiliateProgramme', '')\n );\n }\n\n if (enableAlert) {\n success(mode);\n }\n\n if (enableExit) {\n formRef.current.resetForm();\n affiliateDispatch({\n type: AffiliateTypes.RESET_ACTIVE_AFFILIATE_PROGRAMME,\n });\n createAffiliateProgrammeDispatch({\n type: CreateAffiliateProgrammeTypes.SET_ACTIVE_SCREEN,\n payload:\n CreateAffiliateProgrammeTypes.AGENT_AFFILIATE_PROGRAMME_SCREEN,\n });\n affiliateDispatch({\n type: AffiliateTypes.HIDE_CREATE_AFFILIATE_PROGRAMME,\n });\n }\n return res;\n } catch (e) {\n const isDefault = coercedGet(formRef?.current?.values, 'default', false);\n\n if (isDefault) {\n error(ErrorTypes.DEFAULT);\n }\n\n return e;\n } finally {\n setIsLoading(false);\n if (mode === SubmissionModes.SUBMIT || enableExit) {\n setIsSubmitting(false);\n }\n }\n };\n\n React.useImperativeHandle(formRef, () => ({\n ...formRef.current,\n handleSubmit: () => submit,\n }));\n\n React.useEffect(() => {\n document.body.classList.remove('create-affiliate-programme-drawer-shown');\n if (affiliateState.showCreateAffiliateProgramme) {\n document.body.classList.add('create-affiliate-programme-drawer-shown');\n }\n }, [affiliateState.showCreateAffiliateProgramme]);\n\n const createAffiliateProgrammeValues = Object.values(\n CreateAffiliateProgrammeScreens\n );\n\n const activeScreenIndex =\n createAffiliateProgrammeValues.findIndex(\n (screen) => screen === createAffiliateProgrammeState.activeScreen\n ) || 0;\n\n const validationSchema = Yup.object().shape({\n ...formSchemas[activeScreenIndex],\n });\n\n const RenderLeftButtons = () => {\n const screen = getPrevScreen(createAffiliateProgrammeState.activeScreen);\n\n switch (createAffiliateProgrammeState.activeScreen) {\n case CreateAffiliateProgrammeScreens.AGENT_AFFILIATE_PROGRAMME_SCREEN:\n return (\n \n );\n case CreateAffiliateProgrammeScreens.SETTLEMENT_PERIOD_SCREEN:\n case CreateAffiliateProgrammeScreens.COST_SETTINGS_SCREEN:\n case CreateAffiliateProgrammeScreens.TIER_SETTINGS_SCREEN:\n return (\n \n );\n default:\n return <>>;\n }\n };\n\n const costSettingsOpen =\n createAffiliateProgrammeState.activeScreen === 'COST_SETTINGS_SCREEN';\n\n const RenderRightButtons = () => {\n const screen = getNextScreen(createAffiliateProgrammeState.activeScreen);\n\n const continueButton = (\n \n );\n\n const publishButton = (\n \n );\n\n switch (createAffiliateProgrammeState.activeScreen) {\n case CreateAffiliateProgrammeScreens.AGENT_AFFILIATE_PROGRAMME_SCREEN:\n case CreateAffiliateProgrammeScreens.SETTLEMENT_PERIOD_SCREEN:\n case CreateAffiliateProgrammeScreens.COST_SETTINGS_SCREEN:\n return continueButton;\n case CreateAffiliateProgrammeScreens.TIER_SETTINGS_SCREEN:\n return publishButton;\n default:\n return <>>;\n }\n };\n\n const defaultValues = {\n vendorHandler: { ...affiliateState.vendorHandlers },\n ...transformAffiliateData({\n ...affiliateState.activeAffiliateData,\n }),\n };\n\n const initialValues = {\n id: '',\n name: '',\n description: null,\n default: false,\n automaticPayoutClaiming: false,\n negativeCarryOverEnabled: false,\n positiveCarryOverEnabled: false,\n vendorPlatformFees: [],\n depositTransactionCost: 100,\n thirdPartyDepositTransactionCost: 100,\n withdrawalTransactionCost: 100,\n thirdPartyWithdrawalTransactionCost: 100,\n promoCost: 100,\n rebateCost: 100,\n interestAccountCost: 100,\n minimumEffectiveBetRequirement: null,\n minimumDepositRequirement: null,\n minimumPayoutAccumulationEnabled: false,\n minimumPayoutAccumulationAmount: 0,\n turnoverRequirementMultiplier: null,\n settlementPeriod: AffiliateProgrammeSettlementPeriod.WEEKLY,\n settlementTime: moment().startOf('day'),\n settlementDayOfWeek: 0,\n settlementDayOfMonth: 0,\n payoutClaimOffsetDuration: null,\n payoutClaimExpiryDuration: null,\n payoutExpiryDuration: null,\n payoutClaimOffsetSelected: 'd',\n payoutClaimExpirySelected: 'd',\n payoutExpirySelected: 'd',\n noPayoutClaimOffsetDuration: false,\n noPayoutClaimExpiryDuration: false,\n noPayoutExpiryDuration: false,\n levels: [],\n levelsRequirement: null,\n tierRequirement: [],\n tierRequirementOperator: 'BOTH',\n whichWeek: 0,\n vendorHandlers: [],\n ...defaultValues,\n };\n\n return (\n \n affiliateDispatch({\n type: AffiliateTypes.HIDE_CREATE_AFFILIATE_PROGRAMME,\n })\n }\n >\n \n <>\n {!isSubmitting ? (\n \n ) : (\n ''\n )}\n >\n \n \n \n
\n \n {Object.entries(steps).map((item) => (\n \n ))}\n \n {}}\n innerRef={formRef}\n initialValues={initialValues}\n validationSchema={validationSchema}\n enableReinitialize\n >\n {() => }\n \n
\n
\n \n \n \n \n \n \n
\n \n \n );\n}\n\nexport default CreateAffiliateProgramme;\n","import React, { useEffect, useState } from 'react';\nimport { Tag } from 'antd';\nimport { isEmpty } from 'lodash';\nimport { AffiliateProgrammesFilterInput } from 'types/graphqlTypes';\n\ntype filterConditionsProps = {\n filters: AffiliateProgrammesFilterInput;\n onFilterChange: (e: AffiliateProgrammesFilterInput) => void;\n};\n\nconst FilterConditions = ({\n filters,\n onFilterChange,\n}: filterConditionsProps) => {\n const [localStateFilter, setLocalStateFilter] = useState<\n AffiliateProgrammesFilterInput\n >({});\n\n useEffect(() => {\n setLocalStateFilter(filters || {});\n }, [filters, setLocalStateFilter]);\n\n const handleRemoveProgrammeName = (\n value: string,\n e: { preventDefault: () => void }\n ) => {\n e.preventDefault();\n const { name } = filters;\n const data = name?.in?.filter((item: string) => item !== value);\n const newProgrammeName = {\n in: data,\n };\n onFilterChange({\n ...filters,\n name: data?.length ? newProgrammeName : null,\n });\n };\n\n const handleRemoveStatus = (\n value: string,\n e: { preventDefault: () => void }\n ) => {\n e.preventDefault();\n const { status } = filters;\n const data = status?.in?.filter((item: string) => item !== value);\n const newStatus = {\n in: data,\n };\n onFilterChange({\n ...filters,\n status: data?.length ? newStatus : null,\n });\n };\n\n const handleRemoveDefault = (e: { preventDefault: () => void }) => {\n e.preventDefault();\n onFilterChange({\n ...filters,\n default: null,\n });\n };\n\n const handleRemoveNegativeCarry = (e: { preventDefault: () => void }) => {\n e.preventDefault();\n onFilterChange({\n ...filters,\n negativeCarryOverEnabled: null,\n });\n };\n\n return (\n <>\n {localStateFilter?.name?.in?.map((item: string, key: number) => (\n void }) =>\n handleRemoveProgrammeName(item, e)\n }\n >\n {item}\n \n ))}\n\n {localStateFilter?.status?.in?.map((item: string, key: number) => (\n void }) =>\n handleRemoveStatus(item, e)\n }\n >\n {item}\n \n ))}\n\n {!isEmpty(localStateFilter.default) && (\n void }) =>\n handleRemoveDefault(e)\n }\n >\n Default Program: {localStateFilter?.default?.in ? 'Yes' : 'No'}\n \n )}\n\n {!isEmpty(localStateFilter.negativeCarryOverEnabled) && (\n void }) =>\n handleRemoveNegativeCarry(e)\n }\n >\n Negative Carry:{' '}\n {localStateFilter?.negativeCarryOverEnabled?.in ? 'Yes' : 'No'}\n \n )}\n >\n );\n};\n\nexport default FilterConditions;\n","import { useEffect, useState } from 'react';\n\n// eslint-disable-next-line import/prefer-default-export\nexport function useDebounce(value: number | string, delay: number) {\n // State and setters for debounced value\n const [debouncedValue, setDebouncedValue] = useState(value);\n\n useEffect(\n () => {\n // Set debouncedValue to value (passed in) after the specified delay\n const handler = setTimeout(() => {\n setDebouncedValue(value);\n }, delay);\n\n // Return a cleanup function that will be called every time ...\n // ... useEffect is re-called. useEffect will only be re-called ...\n // ... if value changes (see the inputs array below).\n // This is how we prevent debouncedValue from changing if value is ...\n // ... changed within the delay period. Timeout gets cleared and restarted.\n // To put it in context, if the user is typing within our app's ...\n // ... search box, we don't want the debouncedValue to update until ...\n // ... they've stopped typing for more than 500ms.\n return () => {\n clearTimeout(handler);\n };\n },\n // Only re-call effect if value changes\n // You could also add the \"delay\" var to inputs array if you ...\n // ... need to be able to change that dynamically.\n [value, delay]\n );\n\n return debouncedValue;\n}\n","export const getPartialKey = (): string =>\n localStorage.getItem('locale') === 'en' ? 'Partial: ' : '部分: ';\n\nexport const isPartialString = (str: string) => str.includes(getPartialKey());\n","import React from 'react';\nimport {\n uniqBy,\n isEqual,\n partialRight,\n uniq,\n isBoolean,\n isNumber,\n isEmpty,\n forOwn,\n isArray,\n} from 'lodash';\nimport { useQuery, useLazyQuery } from '@apollo/react-hooks';\nimport { DocumentNode } from 'graphql';\nimport { DynamicObj } from 'interfaces/user.interface';\nimport removeNull from 'utils/removeNull';\n\nimport { getPartialKey } from 'constants/partialFilterKey';\nimport { WatchQueryFetchPolicy } from 'apollo-client';\nimport { useOperatorHeader } from 'utils/useOperatorHeader';\nimport coercedGet from './coercedGet';\n\ntype FilterObjectType = DynamicObj;\n\ntype PageStateType = {\n first: number;\n after: undefined | string;\n savedCursor: (string | undefined)[];\n currentPage: number;\n sort?: string;\n};\n\ntype PartialFilterStateType = {\n partialKeys: any[];\n savedFilts: FilterObjectType;\n};\n\ntype FilterValueType = string | number | boolean;\n\nexport const checkPartial = (filterKey: string, state: FilterObjectType) => {\n if (\n coercedGet(state, filterKey) &&\n state[filterKey].in &&\n state[filterKey].in.length\n ) {\n return state[filterKey].in.some(\n (filter: string) =>\n filter &&\n !isBoolean(filter) &&\n !isNumber(filter) &&\n filter.includes(getPartialKey())\n );\n }\n\n return false;\n};\n\nexport const getPartialString = (\n filtKey: string,\n filtObj: FilterObjectType\n) => {\n if (coercedGet(filtObj, filtKey) && filtObj[filtKey].in.length) {\n return filtObj[filtKey].in\n .find((str: string) => str.includes(getPartialKey()))\n .slice(getPartialKey().length);\n }\n return null;\n};\n\n// purpose for this func is to extract and use the Partial string\n// from the filter object\nconst getProcessedPartialFilters = (\n filterObj: FilterObjectType,\n filtFields: string[]\n) => {\n const newFilterObj = { ...filterObj };\n\n const isFiltField = (filtKey: string) => filtFields.includes(filtKey);\n\n return Object.entries(newFilterObj).reduce((acc, curr) => {\n const [key, value] = curr;\n\n if (checkPartial(key, newFilterObj)) {\n acc[key] = isFiltField(key)\n ? {\n contains: getPartialString(key, newFilterObj),\n }\n : null;\n }\n return {\n [key]: value,\n ...acc,\n };\n }, {});\n};\n\n// specific partial filter \"function creator\" provided the specific module\n\nexport const sortTransform = {\n ascend: 'ASC',\n descend: 'DESC',\n};\n\nexport const getUnpaginatedTableData = (\n dataPath: string,\n tableData: object,\n customKey?: string\n) => {\n const mainResults = coercedGet(tableData, dataPath, {});\n const partialResults = coercedGet(tableData, 'partial', {});\n\n const edges = coercedGet(mainResults, 'edges', []);\n const partialEdges = coercedGet(partialResults, 'edges', []);\n const combination = [...edges, ...partialEdges];\n const uniqueCombinedEdges = uniqBy(combination, `node.${customKey}`);\n\n const uniqueTableData = uniqueCombinedEdges.map((edge) => edge.node);\n\n return uniqueTableData.length ? uniqueTableData : [];\n};\n\n/**\n * @desc Remove partials from the filter passed\n * @author Milfren John dela Vega | nerflim\n * @todo unit testing\n * @param filter\n */\n\nconst removePartialFilter = (filter: FilterObjectType) => {\n const populatedFilters = removeNull(filter);\n\n return Object.keys(populatedFilters).reduce((acc, curr) => {\n const noPartials = {};\n\n forOwn(populatedFilters[curr], (value, key) => {\n noPartials[curr] = {\n ...noPartials[curr],\n [key]: isArray(value)\n ? value.filter(\n (fItem: FilterValueType) =>\n typeof fItem !== 'string' || !fItem.includes(getPartialKey())\n ) || []\n : value,\n };\n });\n\n return {\n ...acc,\n ...noPartials,\n };\n }, {});\n};\n\n/**\n * @desc Retain partials from the filter passed\n * @author Milfren John dela Vega | nerflim\n * @todo unit testing\n * @param filter\n */\nconst getPartialFilter = (\n filter: FilterObjectType,\n filtFields: string[],\n extraFilter: FilterObjectType\n) => {\n const populatedFilters = removeNull(filter);\n\n const partials = Object.keys(populatedFilters).reduce((acc, curr) => {\n if (checkPartial(curr, populatedFilters) && filtFields.includes(curr)) {\n return {\n ...acc,\n [curr]: { contains: getPartialString(curr, populatedFilters) },\n };\n }\n\n return {\n ...acc,\n };\n }, {});\n\n return isEmpty(partials) ? partials : { ...partials, ...extraFilter };\n};\n\nexport const usePartialFiltersQuery = (\n query1: DocumentNode,\n query2: DocumentNode,\n edgesPath: string, // eg. 'memberBetRecords.edges'\n rawFilters: FilterObjectType,\n pageState: PageStateType,\n filtFields: string[],\n fetchPolicy: WatchQueryFetchPolicy = 'cache-and-network',\n customKey?: string,\n extraPartialFilter: FilterObjectType = {}, // this will be added to the partial query without getting modified\n preAppliedFilter: boolean = true // to prevent initial load of query, only call query when filter is applied | used in MBR abd BTR\n) => {\n const processedFilters = React.useMemo(\n () => removePartialFilter(rawFilters),\n [rawFilters]\n );\n\n const processedPartialFilters = React.useMemo(\n () => getPartialFilter(rawFilters, filtFields, extraPartialFilter),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [rawFilters]\n );\n\n const mixedFilters = {\n filter: processedFilters,\n partialFilter: processedPartialFilters,\n };\n\n const queryPath = edgesPath.replace(/.edges/g, '');\n\n const initialState = {\n partialKeys: [],\n savedFilts: {},\n } as PartialFilterStateType;\n\n const [partialFilterState, setPartialFilterState] = React.useState(\n initialState\n );\n\n const { partialKeys, savedFilts } = partialFilterState;\n\n const { context } = useOperatorHeader();\n\n // customKey is used when you want to enable partial filtering using its own filter field and not the id\n // make sure to pass filter field key string to customKey props\n const filterKey = customKey || 'id';\n\n // query 1\n const [\n loadPartialQueries,\n { loading: loading1, error: error1 },\n ] = useLazyQuery(query1, {\n fetchPolicy,\n variables: mixedFilters,\n context,\n onError: () => {\n setPartialFilterState((prev) => ({\n ...prev,\n partialKeys: [],\n }));\n },\n\n onCompleted: (data: any) => {\n const preEdges = getUnpaginatedTableData(queryPath, data, filterKey);\n\n const queriedIdentifiers = preEdges.map((item) => item[filterKey]);\n\n if (queriedIdentifiers.length)\n return setPartialFilterState((prev) => ({\n ...prev,\n partialKeys: queriedIdentifiers,\n }));\n\n return setPartialFilterState((prev) => ({\n ...prev,\n partialKeys: [],\n }));\n },\n });\n\n React.useEffect(() => {\n if (\n !isEmpty(processedPartialFilters) &&\n !partialKeys.length &&\n preAppliedFilter\n ) {\n loadPartialQueries({\n variables: mixedFilters,\n });\n return;\n }\n if (isEmpty(processedPartialFilters) && partialKeys.length) {\n setPartialFilterState(initialState);\n return;\n }\n\n if (\n !isEmpty(processedPartialFilters) &&\n !isEqual(savedFilts, processedFilters) &&\n preAppliedFilter\n ) {\n loadPartialQueries({\n variables: mixedFilters,\n });\n setPartialFilterState((prev: PartialFilterStateType) => ({\n ...prev,\n savedFilts: processedFilters,\n }));\n }\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [rawFilters]);\n\n const finalQueryFilter = React.useMemo(\n () =>\n partialKeys.length\n ? {\n [filterKey]: {\n in: [...partialKeys],\n },\n }\n : processedFilters,\n [partialKeys, processedFilters, filterKey]\n );\n\n const memPageState = React.useMemo(() => pageState, [pageState]);\n\n const refetchVariables = React.useMemo(\n () => ({\n first: memPageState.first,\n after: memPageState.after,\n filter: finalQueryFilter,\n }),\n [finalQueryFilter, memPageState.after, memPageState.first]\n );\n\n const {\n loading: loading2,\n error: error2,\n data: queryData = {},\n refetch,\n } = useQuery(query2, {\n variables: refetchVariables,\n fetchPolicy,\n context,\n skip: !preAppliedFilter,\n });\n\n return {\n data: queryData,\n loading: loading1 || loading2,\n error: error1 || error2,\n refetchVariables,\n refetch,\n finalQueryFilter,\n };\n};\n\nexport const getMbrPartialFilters = partialRight(getProcessedPartialFilters, [\n 'serialCode',\n 'gameCategory',\n 'gameSubCategory',\n 'platformId',\n 'brandId',\n 'round',\n]);\n\n// to avoid API error when having \"Partial:\" with Id based filters e.g member: {in : [\"Partial: \"]}\n// will remove partial S\nconst removePartialStrings = (\n filterObj: Record,\n removeFields: Array\n) => {\n if (!removeFields || !removeFields.length) return filterObj;\n\n const newFiltObj = { ...filterObj };\n\n const isRemovableField = (filtKey: string) => removeFields.includes(filtKey);\n\n return Object.entries(newFiltObj).reduce((acc, curr) => {\n const [key, value] = curr;\n\n if (checkPartial(key, newFiltObj) && isRemovableField(key)) {\n const inValue = value.in.filter(\n (item: string) => !item.includes(getPartialKey())\n );\n\n // @ts-ignore\n acc[key] = inValue.length\n ? {\n in: inValue,\n }\n : null;\n }\n\n return {\n [key]: value,\n ...acc,\n };\n }, {});\n};\n\nconst neutQuery = (filtObj: FilterObjectType) => {\n const newObj = Object.entries(filtObj).reduce((acc: any, curr: any) => {\n const key = curr[0];\n const val = curr[1];\n\n if (checkPartial(key, filtObj)) {\n const inValue = val.in.filter(\n (item: string) => !item.includes(getPartialKey())\n );\n acc[key] = {\n in: inValue,\n };\n }\n\n return {\n [key]: val,\n ...acc,\n };\n }, {});\n\n return newObj;\n};\n\nexport const checkPartialExist = (procFilts: FilterObjectType) => {\n const filtKeys = Object.keys(procFilts);\n return filtKeys.some((filtKey) => checkPartial(filtKey, procFilts));\n};\n\ntype IDQueryObjectType = {\n query: any;\n sourceFiltFields: Array;\n targetStringFields: Array;\n targetFilterFields: Array;\n};\n\nexport const createPartialUtil = (\n identifier?: string,\n processorFunc?: ((filt: FilterObjectType) => FilterObjectType) | null,\n fetchPolicy?: WatchQueryFetchPolicy\n) => (\n query1: DocumentNode,\n query2: DocumentNode,\n edgesPath: string, // eg. 'memberBetRecords.edges'\n initialFilters: FilterObjectType,\n pageState: PageStateType,\n filtFields: string[],\n idQueryObject?: IDQueryObjectType,\n language?: string\n) => {\n const hasProcessorFunc = processorFunc && typeof processorFunc === 'function';\n const { context } = useOperatorHeader();\n\n const procFilters = hasProcessorFunc\n ? processorFunc && processorFunc(initialFilters)\n : initialFilters;\n\n const memProcFilts = React.useMemo(() => procFilters, [\n procFilters,\n ]) as FilterObjectType;\n\n const memFilts = React.useMemo(() => initialFilters, [initialFilters]);\n\n // eslint-disable-next-line no-param-reassign\n identifier = identifier || 'id';\n\n // eslint-disable-next-line no-param-reassign\n fetchPolicy = fetchPolicy || 'cache-and-network';\n\n const isSerialCode = identifier === 'serialCode';\n\n // to circumvent API error for partial strings in ID based filter fields\n const removeIdPartials = partialRight(removePartialStrings, [\n ...coercedGet(idQueryObject as IDQueryObjectType, 'targetFilterFields', []),\n ]) as any;\n\n const processedFilters = removeNull(removeIdPartials(memProcFilts));\n\n const processedPartialFilters = removeNull(\n getProcessedPartialFilters(memProcFilts, filtFields)\n ) as any;\n\n const mixedFilters = {\n filter: neutQuery(processedFilters),\n partialFilter: processedPartialFilters,\n };\n\n const queryPath = edgesPath.replace(/.edges/g, '');\n\n const initialState = {\n partialKeys: [],\n savedFilts: {},\n } as PartialFilterStateType;\n\n const [partialFilterState, setPartialFilterState] = React.useState(\n initialState\n );\n\n const { partialKeys, savedFilts } = partialFilterState;\n\n // query 1\n const [\n loadPartialQueries,\n { loading: loading1, error: error1 },\n ] = useLazyQuery(query1, {\n fetchPolicy,\n variables: mixedFilters,\n onError: () => {\n setPartialFilterState((prev) => ({\n ...prev,\n partialKeys: [],\n }));\n },\n context,\n\n onCompleted: (data: any) => {\n const preEdges = getUnpaginatedTableData(queryPath, data, identifier);\n\n const queriedIdentifiers = isSerialCode\n ? preEdges.map(({ serialCode }) => serialCode)\n : preEdges.map(({ id }) => id);\n\n if (queriedIdentifiers.length)\n return setPartialFilterState((prev) => ({\n ...prev,\n partialKeys: queriedIdentifiers,\n }));\n\n return setPartialFilterState((prev) => ({\n ...prev,\n partialKeys: [],\n }));\n },\n });\n\n React.useEffect(() => {\n if (checkPartialExist(processedFilters) && !partialKeys.length) {\n loadPartialQueries({\n variables: mixedFilters,\n });\n\n return;\n }\n if (!checkPartialExist(processedFilters) && partialKeys.length) {\n setPartialFilterState(initialState);\n return;\n }\n\n if (\n checkPartialExist(processedFilters) &&\n !isEqual(savedFilts, processedFilters)\n ) {\n loadPartialQueries({\n variables: mixedFilters,\n });\n setPartialFilterState((prev: PartialFilterStateType) => ({\n ...prev,\n savedFilts: processedFilters,\n }));\n }\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [memFilts]);\n\n // ID ============================\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const [collatedIdKeyVals, setCollatedIdKeyVals] = React.useState({});\n\n const getQueryFiltVars = () => {\n const sourceFiltFields = coercedGet(\n idQueryObject as IDQueryObjectType,\n 'sourceFiltFields',\n []\n );\n const targetStringFields = coercedGet(\n idQueryObject as IDQueryObjectType,\n 'targetStringFields',\n []\n );\n\n const currentProcFilts = removeNull(\n getProcessedPartialFilters(memFilts, sourceFiltFields)\n ) as any;\n\n const procToTarget = sourceFiltFields.reduce((acc: any, curr: string) => {\n const sourceIndex = sourceFiltFields.indexOf(curr);\n const newKey = targetStringFields[sourceIndex];\n\n acc[newKey] = {};\n acc[newKey][newKey] = {\n in: [],\n };\n\n if (currentProcFilts[curr]) {\n acc[newKey] = {};\n acc[newKey][newKey] = currentProcFilts[curr];\n }\n\n return acc;\n }, {});\n\n return procToTarget;\n };\n\n const checkPartialOnSource = (filts: any) =>\n coercedGet(\n idQueryObject as IDQueryObjectType,\n 'sourceFiltFields',\n []\n ).some((filtKey: string) => checkPartial(filtKey, filts));\n\n const hasPartialOnSourceFields = checkPartialOnSource(memFilts);\n\n const [loadIdQueries, { loading: loading2, error: error2 }] = useLazyQuery(\n idQueryObject?.query,\n {\n fetchPolicy: 'cache-and-network',\n variables: getQueryFiltVars(),\n onCompleted: (data: any) => {\n const targetStringFields = coercedGet(\n idQueryObject as IDQueryObjectType,\n 'targetStringFields',\n []\n );\n\n const keyVals = targetStringFields.reduce(\n (acc: Record, curr: string) => {\n const edges = coercedGet(data[curr], 'edges', []);\n const queriedIds = edges.map(({ node }: any) => node.id);\n acc[curr] = queriedIds;\n return acc;\n },\n {}\n );\n\n if (hasPartialOnSourceFields) setCollatedIdKeyVals(keyVals);\n },\n }\n );\n\n React.useEffect(() => {\n if (idQueryObject) {\n if (hasPartialOnSourceFields && !Object.keys(collatedIdKeyVals).length) {\n loadIdQueries();\n }\n\n if (!hasPartialOnSourceFields && Object.keys(collatedIdKeyVals).length) {\n setCollatedIdKeyVals({});\n }\n }\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [memFilts]);\n\n // ID ============================\n\n const getFinalQueryFilter = (\n idKeys: Array,\n collatedKeyVals: Record,\n rawFilts: FilterObjectType\n ) => {\n // in string based queries, non partial filters is accounted for in the first query\n const initialFinalQuery = {\n [identifier as string]: {\n in: uniq([...idKeys]),\n },\n };\n\n const hasStringBased = coercedGet(idKeys, 'length', null);\n\n const idBasedKeyValArray = Object.entries(collatedKeyVals);\n const hasIdBased = coercedGet(idBasedKeyValArray, 'length', null);\n\n const hasBoth = hasStringBased && hasIdBased;\n\n if (hasBoth) {\n return idBasedKeyValArray.reduce((acc, curr) => {\n const key = curr[0];\n const val = curr[1];\n\n const strFieldIndex = coercedGet(\n idQueryObject as IDQueryObjectType,\n 'targetStringFields',\n []\n ).indexOf(key);\n\n const targetFiltKey = coercedGet(\n idQueryObject as IDQueryObjectType,\n 'targetFilterFields',\n []\n )[strFieldIndex];\n\n if (acc[targetFiltKey]) {\n const prevSameKey = coercedGet(acc[targetFiltKey], 'in', []);\n\n return {\n ...acc,\n [targetFiltKey]: {\n in: uniq([...prevSameKey, ...val]),\n },\n };\n }\n\n return {\n ...acc,\n [targetFiltKey]: {\n in: uniq([...val]),\n },\n };\n }, initialFinalQuery);\n }\n\n if (hasIdBased) {\n // mix and match of previous regular Ids and Ids produced from Id based string query\n\n return idBasedKeyValArray.reduce((acc, curr) => {\n const key = curr[0];\n const val = curr[1];\n\n const strFieldIndex = coercedGet(\n idQueryObject as IDQueryObjectType,\n 'targetStringFields',\n []\n ).indexOf(key);\n\n const targetFiltKey = coercedGet(\n idQueryObject as IDQueryObjectType,\n 'targetFilterFields',\n []\n )[strFieldIndex];\n\n // in Id based ONLY filters regular filters is not accounted for in the query\n // thats why its set as initial value for reduce\n\n if (acc[targetFiltKey]) {\n const prevSameKey = coercedGet(acc[targetFiltKey], 'in', []);\n\n return {\n ...acc,\n [targetFiltKey]: {\n in: uniq([...prevSameKey, ...val]),\n },\n };\n }\n\n return {\n ...acc,\n [targetFiltKey]: {\n in: uniq([...val]),\n },\n };\n }, rawFilts);\n }\n\n if (hasStringBased) {\n return initialFinalQuery;\n }\n\n return rawFilts;\n };\n\n const finalQueryFilter = getFinalQueryFilter(\n partialKeys,\n collatedIdKeyVals,\n neutQuery(processedFilters)\n );\n\n const refetchVariables = {\n first: pageState.first,\n after: pageState.after,\n filter: finalQueryFilter,\n language,\n ...(pageState.sort && {\n sort: {\n direction: sortTransform[pageState.sort],\n },\n }),\n };\n\n const {\n loading: loading3,\n error: error3,\n data: queryData = {},\n refetch,\n } = useQuery(query2, {\n variables: refetchVariables,\n fetchPolicy,\n context,\n });\n\n const loading = loading1 || loading2 || loading3;\n const error = error1 || error2 || error3;\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const memFinalFilter = React.useMemo(() => finalQueryFilter, [\n memFilts,\n loading,\n ]);\n\n return {\n data: queryData,\n loading,\n error,\n refetchVariables,\n refetch,\n finalQueryFilter: memFinalFilter,\n };\n};\n\nexport const usePartialFilterUtil = createPartialUtil('id');\n","import * as React from 'react';\nimport { Select } from 'antd';\nimport styled from 'styled-components';\nimport { SelectProps } from 'antd/lib/select';\n\nexport const StyledSpan = styled.span`\n font-size: 10px;\n cursor: pointer;\n color: rgba(0, 0, 0, 0.85);\n\n :hover {\n text-decoration: underline;\n opacity: 0.7;\n }\n`;\n\nexport const StyledLabel = styled.span`\n font-size: 10px;\n font-weight: bold;\n`;\n\nexport const StyledSelect = styled((props: SelectProps) => (\n \n))`\n width: 100%;\n\n .ant-select-selection {\n padding: 4px;\n padding-top: 0;\n border-radius: 2px;\n }\n\n .ant-select-selection__rendered {\n margin-left: 0 !important;\n }\n\n .ant-select-selection li.ant-select-selection__choice {\n border-radius: 4px;\n }\n`;\n","import React, { useState } from 'react';\nimport { Select } from 'antd';\nimport { DocumentNode } from 'graphql';\nimport { useLazyQuery } from '@apollo/react-hooks';\nimport { useDebounce } from 'hooks/useDebounce';\nimport { uniq } from 'lodash';\nimport { checkPartial } from 'utils/partialUtils';\nimport {\n StyledLabel,\n StyledSelect,\n StyledSpan,\n} from 'styles/SharedStyledSelectFilter';\nimport { AvailableCurrency } from 'types/graphqlTypes-row';\n\nconst { Option } = Select;\n\ntype Props = {\n label: string;\n query: DocumentNode;\n queryConnection: string;\n filterFieldName: string;\n filters: any;\n fieldType?: string;\n onChange: (e: string[] | null) => void;\n manipulateOptionFunction?: Function;\n partialSupported?: boolean;\n additionalOptionsFilter?: { [key: string]: Record };\n queryOperation?: string;\n testId?: string;\n showLabel?: boolean;\n className?: string;\n multiple?: boolean;\n isAvailableCurrencyQuery?: boolean;\n onKeyDown?: (e: { key: string; preventDefault: () => void }) => void;\n allowFilterOption?: boolean;\n};\n\ntype ConnectionEdge = {\n node: {\n [key: string]: {\n [key: string]: unknown;\n };\n };\n};\n\nexport default ({\n label,\n query,\n filterFieldName,\n filters: value,\n onChange,\n queryConnection,\n fieldType,\n manipulateOptionFunction,\n partialSupported = true,\n additionalOptionsFilter,\n queryOperation = 'in',\n isAvailableCurrencyQuery = false,\n testId,\n showLabel = true,\n className,\n multiple = true,\n onKeyDown,\n allowFilterOption = false,\n}: Props) => {\n const [options, setOptions] = useState([]);\n const [searchedText, setSearchedText] = useState('');\n const [partialText, setPartialText] = useState('');\n const debouncedText = useDebounce(searchedText, 500);\n\n const [loadOptions, { loading }] = useLazyQuery(query, {\n fetchPolicy: 'cache-and-network',\n variables: {\n first: 10,\n filter: {\n [filterFieldName]: {\n contains: debouncedText,\n },\n ...additionalOptionsFilter,\n },\n },\n context: { shouldBatch: true },\n onCompleted: (data) => {\n const rawOptions = () =>\n data[`${queryConnection}`]?.edges.map(({ node }: ConnectionEdge) => {\n if (fieldType) {\n return node[fieldType][filterFieldName];\n }\n\n return node[filterFieldName];\n });\n\n const rawOptionAvailableCurrency = () =>\n data.availableCurrencies.map((d: AvailableCurrency) => d.code);\n\n const uniqueOptions: string[] = uniq(\n isAvailableCurrencyQuery ? rawOptionAvailableCurrency() : rawOptions()\n );\n\n /**\n * @desc Create a custom function and pass it as props in this component to manipulate filter options on special cases.\n * @function manipulateOptionFunction\n * @author Christopher Sotero| pogi\n */\n\n const finalOptions = manipulateOptionFunction\n ? manipulateOptionFunction!(uniqueOptions)\n : uniqueOptions;\n\n setOptions(finalOptions);\n },\n });\n\n const values = value?.[filterFieldName]?.[queryOperation] || [];\n\n const handleChange = (e: string[]) => {\n if (e.length) {\n onChange(e);\n } else {\n onChange(null);\n }\n\n setPartialText('');\n setSearchedText('');\n };\n\n const hasPartial = checkPartial(filterFieldName, value);\n\n return (\n \n {showLabel && (\n
\n
\n {label}\n
\n
\n handleChange([])}>Clear\n
\n
\n )}\n\n
\n option?.children\n ?.toString()\n .toLowerCase()\n .includes(input.toLowerCase())\n : false\n }\n loading={loading}\n onSearch={(text: string) => {\n setSearchedText(text);\n setPartialText(text);\n }}\n onFocus={() => setSearchedText('')}\n onDropdownVisibleChange={(open) => {\n if (open && !options.length) loadOptions();\n }}\n onBlur={() => setSearchedText('')}\n onKeyDown={onKeyDown}\n >\n {!hasPartial && partialText.length && partialSupported && (\n \n )}\n\n {options.map((option, index) => (\n \n ))}\n \n
\n );\n};\n","import React, { ReactNode } from 'react';\nimport styled from 'styled-components';\nimport { FormattedMessage } from 'react-intl';\n\nconst StyledLabel = styled.span`\n font-size: 10px;\n font-weight: bold;\n`;\n\nconst StyledClearButton = styled.span`\n font-size: 10px;\n cursor: pointer;\n\n :hover {\n text-decoration: underline;\n }\n`;\n\nconst Section = styled.section`\n margin-top: 5px;\n`;\n\nexport const FilterItem = ({\n onClear,\n label,\n children,\n}: {\n onClear?: (value: string[]) => void;\n label: string | ReactNode;\n children: ReactNode;\n}) => {\n const Label = () => {label};\n return (\n \n \n {onClear && (\n
\n \n \n \n \n
\n )}\n {!onClear &&
}\n
\n {children}
\n \n );\n};\n","export const AFFLIATE_PROGRAMME_STATUSES = [\n {\n label: 'Active',\n value: 'ACTIVE',\n },\n {\n label: 'Inactive',\n value: 'INACTIVE',\n },\n {\n label: 'Draft',\n value: 'DRAFT',\n },\n];\n","import React from 'react';\nimport { FormattedMessage } from 'react-intl';\nimport { Select } from 'antd';\nimport { StyledSelect } from 'styles';\nimport messages from 'messages';\nimport useTranslate from 'utils/useTranslate';\nimport { FilterItem } from 'components/FilterItem/FilterItem';\nimport { AFFLIATE_PROGRAMME_STATUSES } from './utils';\n\nconst { Option } = Select;\n\ntype StatusType = {\n onChange: (e: string[] | string) => void;\n value: { in: string };\n};\n\nconst Status = (props: StatusType) => {\n const { onChange, value } = props;\n const translate = useTranslate();\n\n return (\n onChange([])}>\n \n }\n value={value ? value.in : []}\n onChange={onChange}\n showSearch\n >\n {AFFLIATE_PROGRAMME_STATUSES.map((option) => (\n \n ))}\n \n \n );\n};\n\nexport default Status;\n","import React from 'react';\nimport { Select } from 'antd';\nimport { StyledSelect } from 'styles';\nimport messages from 'messages';\nimport useTranslate from 'utils/useTranslate';\nimport { FilterItem } from 'components/FilterItem/FilterItem';\n\nconst { Option }: any = Select;\n\ntype DefaultProgrammeType = {\n onChange: (e: boolean | string[]) => void;\n value: { in: boolean };\n};\n\nfunction DefaultProgramme(props: DefaultProgrammeType) {\n const { onChange, value } = props;\n\n const translate = useTranslate();\n\n return (\n onChange([])}\n >\n \n \n \n \n \n );\n}\n\nexport default DefaultProgramme;\n","import React from 'react';\nimport { Select } from 'antd';\nimport { StyledSelect } from 'styles';\nimport messages from 'messages';\nimport useTranslate from 'utils/useTranslate';\nimport { FilterItem } from 'components/FilterItem/FilterItem';\n\nconst { Option }: any = Select;\n\ntype NegativeCarryType = {\n onChange: (e: boolean | string[]) => void;\n value: { in: boolean };\n};\n\nconst NegativeCarry = (props: NegativeCarryType) => {\n const { onChange, value } = props;\n const translate = useTranslate();\n\n return (\n onChange([])}\n >\n \n \n \n \n \n );\n};\n\nexport default NegativeCarry;\n","import React from 'react';\nimport { DynamicObj } from 'interfaces/user.interface';\nimport SelectFilterField from 'components/SelectFilterField';\nimport { PROGRAMME_NAMES } from 'graphql/queries/affiliateProgramme.query';\nimport Status from '../Status';\nimport DefaultProgramme from '../DefaultProgramme';\nimport NegativeCarry from '../NegativeCarry';\n\ntype Props = {\n filters: Record;\n onRawFilterChange: ({\n key,\n value,\n }: {\n key: string;\n value: DynamicObj | null;\n }) => void;\n};\n\nconst FilterItems = ({ filters, onRawFilterChange: handleChange }: Props) => (\n <>\n \n handleChange({\n key: 'name',\n value: e?.length ? { in: e } : null,\n })\n }\n />\n \n handleChange({\n key: 'status',\n value: e.length ? { in: e } : null,\n })\n }\n />\n \n handleChange({\n key: 'default',\n value: Array.isArray(e) ? null : { in: e },\n })\n }\n />\n {\n handleChange({\n key: 'negativeCarryOverEnabled',\n value: Array.isArray(e) ? null : { in: e },\n });\n }}\n />\n >\n);\n\nexport default FilterItems;\n","import React from 'react';\nimport { Form } from '@ant-design/compatible';\nimport '@ant-design/compatible/assets/index.css';\nimport { DynamicObj } from 'interfaces/user.interface';\nimport FilterItems from './components/FilterItems/FilterItems';\n\ntype Props = {\n filters: DynamicObj;\n onFilterChange: (e: any) => void;\n};\n\nfunction Sidebar(props: Props) {\n const { filters, onFilterChange } = props;\n\n const handleChange = (e: { key: string; value: DynamicObj | null }) => {\n const { key, value } = e;\n onFilterChange((prevFilter: DynamicObj) => ({\n ...prevFilter,\n [key]: value,\n }));\n };\n\n return (\n \n );\n}\n\nexport default Sidebar;\n","import { Form } from '@ant-design/compatible';\nimport { Row, Col, Button } from 'antd';\nimport { DynamicObj } from 'interfaces/user.interface';\nimport React, { useState } from 'react';\nimport styled from 'styled-components';\nimport FilterItems from '../Sidebar/components/FilterItems/FilterItems';\n\ntype Props = {\n initialValues: { [key: string]: any };\n onSubmit: (values: any) => void;\n onClose: () => void;\n isLoading: boolean;\n};\n\nconst StyledForm = styled(Form)`\n .ant-legacy-form-item {\n margin-bottom: 12px;\n display: flex;\n justify-content: center;\n\n label {\n color: rgba(0, 0, 0, 0.35);\n }\n }\n`;\n\nconst SearchSettingsForm: React.FC = ({\n initialValues,\n onSubmit,\n onClose,\n isLoading,\n}) => {\n const [values, setValues] = useState(initialValues);\n\n const handleChange = (e: { key: string; value: DynamicObj | null }) => {\n const { key, value } = e;\n setValues((prevFilter: DynamicObj) => ({\n ...prevFilter,\n [key]: value,\n }));\n };\n\n return (\n \n \n \n \n \n
\n\n \n {' '}\n \n
\n \n );\n};\n\nexport default SearchSettingsForm;\n","import { PlusOutlined } from '@ant-design/icons';\nimport { useQuery } from '@apollo/react-hooks';\nimport { Button } from 'antd';\nimport { withErrorHandler } from 'components/ErrorHandler';\nimport Layout from 'components/Layout';\nimport LegacyIconToggle from 'components/LegacyIconToggle';\nimport ALL_PERMISSIONS from 'constants/permissions3';\nimport { AFFILIATE_PROGRAMMES } from 'graphql/queries/affiliateProgramme.query';\nimport { VENDORS } from 'graphql/queries/vendor.query';\nimport { Page, PageInfo } from 'interfaces/user.interface';\nimport { collectPermissions } from 'pages/components/PermissionGroup/utils';\nimport messages from 'messages';\nimport React, { useState } from 'react';\nimport { useIntl } from 'react-intl';\nimport { ClearAllFilterButton } from 'components/ClearAllFilterButton/ClearAllFilterButton';\nimport RefreshButton from 'components/RefreshButton/RefreshButton';\nimport { QuickSearchIds } from 'components/QuickSearchFilter';\nimport { ToggleSidebarHead } from 'components/ToggleSidebarHead/ToggleSidebarHead';\nimport { usePermissions } from 'store/accountState';\nimport { StyledTagContainer } from 'styles';\nimport { AffiliateProgrammesFilterInput } from 'types/graphqlTypes';\nimport coercedGet from 'utils/coercedGet';\nimport removeNull from 'utils/removeNull';\nimport { customFormatMessage } from '../../../utils/customFormatMessage';\nimport AffiliateDetails from './components/AffiliateDetails';\nimport AgentAffiliateTable from './components/AgentAffiliateTable';\nimport CreateAffiliateProgramme from './components/CreateAffiliateProgramme';\nimport { CreateAffiliateProgrammeProvider } from './components/CreateAffiliateProgramme/context';\nimport FilterConditions from './components/FilterConditions';\nimport Sidebar from './components/Sidebar';\nimport { AffiliateTypes, useAffiliateState } from './context';\nimport SearchSettingsForm from './components/SearchSettingsForm/SearchSettingsForm';\n\nconst pageInitState: Page = {\n after: undefined,\n savedCursor: [undefined] as any,\n currentPage: 0,\n first: 10,\n};\n\nconst AffiliateProgramme = () => {\n const { role, permissions } = usePermissions();\n\n const { ALLOWED_LIST, ALLOWED_CREATE } = collectPermissions(\n role,\n permissions,\n ['LIST', 'CREATE'],\n ALL_PERMISSIONS.ALL_AFFILIATES.AFFILIATES_AFFILIATE_PROGRAMME\n );\n\n const defaultFilters: AffiliateProgrammesFilterInput = {\n name: null,\n status: null,\n default: null,\n negativeCarryOverEnabled: null,\n };\n\n const [filters, setFilters] = React.useState(defaultFilters);\n\n const handleFilters = (e: AffiliateProgrammesFilterInput) => {\n setFilters(e);\n };\n\n const intl = useIntl();\n const [totalCount, setTotalCount] = useState(0);\n const [pageInfo, setPageInfo] = useState>({});\n\n const [affiliateState, dispatch] = useAffiliateState() as any;\n\n const [page, setPage] = useState(pageInitState);\n\n const handleNext = () => {\n const { savedCursor, currentPage } = page;\n savedCursor.push(pageInfo.endCursor!);\n setPage({\n ...page,\n after: pageInfo.endCursor,\n currentPage: currentPage + 1,\n savedCursor,\n });\n };\n\n const handlePrev = () => {\n const { currentPage, savedCursor } = page;\n const prevPage = currentPage - 1;\n const after = savedCursor[prevPage];\n setPage({\n ...page,\n after,\n currentPage: prevPage,\n });\n };\n\n const refetchVariables = {\n first: page.first,\n after: page.after || undefined,\n filter: removeNull(filters),\n };\n\n const setResultInfo = (data: { pageInfo: PageInfo; totalCount: number }) => {\n setTotalCount(data.totalCount);\n setPageInfo(data.pageInfo);\n };\n\n const totalPage = Math.ceil(totalCount / page.first) || 1;\n\n const showForm = (record: any = null) => {\n if (record.id) {\n dispatch({\n type: AffiliateTypes.SET_ACTIVE_AFFILIATE_PROGRAMME,\n payload: record.id,\n meta: record,\n });\n }\n dispatch({\n type: AffiliateTypes.SHOW_CREATE_AFFILIATE_PROGRAMME,\n });\n };\n\n useQuery(VENDORS, {\n fetchPolicy: 'network-only',\n onCompleted: (res: any) => {\n const vendors = coercedGet(res, 'vendors.edges', []);\n const defaultVendorHandlers = vendors.reduce(\n (acc: any, { node }: any) => {\n const gameTypes = coercedGet(node, 'gameTypes', []);\n let newCharges = {};\n gameTypes.forEach((gameType: any) => {\n newCharges = {\n ...newCharges,\n [`${gameType}_${node.id}`]: {\n vendor: node.id,\n gameType,\n },\n };\n });\n return { ...acc, ...newCharges };\n },\n {}\n );\n dispatch({\n type: AffiliateTypes.SET_DEFAULT_VENDORS,\n payload: vendors,\n });\n dispatch({\n type: AffiliateTypes.SET_DEFAULT_VENDOR_HANDLERS,\n payload: defaultVendorHandlers,\n });\n },\n });\n\n const { loading, error, data, refetch } = useQuery(AFFILIATE_PROGRAMMES, {\n variables: refetchVariables,\n fetchPolicy: 'network-only',\n notifyOnNetworkStatusChange: true,\n onCompleted: (res) => {\n setResultInfo(res.affiliateProgrammes);\n },\n });\n\n const edges = coercedGet(data, 'affiliateProgrammes.edges', []).map(\n (item: any, key: number) => ({\n ...item.node,\n key: key + 1,\n })\n );\n\n const translate = (value: any) =>\n customFormatMessage(intl.formatMessage, value);\n\n const ref = React.useRef(null);\n const [expandedTags, setExpandedTags] = useState(false);\n\n return affiliateState.activeScreen ===\n AffiliateTypes.AGENT_AFFILIATE_DETAILS ? (\n \n ) : (\n \n <>\n \n \n \n \n {translate(messages.FILTER_CONDITIONS)}:{' '}\n {' '}\n \n \n \n handleFilters(defaultFilters)}\n style={{ marginTop: '0.35rem' }}\n />\n \n }\n rightNode={\n \n refetch(refetchVariables)} />\n {ALLOWED_CREATE && (\n }\n onClick={showForm}\n >\n {translate(messages.CREATE_PROGRAMME)}\n \n )}\n
\n }\n />\n \n <>\n \n >\n \n }\n footer={\n \n }\n >\n {affiliateState.activeScreen ===\n AffiliateTypes.AGENT_AFFILIATE_LIST &&\n ALLOWED_LIST && (\n \n )}\n\n \n \n \n \n >\n \n );\n};\n\nexport default withErrorHandler(AffiliateProgramme);\n","import styled from 'styled-components';\n\nexport const StyledCenter = styled.div`\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n`;\n\nexport const StyledContainer = styled.div`\n padding-top: 48px;\n`;\n\nexport default {};\n","import gql from 'graphql-tag';\n\nexport const AFFILIATE_PROGRAMMES = gql`\n query affiliateProgrammes(\n $first: Int\n $after: Binary\n $filter: AffiliateProgrammesFilterInput\n ) {\n affiliateProgrammes(first: $first, after: $after, filter: $filter) {\n totalCount\n edges {\n cursor\n node {\n id\n status\n membersCount\n name\n description\n default\n automaticPayoutClaiming\n negativeCarryOverEnabled\n vendorPlatformFees {\n vendor {\n id\n name\n nameEn: name(language: EN)\n nameZh: name(language: ZH)\n gameTypes\n }\n minimumCharge\n maximumCharge\n chargeLevels {\n minimumTotalWinloss\n percentage\n }\n gameType\n }\n minimumEffectiveBetRequirement\n minimumDepositRequirement\n minimumPayoutAccumulationEnabled\n minimumPayoutAccumulationAmount\n turnoverRequirementMultiplier\n settlementPeriod\n settlementTime\n settlementDayOfWeek\n settlementDayOfMonth\n payoutClaimOffsetDuration\n payoutClaimExpiryDuration\n payoutExpiryDuration\n levels {\n name\n minimumActiveMembersCount\n minimumNetProfit\n percentage\n }\n levelsRequirement\n depositTransactionCost\n thirdPartyDepositTransactionCost\n withdrawalTransactionCost\n thirdPartyWithdrawalTransactionCost\n promoCost\n rebateCost\n interestAccountCost\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n`;\n\nexport const AFFILIATE_PROGRAMME = gql`\n query affiliateProgramme($id: ID!) {\n affiliateProgramme(id: $id) {\n id\n status\n membersCount\n name\n description\n default\n automaticPayoutClaiming\n negativeCarryOverEnabled\n vendorPlatformFees {\n vendor {\n id\n name\n nameEn: name(language: EN)\n nameZh: name(language: ZH)\n gameTypes\n }\n minimumCharge\n maximumCharge\n chargeLevels {\n minimumTotalWinloss\n percentage\n }\n gameType\n }\n minimumEffectiveBetRequirement\n minimumDepositRequirement\n minimumPayoutAccumulationEnabled\n minimumPayoutAccumulationAmount\n turnoverRequirementMultiplier\n settlementPeriod\n settlementTime\n settlementDayOfWeek\n settlementDayOfMonth\n payoutClaimOffsetDuration\n payoutClaimExpiryDuration\n payoutExpiryDuration\n levels {\n name\n minimumActiveMembersCount\n minimumNetProfit\n percentage\n }\n levelsRequirement\n depositTransactionCost\n thirdPartyDepositTransactionCost\n withdrawalTransactionCost\n thirdPartyWithdrawalTransactionCost\n promoCost\n rebateCost\n interestAccountCost\n }\n }\n`;\n\nexport const AFFILIATE_REQUESTS = gql`\n query affiliateRequests(\n $first: Int\n $after: Binary\n $filter: AffiliateRequestsFilterInput\n ) {\n affiliateRequests(first: $first, after: $after, filter: $filter) {\n totalCount\n edges {\n node {\n id\n serialCode\n programme {\n id\n name\n }\n member {\n id\n username\n realName\n memberLoyaltyLevels {\n id\n programme {\n id\n name\n }\n name\n color\n }\n }\n status\n dateTimeCreated\n dateTimeUpdated\n processor {\n id\n username\n }\n dateTimeProcessingStarted\n dateTimeProcessingEnded\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n`;\n\nexport const AFFILIATE_REQUESTS_CSV_DATA = gql`\n query affiliateRequests(\n $first: Int\n $after: Binary\n $filter: AffiliateRequestsFilterInput\n ) {\n affiliateRequests(first: $first, after: $after, filter: $filter) {\n totalCount\n pageInfo {\n endCursor\n hasNextPage\n }\n edges {\n node {\n id\n serialCode\n programme {\n id\n name\n }\n member {\n id\n username\n realName\n memberLoyaltyLevels {\n id\n programme {\n id\n name\n }\n name\n color\n }\n }\n status\n dateTimeCreated\n dateTimeUpdated\n processor {\n id\n username\n }\n dateTimeProcessingStarted\n dateTimeProcessingEnded\n }\n }\n }\n }\n`;\n\nexport const AFFILIATE_REQUEST = gql`\n query affiliateRequest($id: ID!) {\n affiliateRequest(id: $id) {\n id\n serialCode\n processor {\n id\n username\n }\n programme {\n id\n name\n }\n formFields {\n ... on CustomFormField {\n type\n required\n label\n pattern\n }\n ... on BuiltInFormField {\n type\n required\n field\n }\n }\n formFieldValues\n member {\n id\n username\n realName\n gender\n dateOfBirth\n email\n mobileNumber\n wechatId\n qqId\n bankAccounts {\n edges {\n node {\n id\n accountNumber\n }\n }\n }\n status\n memberLevel {\n id\n name\n color\n }\n memberLoyaltyLevels {\n id\n programme {\n id\n name\n }\n name\n color\n }\n tags {\n id\n name\n color\n description\n }\n totalTurnover\n totalPromoPayout\n lastOnlineDateTime\n registrationDateTime\n }\n status\n dateTimeCreated\n dateTimeUpdated\n remarks\n }\n }\n`;\n\nexport const AFFILIATE_CRITERIA = gql`\n {\n config {\n affiliateRequestFormFields {\n ... on BuiltInFormField {\n type\n required\n field\n }\n ... on CustomFormField {\n type\n required\n label\n pattern\n }\n }\n }\n }\n`;\n\nexport const AFFILIATE_REQUESTS_SERIAL_CODE = gql`\n query FilterAffiliateRequestsSerial(\n $first: Int\n $after: Binary\n $filter: AffiliateRequestsFilterInput\n ) {\n affiliateRequests(first: $first, after: $after, filter: $filter) {\n totalCount\n edges {\n node {\n id\n serialCode\n }\n }\n }\n }\n`;\n\nexport default {};\n","export const TIER_REQUIREMENT = {\n ACTIVE_MEMBERS: 'ACTIVE_MEMBERS_COUNT',\n NET_PROFIT: 'NET_PROFIT',\n BOTH: 'BOTH',\n EITHER: 'EITHER',\n};\n\nexport const getTierRequirement = (requirement: string) => ({\n forActiveMembers:\n requirement === TIER_REQUIREMENT.ACTIVE_MEMBERS ||\n requirement === TIER_REQUIREMENT.BOTH ||\n requirement === TIER_REQUIREMENT.EITHER,\n forNetProfit:\n requirement === TIER_REQUIREMENT.NET_PROFIT ||\n requirement === TIER_REQUIREMENT.BOTH ||\n requirement === TIER_REQUIREMENT.EITHER,\n});\n","import React from 'react';\n\nexport const AffiliateTypes = {\n SET_ACTIVE_SCREEN: 'SET_ACTIVE_SCREEN',\n AGENT_AFFILIATE_LIST: 'AGENT_AFFILIATE_LIST',\n AGENT_AFFILIATE_DETAILS: 'AGENT_AFFILIATE_DETAILS',\n SHOW_CREATE_AFFILIATE_PROGRAMME: 'SHOW_CREATE_AFFILIATE_PROGRAMME',\n HIDE_CREATE_AFFILIATE_PROGRAMME: 'HIDE_CREATE_AFFILIATE_PROGRAMME',\n SET_DEFAULT_VENDORS: 'SET_DEFAULT_VENDORS',\n SET_DEFAULT_VENDOR_HANDLERS: 'SET_DEFAULT_VENDOR_HANDLERS',\n SET_ACTIVE_AFFILIATE_PROGRAMME: 'SET_ACTIVE_AFFILIATE_PROGRAMME',\n RESET_ACTIVE_AFFILIATE_PROGRAMME: 'RESET_ACTIVE_AFFILIATE_PROGRAMME',\n SET_SUMMARY: 'SET_SUMMARY',\n SET_REFETCH_VARIABLES: 'SET_REFETCH_VARIABLES',\n};\n\nexport const AffiliateContext = React.createContext(undefined);\n\nexport function AffiliateProvider({ children }: any) {\n const initialState = {\n activeScreen: AffiliateTypes.AGENT_AFFILIATE_LIST,\n showCreateAffiliateProgramme: false,\n vendorHandlers: {},\n vendors: [],\n activeAffiliate: '',\n activeAffiliateData: {},\n recordSummary: '',\n refetchVariables: {},\n };\n\n const reducer = (state: Record, action: Record) => {\n switch (action.type) {\n case AffiliateTypes.SET_ACTIVE_SCREEN:\n return {\n ...state,\n activeScreen: action.payload,\n };\n case AffiliateTypes.SET_REFETCH_VARIABLES:\n return {\n ...state,\n refetchVariables: action.payload,\n };\n case AffiliateTypes.SET_DEFAULT_VENDOR_HANDLERS:\n return {\n ...state,\n vendorHandlers: action.payload,\n };\n case AffiliateTypes.SET_DEFAULT_VENDORS:\n return {\n ...state,\n vendors: action.payload,\n };\n case AffiliateTypes.SHOW_CREATE_AFFILIATE_PROGRAMME:\n return {\n ...state,\n showCreateAffiliateProgramme: true,\n };\n case AffiliateTypes.HIDE_CREATE_AFFILIATE_PROGRAMME:\n return {\n ...state,\n showCreateAffiliateProgramme: false,\n };\n case AffiliateTypes.SET_ACTIVE_AFFILIATE_PROGRAMME:\n return {\n ...state,\n activeAffiliate: action.payload,\n activeAffiliateData: action.meta,\n };\n case AffiliateTypes.RESET_ACTIVE_AFFILIATE_PROGRAMME:\n return {\n ...state,\n activeAffiliate: '',\n activeAffiliateData: {},\n };\n case AffiliateTypes.SET_SUMMARY:\n return {\n ...state,\n recordSummary: action.payload,\n };\n default:\n return state;\n }\n };\n return (\n \n {children}\n \n );\n}\n\nexport const useAffiliateState = () => React.useContext(AffiliateContext);\n","import styled from 'styled-components';\nimport { Layout } from 'antd';\n\nexport const FilterContainer = styled.div`\n background-color: #fff;\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: space-between;\n`;\nexport const CostSettingsSider = styled(Layout.Sider)`\n background-color: #ffffff;\n border-left: 1px solid #e8e8e8;\n border-top: 1px solid #e8e8e8;\n`;\n\nexport default {};\n","import { defineMessages } from 'react-intl';\n\nconst messages = defineMessages({\n 'game-vendor.text': {\n id: 'game-vendor.text',\n defaultMessage: 'Game vendor',\n },\n 'game-category.text': {\n id: 'game-category.text',\n defaultMessage: 'Game category',\n },\n 'all.text': {\n id: 'all.text',\n defaultMessage: 'All',\n },\n 'from.text': {\n id: 'from.text',\n defaultMessage: 'From',\n },\n 'to.text': {\n id: 'to.text',\n defaultMessage: 'To',\n },\n 'charge.text': {\n id: 'charge.text',\n defaultMessage: 'Charge',\n },\n});\n\nexport default messages;\n","import React from 'react';\n\nexport const CostSettingsTypes = {\n SET_SORT_FILTER: 'SET_SORT_FILTER',\n SET_SEARCH_FILTER: 'SET_SEARCH_FILTER',\n SET_SUBFILTER: 'SET_SUBFILTER',\n SET_SEARCH: 'SET_SEARCH',\n SET_COPIED: 'SET_COPIED',\n SET_ACTIVE_VENDOR: 'SET_ACTIVE_VENDOR',\n REMOVE_SUBFILTER: 'REMOVE_SUBFILTER',\n};\n\nexport const CostSettingsFilters = {\n GAME_VENDOR: 'GAME_VENDOR',\n GAME_CATEGORY: 'GAME_CATEGORY',\n ALL: 'ALL',\n};\n\nexport const CostSettingsContext = React.createContext(undefined);\n\nexport const CostSettingsProvider = ({ children }: any) => {\n const initialState = {\n sortFilter: CostSettingsFilters.GAME_VENDOR,\n searchFilter: CostSettingsFilters.GAME_VENDOR,\n subFilters: [],\n search: '',\n activeVendor: {},\n };\n\n const reducer = (state: Record, action: Record) => {\n switch (action.type) {\n case CostSettingsTypes.SET_SORT_FILTER:\n return { ...state, sortFilter: action.payload };\n case CostSettingsTypes.SET_ACTIVE_VENDOR:\n return { ...state, activeVendor: action.payload };\n case CostSettingsTypes.SET_COPIED:\n return { ...state, copied: action.payload };\n case CostSettingsTypes.SET_SEARCH:\n return { ...state, search: action.payload };\n case CostSettingsTypes.SET_SEARCH_FILTER:\n return { ...state, searchFilter: action.payload };\n case CostSettingsTypes.SET_SUBFILTER:\n return {\n ...state,\n subFilters: [...state.subFilters, action.payload],\n };\n case CostSettingsTypes.REMOVE_SUBFILTER:\n return {\n ...state,\n subFilters: state.subFilters.filter(\n (filter: Record) =>\n filter.value !== action.payload.value\n ),\n };\n default:\n return state;\n }\n };\n\n return (\n \n {children}\n \n );\n};\n\nexport const useCostSettingsContext = () =>\n React.useContext(CostSettingsContext);\n","import React, { useState, useRef } from 'react';\nimport { CloseOutlined, DownOutlined, SearchOutlined } from '@ant-design/icons';\nimport { Input, Dropdown, Menu, Button, Checkbox, Select } from 'antd';\nimport { FormattedMessage, useIntl } from 'react-intl';\nimport { kebabCase } from 'lodash';\nimport styled from 'styled-components';\nimport { useAffiliateState } from 'pages/components/Agent/components/Affiliate/context';\nimport { Locale } from 'constants/locale';\nimport { GameTypes } from 'constants/gameTypes';\nimport globalMessages from 'messages';\nimport useTranslate from 'utils/useTranslate';\nimport { FilterContainer } from '../styles';\nimport messages from '../messages';\nimport {\n CostSettingsTypes,\n useCostSettingsContext,\n CostSettingsFilters,\n} from '../context';\n\nconst InputGroup = Input.Group;\nconst CustomMenu: any = Menu;\n\nconst StyledSelect = styled(Select)`\n width: 150px !important;\n height: 36px;\n margin-left: 1px;\n &.ant-select > .ant-select-selection--single {\n height: 36px;\n border-top-left-radius: 0px;\n border-bottom-left-radius: 0px;\n border-left: 0px;\n }\n &.ant-select\n > .ant-select-selection--single\n > .ant-select-selection__rendered {\n line-height: 35px;\n }\n`;\n\nconst StyledInput = styled(Input)`\n height: 36px;\n width: 200px;\n .ant-input {\n border-top-right-radius: 0px;\n border-bottom-right-radius: 0px;\n }\n &.ant-input-affix-wrapper .ant-input:not(:first-child) {\n padding-left: 40px;\n }\n`;\n\nconst StyledMenu = styled(Menu)`\n max-width: ${(props) => (props.isGameVendorWidth ? '200px' : '150px')};\n max-height: 300px;\n overflow: hidden;\n overflow-y: auto;\n .ant-dropdown-menu-item {\n label {\n display: block;\n }\n }\n`;\n\nfunction Filters() {\n const translate = useTranslate();\n const intl = useIntl();\n const [search, setSearch] = useState('');\n const [{ sortFilter, subFilters }, dispatch] = useCostSettingsContext();\n const [{ vendors }] = useAffiliateState() as any;\n const [filterValuesShown, setFilterValuesShown] = useState(false);\n const timeOut = useRef(0);\n\n const setSortFilter = (value: any) => {\n dispatch({\n type: CostSettingsTypes.SET_SORT_FILTER,\n payload: value,\n });\n };\n\n const setSearchFilter = (value: Record) => {\n dispatch({\n type: CostSettingsTypes.SET_SEARCH_FILTER,\n payload: value,\n });\n };\n\n const setInputSearch = (e: Record) => {\n const { value } = e.target;\n setSearch(value);\n\n clearTimeout(timeOut.current);\n e.persist();\n timeOut.current = setTimeout(() => {\n dispatch({\n type: CostSettingsTypes.SET_SEARCH,\n payload: value,\n });\n }, 250);\n };\n\n const subMenuItems =\n sortFilter === CostSettingsFilters.GAME_VENDOR\n ? vendors.map((item: Record) => ({\n label:\n intl.locale === Locale.EN\n ? item.node.nameEn\n : `${item.node.nameZh || item.node.name}`,\n value: item.node.id,\n }))\n : Object.keys(GameTypes).map((key) => ({\n label: `${translate(globalMessages[`${kebabCase(key)}.text`])}`,\n value: key,\n }));\n\n const menu = {\n sortFilter: (\n \n {Object.keys(CostSettingsFilters).map(\n (value, index) =>\n value !== CostSettingsFilters.ALL && (\n {\n setSortFilter(value);\n }}\n >\n {translate(messages[`${kebabCase(value)}.text`])}\n \n )\n )}\n \n ),\n subFilters: (\n \n {subMenuItems.map((item: Record) => (\n \n ) =>\n filterValue.value === item.value\n )\n )}\n onChange={(e) => {\n if (e.target.checked) {\n dispatch({\n type: CostSettingsTypes.SET_SUBFILTER,\n payload: item,\n });\n } else {\n dispatch({\n type: CostSettingsTypes.REMOVE_SUBFILTER,\n payload: item,\n });\n }\n }}\n >\n {item.label}\n \n \n ))}\n \n ),\n };\n\n return (\n \n \n \n \n }\n value={search}\n suffix={}\n onChange={setInputSearch}\n />\n \n {Object.keys(CostSettingsFilters).map((value, index) => {\n const messageId = kebabCase(value.toLocaleLowerCase());\n\n return (\n \n {translate(messages[`${messageId}.text`])}\n \n );\n })}\n \n \n
\n \n
\n \n \n \n
\n
\n setFilterValuesShown(flag)}\n visible={filterValuesShown}\n overlay={menu.subFilters}\n trigger={['click']}\n >\n \n \n
\n
\n \n );\n}\n\nexport default Filters;\n","import React from 'react';\nimport { Card, Row, Col, Typography, Switch } from 'antd';\nimport styled from 'styled-components';\nimport cx from 'classnames';\nimport { FormattedMessage, useIntl } from 'react-intl';\nimport { GameTypeNames } from 'constants/gameTypes';\nimport { Locale } from 'constants/locale';\nimport messages from 'messages';\nimport coercedGet from 'utils/coercedGet';\nimport { customFormatMessage } from 'utils/customFormatMessage';\nimport { useAffiliateState } from '../../../../../context';\nimport {\n useCostSettingsContext,\n CostSettingsFilters,\n CostSettingsTypes,\n} from '../context';\n\nconst StyledSwitch = styled(Switch)`\n &.ant-switch-checked {\n background-color: #3bc98c;\n }\n flex: none;\n`;\n\nconst StyledCard = styled(Card)`\n width: 250px;\n\n .ant-card-body {\n min-height: 56px;\n padding-left: 12px;\n padding-right: 12px;\n }\n box-shadow: ${(props) =>\n props.focuseditem ? '0.5px 0.5px 12px 0px rgba(0, 0, 0, 0.25)' : ''};\n z-index: ${(props) => (props.focuseditem ? 15 : 1)};\n`;\n\nconst isActive = (\n activeVendor: Record,\n vendor: Record,\n gameType: string\n) => activeVendor.id === vendor && activeVendor.gameType === gameType;\n\nconst GameTypesByVendor = ({\n gameTypes,\n vendor,\n sortIndex,\n summary,\n}: {\n gameTypes: any;\n vendor: Record;\n sortIndex: number;\n summary: Record;\n}) => {\n const intl = useIntl();\n const [{ activeVendor }, dispatch] = useCostSettingsContext();\n\n return gameTypes.map((gameType: string, index: number) => {\n const vendorPlatformFees = coercedGet(summary, 'vendorPlatformFees', []);\n const selectedVendorGameType =\n vendorPlatformFees.find(\n (node: Record) =>\n node.gameType === gameType && node.vendor.id === vendor\n ) || {};\n\n const checked =\n !!(\n coercedGet(selectedVendorGameType, 'minimumCharge', 0) ||\n coercedGet(selectedVendorGameType, 'maximumCharge', 0) ||\n coercedGet(selectedVendorGameType, 'chargeLevels', []).length\n ) || false;\n\n const activeVendorDetails = {\n id: vendor,\n gameType,\n minimumCharge: coercedGet(selectedVendorGameType, 'minimumCharge', 0),\n maximumCharge: coercedGet(selectedVendorGameType, 'maximumCharge', 0),\n chargeLevels: coercedGet(selectedVendorGameType, 'chargeLevels', []),\n };\n\n if (index === 0 && sortIndex === 0 && !activeVendor.id) {\n dispatch({\n type: CostSettingsTypes.SET_ACTIVE_VENDOR,\n payload: activeVendorDetails,\n });\n }\n const translate = (messageVal: any, opts = null) =>\n customFormatMessage(intl.formatMessage, messageVal, opts);\n return (\n \n {\n if (!isActive(activeVendor, vendor, gameType)) {\n dispatch({\n type: CostSettingsTypes.SET_ACTIVE_VENDOR,\n payload: activeVendorDetails,\n });\n }\n }}\n >\n