export function TargetAudienceFilterComponent()

in apps/chat/src/components/Chat/Publish/TargetAudienceFilterComponent.tsx [66:302]


export function TargetAudienceFilterComponent({
  onSaveFilter,
  onCloseFilter,
}: Props) {
  const { t } = useTranslation(Translation.SideBar);

  const [filterFunction, setFilterFunction] = useState<
    PublicationFunctions | typeof emptySelector
  >(emptySelector);
  const [filterParams, setFilterParams] = useState<string[]>([]);
  const [filterRegexParam, setFilterRegexParam] = useState<string>('');
  const [selectedTarget, setSelectedTarget] = useState(emptySelector);

  const publicationFilters = useAppSelector(
    SettingsSelectors.selectPublicationFilters,
  );

  const handleSaveFilter = useCallback(() => {
    if (!onSaveFilter) return;

    const preparedFilterParams = getPreparedFilterParams(
      filterFunction as PublicationFunctions,
      {
        filterParams,
        filterRegexParam,
      },
    );

    onSaveFilter({
      id: selectedTarget,
      filterFunction: filterFunction as PublicationFunctions,
      filterParams: preparedFilterParams,
    });
  }, [
    filterFunction,
    filterParams,
    filterRegexParam,
    onSaveFilter,
    selectedTarget,
  ]);

  const handleChangeTarget = useCallback((target: string) => {
    setSelectedTarget(target);
  }, []);

  const handleChangeFilterFunction = useCallback(
    (filterFunction: PublicationFunctions) => {
      setFilterFunction(filterFunction);
    },
    [],
  );

  const handleChangeFilterParams = useCallback((filterParams: string[]) => {
    setFilterParams(filterParams);
  }, []);

  const handleChangeFilterRegexParam = useCallback(
    (filterRegexParam: string) => {
      setFilterRegexParam(filterRegexParam);
    },
    [],
  );

  const isTargetAndFunctionSelected =
    selectedTarget !== emptySelector && filterFunction !== emptySelector;
  const areSomeFilterParamSelected = filterParams.length || filterRegexParam;
  const isRegexFilledInButNotSelected = !!(
    filterRegexParam &&
    filterFunction !== PublicationFunctions.Regex &&
    !filterParams.length
  );
  const isParamsFilledInButRegexIsSelected = !!(
    filterParams.length &&
    filterFunction === PublicationFunctions.Regex &&
    !filterRegexParam
  );
  const isSaveBtnDisabled =
    !isTargetAndFunctionSelected ||
    !areSomeFilterParamSelected ||
    isRegexFilledInButNotSelected ||
    isParamsFilledInButRegexIsSelected;

  // TODO: uncomment when it will be supported on core
  // const isTrueOrFalseFilterSelected =
  //   filterFunction === PublicationFunctions.True ||
  //   filterFunction === PublicationFunctions.False;
  // const isSaveBtnDisabled = isTrueOrFalseFilterSelected
  //   ? !isTargetAndFunctionSelected
  //   : !isTargetAndFunctionSelected ||
  //     !areSomeFilterParamSelected ||
  //     isRegexFilledInButNotSelected ||
  //     isParamsFilledInButRegexIsSelected;

  if (isSmallScreen()) {
    return (
      <Modal
        portalId="theme-main"
        dataQa="mobile-filters-select"
        containerClassName="inline-block flex flex-col w-full overflow-y-auto px-3 py-4 align-bottom transition-all md:p-6 h-full xl:max-w-[720px] 2xl:max-w-[780px]"
        state={ModalState.OPENED}
        heading={t('Add filter')}
        onClose={onCloseFilter}
      >
        <div className="flex h-full flex-col justify-between">
          <div className="flex flex-col gap-4">
            <div className="flex flex-col gap-1">
              <label className="text-xs text-secondary">
                {t('Category')}
                <span className="ml-1 inline text-accent-primary">*</span>
              </label>
              <RulesSelect
                triggerClassName="h-[38px] items-center rounded border border-primary font-semibold"
                filters={publicationFilters}
                selectedFilter={selectedTarget}
                capitalizeFirstLetters
                onChangeFilter={handleChangeTarget}
                id="targets"
              />
            </div>
            <div className="flex flex-col gap-1">
              <label className="text-xs text-secondary">
                {t('Condition')}
                <span className="ml-1 inline text-accent-primary">*</span>
              </label>
              <RulesSelect
                triggerClassName="h-[38px] items-center rounded border border-primary italic"
                filters={filterFunctionValues}
                selectedFilter={filterFunction}
                onChangeFilter={handleChangeFilterFunction}
                id="filterFns"
              />
            </div>
            {/* TODO: uncomment when it will be supported on core */}
            {/* {!isTrueOrFalseFilterSelected && ( */}
            <div className="flex flex-col gap-1">
              <label className="text-xs text-secondary">
                {t('Options')}
                <span className="ml-1 inline text-accent-primary">*</span>
              </label>
              {filterFunction === PublicationFunctions.Regex ? (
                <RegexParamInput
                  regEx={filterRegexParam}
                  onRegExChange={handleChangeFilterRegexParam}
                  className="h-[38px] rounded border border-primary"
                />
              ) : (
                <MultipleComboBox
                  className="flex min-h-[38px] items-center rounded border border-primary"
                  initialSelectedItems={filterParams}
                  getItemLabel={getItemLabel}
                  getItemValue={getItemLabel}
                  onChangeSelectedItems={handleChangeFilterParams}
                  placeholder={t('Enter one or more options...') as string}
                />
              )}
            </div>
          </div>
          {/* )} */}
          <div className="flex justify-end">
            <button
              onClick={handleSaveFilter}
              className="button button-primary flex h-[38px] items-center"
              disabled={isSaveBtnDisabled}
            >
              {t('Add filter')}
            </button>
          </div>
        </div>
      </Modal>
    );
  }

  return (
    <div className="flex gap-px" data-qa="publish-audience-filter-selectors">
      <RulesSelect
        menuClassName="max-w-full font-semibold md:max-w-[145px]"
        filters={publicationFilters}
        selectedFilter={selectedTarget}
        capitalizeFirstLetters
        onChangeFilter={handleChangeTarget}
        id="targets"
      />
      <RulesSelect
        menuClassName="max-w-full italic md:max-w-[100px]"
        // TODO: uncomment when it will be supported on core
        // menuClassName={classNames(
        //   'max-w-full italic',
        //   !isTrueOrFalseFilterSelected && 'md:max-w-[100px]',
        // )}
        filters={filterFunctionValues}
        selectedFilter={filterFunction}
        onChangeFilter={handleChangeFilterFunction}
        id="filterFns"
      />
      {/* TODO: uncomment when it will be supported on core */}
      {/* {!isTrueOrFalseFilterSelected && */}
      {filterFunction === PublicationFunctions.Regex ? (
        <RegexParamInput
          regEx={filterRegexParam}
          onRegExChange={handleChangeFilterRegexParam}
        />
      ) : (
        <MultipleComboBox
          className="!bg-layer-3"
          initialSelectedItems={filterParams}
          getItemLabel={getItemLabel}
          getItemValue={getItemLabel}
          onChangeSelectedItems={handleChangeFilterParams}
          fontSize="text-xs"
          placeholder={t('Enter one or more options...') as string}
        />
      )}
      {/* } */}
      <div className="flex min-h-[31px] items-start justify-center bg-layer-3 px-2 py-[5.5px]">
        <div className="flex gap-2">
          <button
            data-qa="save-filter"
            onClick={handleSaveFilter}
            className={classNames(
              isSaveBtnDisabled
                ? 'cursor-not-allowed text-controls-disable'
                : 'text-secondary hover:text-accent-primary',
            )}
            disabled={isSaveBtnDisabled}
          >
            <IconCheck size={18} />
          </button>
          <IconX
            className="cursor-pointer text-secondary hover:text-accent-primary"
            size={18}
            onClick={onCloseFilter}
          />
        </div>
      </div>
    </div>
  );
}